mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
313 lines
9.3 KiB
C
313 lines
9.3 KiB
C
/*
|
|
* 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 */
|
|
/** @} */
|