X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsctp%2Fsctp.h;h=3e3750ea92a000cadcee6a3f3a050b45018bb2fc;hb=8ad6a2dfed0a7248be9d005dd04c76da142f2238;hp=7c4df309906939cd15c5dee6e2684f83e800c889;hpb=8d6ef60b767fc0348b91b3abbf1aff2b84167c2b;p=vpp.git 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);