From db4b83fe49ed5211bae215d78827ed9014285ea5 Mon Sep 17 00:00:00 2001 From: Paul Saab Date: Mon, 6 Jun 2005 19:46:53 +0000 Subject: Fix for a bug in the change that walks the scoreboard backwards from the tail (in tcp_sack_option()). The bug was caused by incorrect accounting of the retransmitted bytes in the sackhint. Reported by: Kris Kennaway. Submitted by: Noritoshi Demizu. --- sys/netinet/tcp_sack.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sys/netinet/tcp_sack.c') diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 28c6d8a4d420..7708e9de7ddc 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -508,8 +508,6 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen) cur->start = sblkp->end; cur->rxmit = SEQ_MAX(cur->rxmit, cur->start); } - /* Go to the previous hole. */ - cur = TAILQ_PREV(cur, sackhole_head, scblink); } else { /* Data acks at least the end of hole */ if (SEQ_GEQ(sblkp->end, cur->end)) { @@ -535,10 +533,17 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen) cur->end); } } - /* Go to the previous sack block. */ - sblkp--; } tp->sackhint.sack_bytes_rexmit += (cur->rxmit - cur->start); + /* + * Testing sblkp->start against cur->start tells us whether + * we're done with the sack block or the sack hole. + * Accordingly, we advance one or the other. + */ + if (SEQ_LEQ(sblkp->start, cur->start)) + cur = TAILQ_PREV(cur, sackhole_head, scblink); + else + sblkp--; } return (0); } -- cgit v1.2.3