tcp/sack: Discard HighRxt, RescueRxt and LostSeq along with SACK scoreboard
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 15 Jun 2012 09:00:57 +0000 (17:00 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 15 Jun 2012 09:01:58 +0000 (17:01 +0800)
sys/netinet/tcp_sack.c
sys/netinet/tcp_timer.c
sys/netinet/tcp_var.h

index 356bbca..812b944 100644 (file)
@@ -201,8 +201,9 @@ free_sackblock(struct scoreboard *scb, struct sackblock *s)
  * Free up SACK blocks for data that's been acked.
  */
 static void
-tcp_sack_ack_blocks(struct scoreboard *scb, tcp_seq th_ack)
+tcp_sack_ack_blocks(struct tcpcb *tp, tcp_seq th_ack)
 {
+       struct scoreboard *scb = &tp->scb;
        struct sackblock *sb, *nb;
 
        sb = TAILQ_FIRST(&scb->sackblocks);
@@ -220,14 +221,14 @@ tcp_sack_ack_blocks(struct scoreboard *scb, tcp_seq th_ack)
        if (sb && SEQ_GEQ(th_ack, sb->sblk_start)) {
                /* Other side reneged? XXX */
                tcpstat.tcps_sackrenege++;
-               tcp_sack_cleanup(scb);
+               tcp_sack_discard(tp);
        }
 }
 
 /*
  * Delete and free SACK blocks saved in scoreboard.
  */
-void
+static void
 tcp_sack_cleanup(struct scoreboard *scb)
 {
        struct sackblock *sb, *nb;
@@ -242,6 +243,18 @@ tcp_sack_cleanup(struct scoreboard *scb)
        scb->lastfound = NULL;
 }
 
+/*
+ * Discard SACK scoreboard, HighRxt, RescueRxt and LostSeq.
+ */
+void
+tcp_sack_discard(struct tcpcb *tp)
+{
+       tcp_sack_cleanup(&tp->scb);
+       tp->rexmt_high = tp->snd_una;
+       tp->sack_flags &= ~TSACK_F_SACKRESCUED;
+       tp->scb.lostseq = tp->snd_una;
+}
+
 /*
  * Delete and free SACK blocks saved in scoreboard.
  * Delete the one slot block cache.
@@ -338,7 +351,7 @@ tcp_sack_update_scoreboard(struct tcpcb *tp, struct tcpopt *to)
        struct scoreboard *scb = &tp->scb;
        int rexmt_high_update = 0;
 
-       tcp_sack_ack_blocks(scb, tp->snd_una);
+       tcp_sack_ack_blocks(tp, tp->snd_una);
        tcp_sack_add_blocks(tp, to);
        tcp_sack_update_lostseq(scb, tp->snd_una, tp->t_maxseg,
            tp->t_rxtthresh);
index 357cb14..22d39a2 100644 (file)
@@ -585,7 +585,7 @@ tcp_timer_rexmt_handler(struct tcpcb *tp)
                tp->t_rxtsyn += tp->t_rxtcur;
        }
        /* Throw away SACK blocks on a RTO, as specified by RFC2018. */
-       tcp_sack_cleanup(&tp->scb);
+       tcp_sack_discard(tp);
        tcpstat.tcps_rexmttimeo++;
        if (tp->t_state == TCPS_SYN_SENT) {
                if (tcp_low_rtobase) {
@@ -619,8 +619,6 @@ tcp_timer_rexmt_handler(struct tcpcb *tp)
                tp->t_srtt = 0;
        }
        tp->snd_nxt = tp->snd_una;
-       tp->rexmt_high = tp->snd_una;
-       tp->sack_flags &= ~TSACK_F_SACKRESCUED;
        tp->snd_recover = tp->snd_max;
        /*
         * Force a segment to be sent.
index ef87dd3..fe1ec9c 100644 (file)
@@ -657,7 +657,7 @@ struct rtentry *
         tcp_rtlookup (struct in_conninfo *);
 int     tcp_sack_bytes_below(const struct scoreboard *scb, tcp_seq seq);
 void    tcp_sack_destroy(struct scoreboard *scb);
-void    tcp_sack_cleanup(struct scoreboard *scb);
+void    tcp_sack_discard(struct tcpcb *tp);
 void    tcp_sack_report_cleanup(struct tcpcb *tp);
 int     tcp_sack_ndsack_blocks(const struct raw_sackblock *blocks,
            const int numblocks, tcp_seq snd_una);