{
SCTP_SUBCONN_STATE_DOWN = 0,
SCTP_SUBCONN_STATE_UP,
- SCTP_SUBCONN_STATE_ALLOW_HB
+ SCTP_SUBCONN_STATE_ALLOW_HB,
+ SCTP_SUBCONN_AWAITING_SACK,
+ SCTP_SUBCONN_SACK_RECEIVED
};
#define SCTP_INITIAL_SSHTRESH 65535
typedef struct _sctp_connection
{
+ /** Required for pool_get_aligned */
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+
sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS]; /**< Common transport data. First! */
sctp_user_configuration_t conn_config; /**< Allows tuning of some SCTP behaviors */
void sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, u8 idx,
vlib_buffer_t * b, ip4_address_t * ip4_addr,
- ip6_address_t * ip6_addr);
-void
-sctp_prepare_initack_chunk_for_collision (sctp_connection_t * sctp_conn,
- u8 idx, vlib_buffer_t * b,
- ip4_address_t * ip4_addr,
- ip6_address_t * ip6_addr);
+ u8 add_ip4, ip6_address_t * ip6_addr,
+ u8 add_ip6);
+void sctp_prepare_initack_chunk_for_collision (sctp_connection_t * sctp_conn,
+ u8 idx, vlib_buffer_t * b,
+ ip4_address_t * ip4_addr,
+ ip6_address_t * ip6_addr);
void sctp_prepare_abort_for_collision (sctp_connection_t * sctp_conn, u8 idx,
vlib_buffer_t * b,
ip4_address_t * ip4_addr,
ip6_address_t * ip6_addr);
-void
-sctp_prepare_operation_error (sctp_connection_t * sctp_conn, u8 idx,
- vlib_buffer_t * b, u8 err_cause);
+void sctp_prepare_operation_error (sctp_connection_t * sctp_conn, u8 idx,
+ vlib_buffer_t * b, u8 err_cause);
void sctp_prepare_cookie_echo_chunk (sctp_connection_t * sctp_conn, u8 idx,
vlib_buffer_t * b, u8 reuse_buffer);
void sctp_prepare_cookie_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
#define SCTP_MAX_INIT_RETRANS 8 // number of attempts
#define SCTP_HB_INTERVAL 30 * SHZ
#define SCTP_HB_MAX_BURST 1
-
#define SCTP_DATA_IDLE_INTERVAL 15 * SHZ /* 15 seconds; the time-interval after which the connetion is considered IDLE */
-
#define SCTP_TO_TIMER_TICK SCTP_TICK*10 /* Period for converting from SCTP_TICK */
+#define SCTP_CONN_RECOVERY 1 << 1
+#define SCTP_FAST_RECOVERY 1 << 2
+
typedef struct _sctp_lookup_dispatch
{
u8 next, error;
always_inline u8
cwnd_fully_utilized (sctp_connection_t * sctp_conn, u8 idx)
{
+ if (sctp_conn->sub_conn[idx].cwnd == 0)
+ return 1;
return 0;
}
update_cwnd (sctp_connection_t * sctp_conn)
{
u8 i;
+ u32 inflight = sctp_conn->next_tsn - sctp_conn->last_unacked_tsn;
for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
{
sctp_conn->sub_conn[i].cwnd =
clib_min (sctp_conn->sub_conn[i].PMTU, 1);
}
+
+ /* Section 6.1; point (D) */
+ if ((inflight + SCTP_RTO_BURST * sctp_conn->sub_conn[i].PMTU) <
+ sctp_conn->sub_conn[i].cwnd)
+ sctp_conn->sub_conn[i].cwnd =
+ inflight + SCTP_RTO_BURST * sctp_conn->sub_conn[i].PMTU;
}
}