diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1864,6 +1864,14 @@ tp->t_dupacks = 0; m_freem(m); + if (SEQ_GEQ(tp->snd_una, tp->round_end) && + !ROUND_HAS_ENDED(tp)) { + tp->round_cnt++; + ROUND_END(tp); + if (CC_ALGO(tp)->newround != NULL) + CC_ALGO(tp)->newround(&tp->t_ccv, tp->round_cnt); + } + /* * If all outstanding data are acked, stop * retransmit timer, otherwise restart timer @@ -3054,6 +3062,14 @@ if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; + if (SEQ_GEQ(tp->snd_una, tp->round_end) && + !ROUND_HAS_ENDED(tp)) { + tp->round_cnt++; + ROUND_END(tp); + if (CC_ALGO(tp)->newround != NULL) + CC_ALGO(tp)->newround(&tp->t_ccv, tp->round_cnt); + } + switch (tp->t_state) { /* * In FIN_WAIT_1 STATE in addition to the processing diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1633,6 +1633,12 @@ if (SEQ_GT(tp->snd_nxt + xlen, tp->snd_max)) tp->snd_max = tp->snd_nxt + xlen; } + + if (ROUND_HAS_ENDED(tp)) { + tp->round_end = tp->snd_max; + ROUND_START(tp); + } + if ((error == 0) && (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->t_flags & TF_SACK_PERMIT) && diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2351,6 +2351,9 @@ * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = V_ip_defttl; + ROUND_END(tp); + tp->round_cnt = 0; + #ifdef TCPPCAP /* * Init the TCP PCAP queues. diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -381,6 +381,8 @@ */ tcp_seq snd_wl1; /* window update seg seq number */ tcp_seq snd_wl2; /* window update seg ack number */ + uint32_t round_cnt; /* Number of rounds in the connection */ + uint32_t round_end; /* ACK number to receive to end the round */ tcp_seq irs; /* initial receive sequence number */ tcp_seq iss; /* initial send sequence number */ @@ -855,6 +857,11 @@ #define TF2_PROC_SACK_PROHIBIT 0x00100000 /* Due to small MSS size do not process sack's */ #define TF2_IPSEC_TSO 0x00200000 /* IPSEC + TSO supported */ #define TF2_NO_ISS_CHECK 0x00400000 /* Don't check SEG.ACK against ISS */ +#define TF2_ROUND_UPDATE 0x00800000 /* Don't check SEG.ACK against ISS */ + +#define ROUND_HAS_ENDED(tp) (tp->t_flags2 & TF2_ROUND_UPDATE) +#define ROUND_START(tp) (tp->t_flags2 &= ~TF2_ROUND_UPDATE) +#define ROUND_END(tp) (tp->t_flags2 |= TF2_ROUND_UPDATE) /* * Structure to hold TCP options that are only used during segment