-#define TCP_TIMER_HANDLE_INVALID ((u32) ~0)
-
-/* Timer delays as multiples of 100ms */
-#define TCP_TO_TIMER_TICK TCP_TICK*10 /* Period for converting from TCP
- * ticks to timer units */
-#define TCP_DELACK_TIME 1 /* 0.1s */
-#define TCP_ESTABLISH_TIME 750 /* 75s */
-#define TCP_SYN_RCVD_TIME 600 /* 60s */
-#define TCP_2MSL_TIME 300 /* 30s */
-#define TCP_CLOSEWAIT_TIME 20 /* 2s */
-#define TCP_TIMEWAIT_TIME 100 /* 10s */
-#define TCP_CLEANUP_TIME 10 /* 1s Time to wait before cleanup */
-#define TCP_TIMER_PERSIST_MIN 2 /* 0.2s */
-
-#define TCP_RTO_MAX 60 * THZ /* Min max RTO (60s) as per RFC6298 */
-#define TCP_RTO_MIN 0.2 * THZ /* Min RTO (200ms) - lower than standard */
-#define TCP_RTT_MAX 30 * THZ /* 30s (probably too much) */
-#define TCP_RTO_SYN_RETRIES 3 /* SYN retries without doubling RTO */
-#define TCP_RTO_INIT 1 * THZ /* Initial retransmit timer */
-
-/** TCP connection flags */
-#define foreach_tcp_connection_flag \
- _(SNDACK, "Send ACK") \
- _(FINSNT, "FIN sent") \
- _(SENT_RCV_WND0, "Sent 0 rcv_wnd") \
- _(RECOVERY, "Recovery") \
- _(FAST_RECOVERY, "Fast Recovery") \
- _(FR_1_SMSS, "Sent 1 SMSS") \
- _(HALF_OPEN_DONE, "Half-open completed") \
- _(FINPNDG, "FIN pending") \
-
-typedef enum _tcp_connection_flag_bits
-{
-#define _(sym, str) TCP_CONN_##sym##_BIT,
- foreach_tcp_connection_flag
-#undef _
- TCP_CONN_N_FLAG_BITS
-} tcp_connection_flag_bits_e;
-
-typedef enum _tcp_connection_flag
-{
-#define _(sym, str) TCP_CONN_##sym = 1 << TCP_CONN_##sym##_BIT,
- foreach_tcp_connection_flag
-#undef _
- TCP_CONN_N_FLAGS
-} tcp_connection_flags_e;
-
-/** TCP buffer flags */
-#define foreach_tcp_buf_flag \
- _ (ACK) /**< Sending ACK. */ \
- _ (DUPACK) /**< Sending DUPACK. */ \
-
-enum
-{
-#define _(f) TCP_BUF_BIT_##f,
- foreach_tcp_buf_flag
-#undef _
- TCP_N_BUF_BITS,
-};
-
-enum
-{
-#define _(f) TCP_BUF_FLAG_##f = 1 << TCP_BUF_BIT_##f,
- foreach_tcp_buf_flag
-#undef _
-};
-
-#define TCP_SCOREBOARD_TRACE (0)
-#define TCP_MAX_SACK_BLOCKS 15 /**< Max number of SACK blocks stored */
-#define TCP_INVALID_SACK_HOLE_INDEX ((u32)~0)
-
-typedef struct _scoreboard_trace_elt
-{
- u32 start;
- u32 end;
- u32 ack;
- u32 snd_una_max;
- u32 group;
-} scoreboard_trace_elt_t;
-
-typedef struct _sack_scoreboard_hole
-{
- u32 next; /**< Index for next entry in linked list */
- u32 prev; /**< Index for previous entry in linked list */
- u32 start; /**< Start sequence number */
- u32 end; /**< End sequence number */
- u8 is_lost; /**< Mark hole as lost */
-} sack_scoreboard_hole_t;
-
-typedef struct _sack_scoreboard
-{
- sack_scoreboard_hole_t *holes; /**< Pool of holes */
- u32 head; /**< Index of first entry */
- u32 tail; /**< Index of last entry */
- u32 sacked_bytes; /**< Number of bytes sacked in sb */
- u32 last_sacked_bytes; /**< Number of bytes last sacked */
- u32 last_bytes_delivered; /**< Number of sack bytes delivered */
- u32 snd_una_adv; /**< Bytes to add to snd_una */
- u32 high_sacked; /**< Highest byte sacked (fack) */
- u32 high_rxt; /**< Highest retransmitted sequence */
- u32 rescue_rxt; /**< Rescue sequence number */
- u32 lost_bytes; /**< Bytes lost as per RFC6675 */
- u32 cur_rxt_hole; /**< Retransmitting from this hole */
-
-#if TCP_SCOREBOARD_TRACE
- scoreboard_trace_elt_t *trace;
-#endif
-
-} sack_scoreboard_t;
-
-#if TCP_SCOREBOARD_TRACE
-#define tcp_scoreboard_trace_add(_tc, _ack) \
-{ \
- static u64 _group = 0; \
- sack_scoreboard_t *_sb = &_tc->sack_sb; \
- sack_block_t *_sack, *_sacks; \
- scoreboard_trace_elt_t *_elt; \
- int i; \
- _group++; \
- _sacks = _tc->rcv_opts.sacks; \
- for (i = 0; i < vec_len (_sacks); i++) \
- { \
- _sack = &_sacks[i]; \
- vec_add2 (_sb->trace, _elt, 1); \
- _elt->start = _sack->start; \
- _elt->end = _sack->end; \
- _elt->ack = _elt->end == _ack ? _ack : 0; \
- _elt->snd_una_max = _elt->end == _ack ? _tc->snd_una_max : 0; \
- _elt->group = _group; \
- } \
-}
-#else
-#define tcp_scoreboard_trace_add(_tc, _ack)
-#endif
-
-typedef enum _tcp_cc_algorithm_type
-{
- TCP_CC_NEWRENO,
-} tcp_cc_algorithm_type_e;
-
-typedef struct _tcp_cc_algorithm tcp_cc_algorithm_t;
-
-typedef enum _tcp_cc_ack_t
-{
- TCP_CC_ACK,
- TCP_CC_DUPACK,
- TCP_CC_PARTIALACK
-} tcp_cc_ack_t;
-
-typedef struct _tcp_connection
-{
- transport_connection_t connection; /**< Common transport data. First! */
-
- u8 state; /**< TCP state as per tcp_state_t */
- u16 flags; /**< Connection flags (see tcp_conn_flags_e) */
- u32 timers[TCP_N_TIMERS]; /**< Timer handles into timer wheel */
-
- /* TODO RFC4898 */
-
- /** Send sequence variables RFC793 */
- u32 snd_una; /**< oldest unacknowledged sequence number */
- u32 snd_una_max; /**< newest unacknowledged sequence number + 1*/
- u32 snd_wnd; /**< send window */
- 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 */
- u16 snd_mss; /**< Effective send max seg (data) size */
-
- /** Receive sequence variables RFC793 */
- u32 rcv_nxt; /**< next sequence number expected */
- u32 rcv_wnd; /**< receive window we expect */
-
- u32 rcv_las; /**< rcv_nxt at last ack sent/rcv_wnd update */
- u32 iss; /**< initial sent sequence */
- u32 irs; /**< initial remote sequence */
-
- /* Options */
- tcp_options_t rcv_opts; /**< Rx options for connection */
- tcp_options_t snd_opts; /**< Tx options for connection */
- u8 snd_opts_len; /**< Tx options len */
- u8 rcv_wscale; /**< Window scale to advertise to peer */
- u8 snd_wscale; /**< Window scale to use when sending */
- u32 tsval_recent; /**< Last timestamp received */
- u32 tsval_recent_age; /**< When last updated tstamp_recent*/
-
- sack_block_t *snd_sacks; /**< Vector of SACKs to send. XXX Fixed size? */
- sack_scoreboard_t sack_sb; /**< SACK "scoreboard" that tracks holes */
-
- u16 rcv_dupacks; /**< Number of DUPACKs received */
- u8 snt_dupacks; /**< Number of DUPACKs sent in a burst */
-
- /* Congestion control */
- u32 cwnd; /**< Congestion window */
- u32 cwnd_acc_bytes; /**< Bytes accumulated for cwnd increment */
- u32 ssthresh; /**< Slow-start threshold */
- u32 prev_ssthresh; /**< ssthresh before congestion */
- u32 prev_cwnd; /**< ssthresh before congestion */
- u32 bytes_acked; /**< Bytes acknowledged by current segment */
- u32 snd_rxt_bytes; /**< Retransmitted bytes */
- u32 snd_rxt_ts; /**< Timestamp when first packet is retransmitted */
- u32 tsecr_last_ack; /**< Timestamp echoed to us in last healthy ACK */
- u32 snd_congestion; /**< snd_una_max when congestion is detected */
- tcp_cc_algorithm_t *cc_algo; /**< Congestion control algorithm */
-
- /* 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 */
-
- u16 mss; /**< Our max seg size that includes options */
- u32 limited_transmit; /**< snd_nxt when limited transmit starts */
- u32 last_fib_check; /**< Last time we checked fib route for peer */
- u32 sw_if_index; /**< Interface for the connection */
-} tcp_connection_t;
-
-struct _tcp_cc_algorithm
-{
- void (*rcv_ack) (tcp_connection_t * tc);
- void (*rcv_cong_ack) (tcp_connection_t * tc, tcp_cc_ack_t ack);
- void (*congestion) (tcp_connection_t * tc);
- void (*recovered) (tcp_connection_t * tc);
- void (*init) (tcp_connection_t * tc);
-};
-
-#define tcp_fastrecovery_on(tc) (tc)->flags |= TCP_CONN_FAST_RECOVERY
-#define tcp_fastrecovery_off(tc) (tc)->flags &= ~TCP_CONN_FAST_RECOVERY
-#define tcp_recovery_on(tc) (tc)->flags |= TCP_CONN_RECOVERY
-#define tcp_recovery_off(tc) (tc)->flags &= ~TCP_CONN_RECOVERY
-#define tcp_in_fastrecovery(tc) ((tc)->flags & TCP_CONN_FAST_RECOVERY)
-#define tcp_in_recovery(tc) ((tc)->flags & (TCP_CONN_RECOVERY))
-#define tcp_in_slowstart(tc) (tc->cwnd < tc->ssthresh)
-#define tcp_fastrecovery_sent_1_smss(tc) ((tc)->flags & TCP_CONN_FR_1_SMSS)
-#define tcp_fastrecovery_1_smss_on(tc) ((tc)->flags |= TCP_CONN_FR_1_SMSS)
-#define tcp_fastrecovery_1_smss_off(tc) ((tc)->flags &= ~TCP_CONN_FR_1_SMSS)
-
-#define tcp_in_cong_recovery(tc) ((tc)->flags & \
- (TCP_CONN_FAST_RECOVERY | TCP_CONN_RECOVERY))
-
-always_inline void
-tcp_cong_recovery_off (tcp_connection_t * tc)
-{
- tc->flags &= ~(TCP_CONN_FAST_RECOVERY | TCP_CONN_RECOVERY);
- tcp_fastrecovery_1_smss_off (tc);
-}
-
-typedef enum
-{
- TCP_IP4,
- TCP_IP6,
- TCP_N_AF,
-} tcp_af_t;
-