summaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp.h
diff options
context:
space:
mode:
authorMarco Varlese <marco.varlese@suse.de>2018-01-26 16:50:01 +0100
committerFlorin Coras <florin.coras@gmail.com>2018-01-31 03:29:33 +0000
commit8ad6a2dfed0a7248be9d005dd04c76da142f2238 (patch)
treee5349b5340d7944c35a6fe3c80db87bb5572f3dd /src/vnet/sctp/sctp.h
parent8d6ef60b767fc0348b91b3abbf1aff2b84167c2b (diff)
Prep-work patch for congestion-control
This patch addresses the missing field in various data-structures to track valuable information to implement the congestion-control algorithms and manage sub-connections states. It adds the possibility to queue up to 2 SACKs chunks when the connection is not gapping. At the same time, it pushes some variable/field renaming for better readibility. Change-Id: Idcc53512983456779600a75e78e21af078e46602 Signed-off-by: Marco Varlese <marco.varlese@suse.de>
Diffstat (limited to 'src/vnet/sctp/sctp.h')
-rw-r--r--src/vnet/sctp/sctp.h129
1 files changed, 99 insertions, 30 deletions
diff --git a/src/vnet/sctp/sctp.h b/src/vnet/sctp/sctp.h
index 7c4df309906..3e3750ea92a 100644
--- a/src/vnet/sctp/sctp.h
+++ b/src/vnet/sctp/sctp.h
@@ -28,6 +28,7 @@
_(T1_COOKIE, "T1_COOKIE") \
_(T2_SHUTDOWN, "T2_SHUTDOWN") \
_(T3_RXTX, "T3_RXTX") \
+ _(T4_HEARTBEAT, "T4_HB") \
_(T5_SHUTDOWN_GUARD, "T5_SHUTDOWN_GUARD")
typedef enum _sctp_timers
@@ -71,58 +72,125 @@ typedef struct _sctp_sub_connection
{
transport_connection_t connection; /**< Common transport data. First! */
void *parent; /**< Link to the parent-super connection */
- u32 timers[SCTP_N_TIMERS]; /**< Timer handles into timer wheel */
+
+ u32 error_count; /**< The current error count for this destination. */
+ u32 error_threshold; /**< Current error threshold for this destination,
+ i.e. what value marks the destination down if error count reaches this value. */
+ u32 cwnd; /**< The current congestion window. */
+ u32 ssthresh; /**< The current ssthresh value. */
+
+ u32 RTO; /**< The current retransmission timeout value. */
+ u32 SRTT; /**< The current smoothed round-trip time. */
+ u32 RTTVAR; /**< The current RTT variation. */
+
+ u32 partially_acked_bytes; /**< The tracking method for increase of cwnd when in
+ congestion avoidance mode (see Section 7.2.2).*/
+
+ u8 state; /**< The current state of this destination, i.e., DOWN, UP, ALLOW-HB, NO-HEARTBEAT, etc. */
+
+ u16 PMTU; /**< The current known path MTU. */
+
+ u32 timers[SCTP_N_TIMERS]; /**< A timer used by each destination. */
+
+ u8 RTO_pending; /**< A flag used to track if one of the DATA chunks sent to
+ this address is currently being used to compute an RTT.
+ If this flag is 0, the next DATA chunk sent to this destination
+ should be used to compute an RTT and this flag should be set.
+ Every time the RTT calculation completes (i.e., the DATA chunk is SACK'd),
+ clear this flag. */
+
+ u32 last_time; /**< The time to which this destination was last sent a packet to.
+ This can be used to determine if a HEARTBEAT is needed. */
} sctp_sub_connection_t;
typedef struct
{
- u32 a_rwnd; /**< Maximum segment size advertised */
+ u32 a_rwnd; /**< Maximum segment size advertised */
} sctp_options_t;
+#define SetBit(A,k) ( A[(k/32)] |= (1 << (k%32)) )
+#define ClearBit(A,k) ( A[(k/32)] &= ~(1 << (k%32)) )
+#define TestBit(A,k) ( A[(k/32)] & (1 << (k%32)) )
+
+#define MAX_INFLIGHT_PACKETS 128
+#define MAX_ENQUEABLE_SACKS 2
+
+/* This parameter indicates to the receiver how much increment in
+ * milliseconds the sender wishes the receiver to add to its default
+ * cookie life-span.
+ */
+#define SUGGESTED_COOKIE_LIFE_SPAN_INCREMENT 1000
+
typedef struct _sctp_connection
{
- sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS]; /**< Common transport data. First! */
+ sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS]; /**< Common transport data. First! */
u8 state; /**< SCTP state as per sctp_state_t */
u16 flags; /**< Chunk flag (see sctp_chunks_common_hdr_t) */
+
u32 local_tag; /**< INIT_TAG generated locally */
u32 remote_tag; /**< INIT_TAG generated by the remote peer */
- u16 life_span_inc;
-
- /** Send sequence variables RFC4960 */
- u32 snd_una; /**< oldest unacknowledged sequence number */
- u32 snd_una_max; /**< newest unacknowledged sequence number + 1*/
- u32 snd_wl1; /**< seq number used for last snd.wnd update */
- u32 snd_wl2; /**< ack number used for last snd.wnd update */
- u32 snd_nxt; /**< next seq number to be sent */
-
- /** Receive sequence variables RFC4960 */
- u32 rcv_nxt; /**< next sequence number expected */
- u32 rcv_las; /**< rcv_nxt at last ack sent/rcv_wnd update */
- u32 iss; /**< initial sent sequence */
- u32 irs; /**< initial remote sequence */
-
- /* RTT and RTO */
- u32 rto; /**< Retransmission timeout */
- u32 rto_boff; /**< Index for RTO backoff */
- u32 srtt; /**< Smoothed RTT */
- u32 rttvar; /**< Smoothed mean RTT difference. Approximates variance */
- u32 rtt_ts; /**< Timestamp for tracked ACK */
- u32 rtt_seq; /**< Sequence number for tracked ACK */
-
- u32 a_rwnd; /** Constrained by medium / IP / etc. */
+
+ u32 local_initial_tsn; /**< Initial TSN generated locally */
+ u32 remote_initial_tsn; /**< Initial TSN generated by the remote-peer */
+
+ u32 peer_cookie_life_span_increment;
+
+ u32 overall_err_count; /**< The overall association error count. */
+ u32 overall_err_treshold; /**< The threshold for this association that if the Overall Error Count
+ reaches will cause this association to be torn down. */
+
+ u32 peer_rwnd; /**< Current calculated value of the peer's rwnd. */
+
+ u32 next_tsn; /**< The next TSN number to be assigned to a new DATA chunk.
+ This is sent in the INIT or INIT ACK chunk to the peer
+ and incremented each time a DATA chunk is assigned a
+ TSN (normally just prior to transmit or during
+ fragmentation). */
+
+ u32 next_tsn_expected; /**< The next TSN number expected to be received. */
+
+ u32 last_rcvd_tsn; /**< This is the last TSN received in sequence. This value
+ is set initially by taking the peer's initial TSN,
+ received in the INIT or INIT ACK chunk, and
+ subtracting one from it. */
+
+ u32 out_of_order_map[MAX_INFLIGHT_PACKETS]; /**< An array of bits or bytes indicating which out-of-order
+ TSNs have been received (relative to the Last Rcvd TSN).
+ If no gaps exist, i.e., no out-of-order packets have been received,
+ this array will be set to all zero. */
+
+ u8 ack_state; /**< This flag indicates if the next received packet is set to be responded to with a SACK.
+ This is initialized to 0. When a packet is received it is incremented.
+ If this value reaches 2 or more, a SACK is sent and the value is reset to 0.
+ Note: This is used only when no DATA chunks are received out-of-order.
+ When DATA chunks are out-of-order, SACKs are not delayed (see Section 6). */
+
+ u32 a_rwnd; /** This value represents the dedicated buffer space, in number of bytes,
+ the sender of the INIT has reserved in association with this window.
+ During the life of the association, this buffer space SHOULD NOT be lessened
+ (i.e., dedicated buffers taken away from this association);
+ however, an endpoint MAY change the value of a_rwnd it sends in SACK chunks. */
+
+ u32 smallest_PMTU; /** The smallest PMTU discovered for all of the peer's transport addresses. */
+
u32 rcv_a_rwnd; /**< LOCAL max seg size that includes options. To be updated by congestion algos, etc. */
u32 snd_a_rwnd; /**< REMOTE max seg size that includes options. To be updated if peer pushes back on window, etc.*/
+
+ u32 rtt_ts;
+ u32 rtt_seq;
+
sctp_options_t rcv_opts;
sctp_options_t snd_opts;
- u32 snd_hdr_length; /**< BASE HEADER LENGTH for the DATA chunk when sending */
+ u32 snd_hdr_length; /**< BASE HEADER LENGTH for the DATA chunk when sending */
u8 next_avail_sub_conn; /**< Represent the index of the next free slot in sub_conn */
+
} sctp_connection_t;
-typedef void (timer_expiration_handler) (u32 index);
+typedef void (sctp_timer_expiration_handler) (u32 conn_index, u32 timer_id);
sctp_connection_t *sctp_connection_new (u8 thread_index);
void sctp_sub_connection_add_ip4 (u8 thread_index,
@@ -155,7 +223,7 @@ clib_error_t *sctp_init (vlib_main_t * vm);
void sctp_connection_timers_init (sctp_connection_t * tc);
void sctp_connection_timers_reset (sctp_connection_t * tc);
void sctp_init_snd_vars (sctp_connection_t * tc);
-void sctp_connection_init_vars (sctp_connection_t * tc);
+void sctp_init_mss (sctp_connection_t * tc);
void sctp_prepare_initack_chunk (sctp_connection_t * ts, vlib_buffer_t * b,
ip4_address_t * ip4_addr,
@@ -522,6 +590,7 @@ sctp_timer_update (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
if (tc->sub_conn[conn_idx].timers[timer_id] != SCTP_TIMER_HANDLE_INVALID)
tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
sub->timers[timer_id]);
+
tc->sub_conn[conn_idx].timers[timer_id] =
tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
sub->c_c_index, timer_id, interval);