mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
congure_reno: initial import of TCP Reno congestion control
This commit is contained in:
parent
755ea30da7
commit
0f1674379a
@ -41,6 +41,14 @@ ifneq (,$(filter congure_test,$(USEMODULE)))
|
||||
USEMODULE += fmt
|
||||
endif
|
||||
|
||||
ifneq (,$(filter congure_reno,$(USEMODULE)))
|
||||
USEMODULE += congure_reno_methods
|
||||
endif
|
||||
|
||||
ifneq (,$(filter congure_reno_methods,$(USEMODULE)))
|
||||
USEMODULE += seq
|
||||
endif
|
||||
|
||||
ifneq (,$(filter eepreg,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_eeprom
|
||||
endif
|
||||
|
@ -9,6 +9,7 @@ menu "CongURE congestion control abstraction"
|
||||
depends on USEMODULE_CONGURE
|
||||
|
||||
rsource "mock/Kconfig"
|
||||
rsource "reno/Kconfig"
|
||||
rsource "test/Kconfig"
|
||||
|
||||
endmenu # CongURE congestion control abstraction
|
||||
@ -22,6 +23,7 @@ menuconfig MODULE_CONGURE
|
||||
if MODULE_CONGURE
|
||||
|
||||
rsource "mock/Kconfig"
|
||||
rsource "reno/Kconfig"
|
||||
rsource "test/Kconfig"
|
||||
|
||||
endif # MODULE_CONGURE
|
||||
|
@ -1,6 +1,12 @@
|
||||
ifneq (,$(filter congure_mock,$(USEMODULE)))
|
||||
DIRS += mock
|
||||
endif
|
||||
ifneq (,$(filter congure_reno,$(USEMODULE)))
|
||||
DIRS += reno
|
||||
endif
|
||||
ifneq (,$(filter congure_reno_methods,$(USEMODULE)))
|
||||
DIRS += reno/methods
|
||||
endif
|
||||
ifneq (,$(filter congure_test,$(USEMODULE)))
|
||||
DIRS += test
|
||||
endif
|
||||
|
14
sys/congure/reno/Kconfig
Normal file
14
sys/congure/reno/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config MODULE_CONGURE_RENO
|
||||
bool "CongURE implementation of TCP Reno"
|
||||
depends on MODULE_CONGURE
|
||||
select MODULE_CONGURE_RENO_METHODS
|
||||
|
||||
config MODULE_CONGURE_RENO_METHODS
|
||||
bool "Send driver methods for the CongURE implementation of TCP Reno"
|
||||
depends on MODULE_SEQ
|
||||
help
|
||||
Many other congestion control mechanisms are just adaptations of TCP
|
||||
Reno, so this makes the methods of @ref sys_congure_reno available to
|
||||
other @ref sys_congure modules. Use module `congure_reno_methods` to
|
||||
only compile in these modules, but not the driver for
|
||||
`congure_reno_snd_t` or @ref congure_reno_snd_setup().
|
3
sys/congure/reno/Makefile
Normal file
3
sys/congure/reno/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := congure_reno
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
36
sys/congure/reno/congure_reno.c
Normal file
36
sys/congure/reno/congure_reno.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include "congure/reno.h"
|
||||
|
||||
static const congure_snd_driver_t _driver = {
|
||||
.init = congure_reno_snd_init,
|
||||
.inter_msg_interval = congure_reno_snd_inter_msg_interval,
|
||||
.report_msg_sent = congure_reno_snd_report_msg_sent,
|
||||
.report_msg_discarded = congure_reno_snd_report_msg_discarded,
|
||||
.report_msgs_timeout = congure_reno_snd_report_msgs_timeout,
|
||||
.report_msgs_lost = congure_reno_snd_report_msgs_lost,
|
||||
.report_msg_acked = congure_reno_snd_report_msg_acked,
|
||||
.report_ecn_ce = congure_reno_snd_report_ecn_ce,
|
||||
};
|
||||
|
||||
void congure_reno_snd_setup(congure_reno_snd_t *c,
|
||||
const congure_reno_snd_consts_t *consts)
|
||||
{
|
||||
c->super.driver = &_driver;
|
||||
c->consts = consts;
|
||||
}
|
||||
|
||||
/** @} */
|
3
sys/congure/reno/methods/Makefile
Normal file
3
sys/congure/reno/methods/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := congure_reno_methods
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
248
sys/congure/reno/methods/congure_reno_methods.c
Normal file
248
sys/congure/reno/methods/congure_reno_methods.c
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "clist.h"
|
||||
#include "seq.h"
|
||||
|
||||
#include "congure/reno.h"
|
||||
|
||||
static int _snd_in_fast_retransmit(congure_snd_t *cong)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
return (c->dup_acks >= c->consts->frthresh);
|
||||
}
|
||||
|
||||
static inline congure_wnd_size_t _calc_init_wnd(congure_reno_snd_t *c)
|
||||
{
|
||||
/* see https://tools.ietf.org/html/rfc5681#section-3.1 */
|
||||
if (c->mss > c->consts->cwnd_upper) {
|
||||
return 2 * c->mss;
|
||||
}
|
||||
else if (c->mss <= c->consts->cwnd_lower) {
|
||||
return 4 * c->mss;
|
||||
}
|
||||
else {
|
||||
return 3 * c->mss;
|
||||
}
|
||||
}
|
||||
|
||||
static void _fr_cwnd_dec(congure_reno_snd_t *c)
|
||||
{
|
||||
if (c->consts->fr_cwnd_dec) {
|
||||
c->consts->fr_cwnd_dec(c);
|
||||
}
|
||||
else {
|
||||
/* max(c->mss * 2, c->super.cwnd / 2) */
|
||||
c->ssthresh = ((c->mss * 4) > c->super.cwnd)
|
||||
? (c->mss * 2) : (c->super.cwnd / 2);
|
||||
c->super.cwnd = c->ssthresh + (3 * c->mss);
|
||||
}
|
||||
}
|
||||
|
||||
static void _enforce_fast_retransmit(congure_reno_snd_t *c)
|
||||
{
|
||||
if (!_snd_in_fast_retransmit(&c->super)) {
|
||||
c->dup_acks = c->consts->frthresh;
|
||||
}
|
||||
_fr_cwnd_dec(c);
|
||||
c->consts->fr(c);
|
||||
}
|
||||
|
||||
static void _dec_flight_size(congure_reno_snd_t *c, unsigned msg_size)
|
||||
{
|
||||
/* check for integer underflow */
|
||||
if ((c->in_flight_size - msg_size) > c->in_flight_size) {
|
||||
c->in_flight_size = 0U;
|
||||
}
|
||||
else {
|
||||
c->in_flight_size -= msg_size;
|
||||
}
|
||||
}
|
||||
|
||||
void congure_reno_set_mss(congure_reno_snd_t *c, congure_wnd_size_t mss)
|
||||
{
|
||||
c->mss = mss;
|
||||
c->super.cwnd = _calc_init_wnd(c);
|
||||
}
|
||||
|
||||
void congure_reno_snd_init(congure_snd_t *cong, void *ctx)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
c->super.ctx = ctx;
|
||||
c->mss = c->consts->init_mss;
|
||||
c->last_ack = UINT32_MAX;
|
||||
c->super.cwnd = _calc_init_wnd(c);
|
||||
c->ssthresh = c->consts->init_ssthresh;
|
||||
c->dup_acks = 0;
|
||||
}
|
||||
|
||||
int32_t congure_reno_snd_inter_msg_interval(congure_snd_t *cong,
|
||||
unsigned msg_size)
|
||||
{
|
||||
(void)cong;
|
||||
(void)msg_size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_msg_sent(congure_snd_t *cong, unsigned sent_size)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
if ((c->in_flight_size + sent_size) < c->super.cwnd) {
|
||||
c->in_flight_size += sent_size;
|
||||
}
|
||||
else {
|
||||
/* state machine is dependent on flight size being smaller or equal
|
||||
* to cwnd as such cap cwnd here, in case caller reports a message in
|
||||
* flight that was marked as lost, but the caller is using a later
|
||||
* message to send another ACK. */
|
||||
c->in_flight_size = c->super.cwnd;
|
||||
}
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_msg_discarded(congure_snd_t *cong,
|
||||
unsigned msg_size)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
assert(msg_size <= c->in_flight_size);
|
||||
|
||||
_dec_flight_size(c, msg_size);
|
||||
}
|
||||
|
||||
int _check_resends(clist_node_t *node, void *ctx)
|
||||
{
|
||||
congure_snd_msg_t *msg = (congure_snd_msg_t *)node;
|
||||
|
||||
(void)ctx;
|
||||
if (msg->resends == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _mark_msg_lost(clist_node_t *node, void *ctx)
|
||||
{
|
||||
congure_snd_msg_t *msg = (congure_snd_msg_t *)node;
|
||||
congure_reno_snd_t *c = (void *)ctx;
|
||||
|
||||
_dec_flight_size(c, msg->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_msgs_timeout(congure_snd_t *cong,
|
||||
congure_snd_msg_t *msgs)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
if (msgs) {
|
||||
if (clist_foreach(&msgs->super, _check_resends, NULL)) {
|
||||
/* see https://tools.ietf.org/html/rfc5681#section-3.1 equation 4 */
|
||||
c->ssthresh = ((c->in_flight_size / 2) > (c->mss * 2))
|
||||
? (c->in_flight_size / 2)
|
||||
: (c->mss * 2);
|
||||
}
|
||||
/* do decrementing of flight size _after_ ssthresh reduction,
|
||||
* since we use the in_flight_size there */
|
||||
clist_foreach(&msgs->super, _mark_msg_lost, c);
|
||||
/* > Furthermore, upon a timeout (as specified in [RFC2988]) cwnd
|
||||
* > MUST be set to no more than the loss window, LW, which equals
|
||||
* > 1 full-sized segment (regardless of the value of IW). */
|
||||
c->super.cwnd = c->mss;
|
||||
}
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_msgs_lost(congure_snd_t *cong,
|
||||
congure_snd_msg_t *msgs)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
clist_foreach(&msgs->super, _mark_msg_lost, c);
|
||||
_enforce_fast_retransmit(c);
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_msg_acked(congure_snd_t *cong,
|
||||
congure_snd_msg_t *msg,
|
||||
congure_snd_ack_t *ack)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
if (seq32_compare(ack->id, c->last_ack) <= 0) {
|
||||
/* check for duplicate ACK according to
|
||||
* https://tools.ietf.org/html/rfc5681#section-2
|
||||
* An acknowledgment is considered a "duplicate" [...] when
|
||||
* (a) the receiver of the ACK has outstanding data, */
|
||||
if ((c->in_flight_size > 0) &&
|
||||
/* (b) the incoming acknowledgment carries no data, */
|
||||
(ack->size == 0) &&
|
||||
/* (c) the SYN and FIN bits are both off */
|
||||
(ack->clean) &&
|
||||
/* (d) the acknowledgment number is equal to the greatest
|
||||
* acknowledgment received on the given connection, and */
|
||||
(ack->id == c->last_ack) &&
|
||||
/* (e) the advertised window in the incoming acknowledgment equals
|
||||
* the advertised window in the last incoming acknowledgment. */
|
||||
((ack->wnd == 0) || (c->consts->same_wnd_adv(c, ack)))) {
|
||||
c->dup_acks++;
|
||||
if (_snd_in_fast_retransmit(cong)) {
|
||||
_fr_cwnd_dec(c);
|
||||
c->consts->fr(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->dup_acks = 0;
|
||||
c->last_ack = ack->id;
|
||||
if (c->super.cwnd < c->ssthresh) {
|
||||
/* slow start */
|
||||
if (c->consts->ss_cwnd_inc) {
|
||||
c->consts->ss_cwnd_inc(c);
|
||||
}
|
||||
else {
|
||||
c->super.cwnd += (c->in_flight_size < c->mss)
|
||||
? c->in_flight_size
|
||||
: c->mss;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* congestion avoidance */
|
||||
if (c->consts->ca_cwnd_inc) {
|
||||
c->consts->ca_cwnd_inc(c);
|
||||
}
|
||||
else {
|
||||
c->super.cwnd += c->mss;
|
||||
}
|
||||
}
|
||||
assert(msg->size <= c->in_flight_size);
|
||||
_dec_flight_size(c, msg->size);
|
||||
}
|
||||
}
|
||||
|
||||
void congure_reno_snd_report_ecn_ce(congure_snd_t *cong, ztimer_now_t time)
|
||||
{
|
||||
congure_reno_snd_t *c = (congure_reno_snd_t *)cong;
|
||||
|
||||
/* see https://tools.ietf.org/html/rfc8311#section-4.1 */
|
||||
(void)time;
|
||||
c->super.cwnd /= 2;
|
||||
c->ssthresh -= c->mss;
|
||||
}
|
||||
|
||||
/** @} */
|
312
sys/include/congure/reno.h
Normal file
312
sys/include/congure/reno.h
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sys_congure_reno CongURE implementation of TCP Reno
|
||||
* @ingroup sys_congure
|
||||
* @brief Implementation of the TCP Reno congestion control algorithm for
|
||||
* the CongURE framework.
|
||||
*
|
||||
* @see [RFC 5681](https://tools.ietf.org/html/rfc5681)
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief
|
||||
*
|
||||
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef CONGURE_RENO_H
|
||||
#define CONGURE_RENO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "congure.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of state object for CongURE Reno.
|
||||
*/
|
||||
typedef struct congure_reno_snd congure_reno_snd_t;
|
||||
|
||||
/**
|
||||
* @brief Constants for the congestion control.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~ {.c}
|
||||
* static const congure_reno_snd_consts_t consts = {
|
||||
* .fr = _my_fast_retransmit,
|
||||
* .same_wnd_adv = _my_same_window_advertised,
|
||||
* .init_mss = 1460,
|
||||
* .cwnd_upper = 2190,
|
||||
* .cwnd_lower = 1095,
|
||||
* .init_ssthresh = CONGURE_WND_SIZE_MAX,
|
||||
* .frthresh = 3,
|
||||
* }
|
||||
* static congure_reno_snd_t cong;
|
||||
*
|
||||
* // ...
|
||||
* congure_reno_snd_setup(&cong, &const);
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Callback to enter and perform fast retransmit
|
||||
*
|
||||
* @param[in] c The CongURE state object (callback context is at
|
||||
* `c->super.ctx`)
|
||||
*/
|
||||
void (*fr)(congure_reno_snd_t *c);
|
||||
|
||||
/**
|
||||
* @brief Callback to check if the advertised window within an ACK is the
|
||||
* same as in the context
|
||||
*
|
||||
* @param[in] c The CongURE state object (callback context is at
|
||||
* `c->super.ctx`)
|
||||
* @param[in] ack The ACK to check.
|
||||
*/
|
||||
bool (*same_wnd_adv)(congure_reno_snd_t *c, congure_snd_ack_t *ack);
|
||||
|
||||
/**
|
||||
* @brief Callback to increase congestion window in slow start
|
||||
*
|
||||
* Defaults to
|
||||
*
|
||||
* ~~~~~~~~~~ {.c}
|
||||
* c->cwnd += c->mss;
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* when set to NULL
|
||||
*
|
||||
* @param[in] c The CongURE state object (callback context is at
|
||||
* `c->super.ctx`)
|
||||
*/
|
||||
void (*ss_cwnd_inc)(congure_reno_snd_t *c);
|
||||
|
||||
/**
|
||||
* @brief Callback to increase congestion window in congestion avoidance
|
||||
*
|
||||
* Defaults to
|
||||
*
|
||||
* ~~~~~~~~~~ {.c}
|
||||
* c->cwnd += (c->in_flight_size < c->mss)
|
||||
* ? c->in_flight_size
|
||||
* : c->mss;
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* when set to NULL
|
||||
*
|
||||
* @param[in] c The CongURE state object (callback context is at
|
||||
* `c->super.ctx`)
|
||||
*/
|
||||
void (*ca_cwnd_inc)(congure_reno_snd_t *c);
|
||||
|
||||
/**
|
||||
* @brief Callback to reset congestion window when entering
|
||||
* fast recovery
|
||||
*
|
||||
* Defaults to
|
||||
*
|
||||
* ~~~~~~~~~~ {.c}
|
||||
* c->ssthresh = max(c->mss * 2, c->cwnd / 2);
|
||||
* c->cwnd = c->ssthresh + (3 * c->mss);
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* when set to NULL
|
||||
*
|
||||
* @param[in] c The CongURE state object (callback context is at
|
||||
* `c->super.ctx`)
|
||||
*/
|
||||
void (*fr_cwnd_dec)(congure_reno_snd_t *c);
|
||||
|
||||
/**
|
||||
* @brief Initial maximum segment size of the sender in intiator-defined
|
||||
* units
|
||||
*
|
||||
* 1460 bytes for TCP over Ethernet
|
||||
* (see [RFC 3390](https://tools.ietf.org/html/rfc3390)).
|
||||
*/
|
||||
unsigned init_mss;
|
||||
|
||||
/**
|
||||
* @brief Initial upper bound for initial window initiator-defined units
|
||||
*
|
||||
* 2190 bytes in classic TCP-Reno (3/4 of the assumed MSS for Ethernet,
|
||||
* see [RFC 3390](https://tools.ietf.org/html/rfc3390)).
|
||||
*/
|
||||
congure_wnd_size_t cwnd_upper;
|
||||
|
||||
/**
|
||||
* @brief Initial lower bound for initial window initiator-defined units
|
||||
*
|
||||
* 1095 bytes in classic TCP-Reno (3/8 of the assumed MSS for Ethernet
|
||||
* see [RFC 3390](https://tools.ietf.org/html/rfc3390)).
|
||||
*/
|
||||
congure_wnd_size_t cwnd_lower;
|
||||
|
||||
/**
|
||||
* @brief Initial slow-start threshold in initiator-defined units
|
||||
*/
|
||||
congure_wnd_size_t init_ssthresh;
|
||||
|
||||
/**
|
||||
* @brief Threshold for duplicate ACKs to go into Fast Retransmit
|
||||
*/
|
||||
uint8_t frthresh;
|
||||
} congure_reno_snd_consts_t;
|
||||
|
||||
/**
|
||||
* @brief State object for CongURE Reno
|
||||
*
|
||||
* @extends congure_snd_t
|
||||
*/
|
||||
struct congure_reno_snd {
|
||||
congure_snd_t super; /**< see @ref congure_snd_t */
|
||||
|
||||
/**
|
||||
* @brief Constants
|
||||
*/
|
||||
const congure_reno_snd_consts_t *consts;
|
||||
uint32_t last_ack; /**< ID of the last ACK reported */
|
||||
/**
|
||||
* @brief Maximum segment size of the sender in caller-defined units
|
||||
*/
|
||||
congure_wnd_size_t mss;
|
||||
congure_wnd_size_t ssthresh; /**< Slow-start threshold */
|
||||
/**
|
||||
* @brief Sum of caller-defined units of message sizes of all messages
|
||||
* that are yet not ack'd or declared lost
|
||||
*/
|
||||
uint16_t in_flight_size;
|
||||
uint8_t dup_acks; /**< Number of duplicate ACKs reported */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set-up @ref sys_congure_reno driver and constants.
|
||||
*
|
||||
* @pre Module `congure_reno` is compiled in (note: `congure_reno_methods` can
|
||||
* also compile this module to enable @ref sys_congure_reno_methods, but
|
||||
* not activate the module `congure_reno`)
|
||||
*
|
||||
* @param[in] c The @ref sys_congure_reno state object
|
||||
* @param[in] consts The constants to use
|
||||
*/
|
||||
void congure_reno_snd_setup(congure_reno_snd_t *c,
|
||||
const congure_reno_snd_consts_t *consts);
|
||||
|
||||
/**
|
||||
* @defgroup sys_congure_reno_methods The send driver methods for CongURE TCP Reno
|
||||
* @ingroup sys_congure_reno
|
||||
*
|
||||
* Many other congestion control mechanisms are just adaptations of TCP Reno,
|
||||
* so this makes the methods of @ref sys_congure_reno available to other
|
||||
* @ref sys_congure modules. Use module `congure_reno_methods` to only compile
|
||||
* in these modules, but not the driver for `congure_reno_snd_t` or
|
||||
* @ref congure_reno_snd_setup().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Set sender maximum segment size.
|
||||
*
|
||||
* @attention This resets congure_reno_snd_t::cwnd to the new initial window
|
||||
* size based on @p mss. So use with care.
|
||||
*
|
||||
* @param[in] c A CongURE state object
|
||||
* @param[in] mss Maximum segment size of the sender in caller-defined units
|
||||
*/
|
||||
void congure_reno_set_mss(congure_reno_snd_t *c, congure_wnd_size_t mss);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::init
|
||||
*
|
||||
* @param[in,out] c The CongURE object to initialize.
|
||||
* @param[in] ctx Context for callbacks specific to the congestion
|
||||
* control (such as a TCP PCB). May be NULL.
|
||||
*/
|
||||
void congure_reno_snd_init(congure_snd_t *c, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::inter_msg_interval
|
||||
*
|
||||
* @param[in,out] c The CongURE object to initialize.
|
||||
* @param[in] msg_size Size of the next message to sent in caller-defined
|
||||
* unit.
|
||||
*
|
||||
* @return Always -1.
|
||||
*/
|
||||
int32_t congure_reno_snd_inter_msg_interval(congure_snd_t *c,
|
||||
unsigned msg_size);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_msg_sent
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] msg_size Size of the message in caller-defined unit.
|
||||
*/
|
||||
void congure_reno_snd_report_msg_sent(congure_snd_t *c, unsigned msg_size);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_msg_discarded
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] msg_size Size of the discarded message in caller-defined
|
||||
* unit.
|
||||
*/
|
||||
void congure_reno_snd_report_msg_discarded(congure_snd_t *c, unsigned msg_size);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_msgs_timeout
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] msgs A collection of messages that are known to be lost.
|
||||
* The list must not be changed by the method.
|
||||
*/
|
||||
void congure_reno_snd_report_msgs_timeout(congure_snd_t *c,
|
||||
congure_snd_msg_t *msgs);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_msgs_lost
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] msgs A collection of messages for which the ACK timed
|
||||
* out. The list must not be changed by the method.
|
||||
*/
|
||||
void congure_reno_snd_report_msgs_lost(congure_snd_t *c,
|
||||
congure_snd_msg_t *msgs);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_msg_acked
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] msg The ACK'd message.
|
||||
* @param[in] ack The received ACK.
|
||||
*/
|
||||
void congure_reno_snd_report_msg_acked(congure_snd_t *c, congure_snd_msg_t *msg,
|
||||
congure_snd_ack_t *ack);
|
||||
|
||||
/**
|
||||
* @brief Use to override congure_snd_driver_t::report_ecn_ce
|
||||
*
|
||||
* @param[in] c The CongURE state object.
|
||||
* @param[in] time Timestamp in milliseconds of the message the CE
|
||||
* event occurred for was sent.
|
||||
*/
|
||||
void congure_reno_snd_report_ecn_ce(congure_snd_t *c, ztimer_now_t time);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONGURE_RENO_H */
|
||||
/** @} */
|
10
tests/congure_reno/app.config.test
Normal file
10
tests/congure_reno/app.config.test
Normal file
@ -0,0 +1,10 @@
|
||||
CONFIG_MODULE_CONGURE=y
|
||||
CONFIG_MODULE_CONGURE_RENO=y
|
||||
CONFIG_MODULE_CONGURE_TEST=y
|
||||
CONFIG_MODULE_FMT=y
|
||||
CONFIG_MODULE_SEQ=y
|
||||
CONFIG_MODULE_SHELL=y
|
||||
CONFIG_MODULE_SHELL_COMMANDS=y
|
||||
|
||||
CONFIG_CONGURE_TEST_LOST_MSG_POOL_SIZE=6
|
||||
CONFIG_SHELL_NO_ECHO=y
|
Loading…
Reference in New Issue
Block a user