tcp: Per-connection DupThresh
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 4 May 2012 09:48:24 +0000 (17:48 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 4 May 2012 09:48:24 +0000 (17:48 +0800)
This eases implementing adaptive DupThresh algorithm, e.g. RFC4653

sys/netinet/tcp_input.c
sys/netinet/tcp_sack.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_var.h

index 90b73de..538cc8f 100644 (file)
@@ -1947,7 +1947,7 @@ after_listen:
                                 * after spurious retransmit.
                                 */
                                /* Do nothing; don't change t_dupacks */
-                       } else if (++tp->t_dupacks == tcprexmtthresh) {
+                       } else if (++tp->t_dupacks == tp->t_rxtthresh) {
                                tcp_seq old_snd_nxt;
                                u_int win;
 
index 485c09d..403185e 100644 (file)
@@ -74,7 +74,7 @@ struct sackblock {
 static int insert_block(struct scoreboard *scb,
                        const struct raw_sackblock *raw_sb, boolean_t *update);
 static void update_lostseq(struct scoreboard *scb, tcp_seq snd_una,
-                          u_int maxseg);
+                          u_int maxseg, int rxtthresh);
 
 static MALLOC_DEFINE(M_SACKBLOCK, "sblk", "sackblock struct");
 
@@ -334,7 +334,7 @@ tcp_sack_update_scoreboard(struct tcpcb *tp, struct tcpopt *to)
 
        tcp_sack_ack_blocks(scb, tp->snd_una);
        tcp_sack_add_blocks(tp, to);
-       update_lostseq(scb, tp->snd_una, tp->t_maxseg);
+       update_lostseq(scb, tp->snd_una, tp->t_maxseg, tp->t_rxtthresh);
        if (SEQ_LT(tp->rexmt_high, tp->snd_una)) {
                tp->rexmt_high = tp->snd_una;
                rexmt_high_update = 1;
@@ -459,7 +459,8 @@ tcp_sack_dump_blocks(struct scoreboard *scb)
  * Optimization to quickly determine which packets are lost.
  */
 static void
-update_lostseq(struct scoreboard *scb, tcp_seq snd_una, u_int maxseg)
+update_lostseq(struct scoreboard *scb, tcp_seq snd_una, u_int maxseg,
+    int rxtthresh)
 {
        struct sackblock *sb;
        int nsackblocks = 0;
@@ -469,8 +470,8 @@ update_lostseq(struct scoreboard *scb, tcp_seq snd_una, u_int maxseg)
        while (sb != NULL) {
                ++nsackblocks;
                bytes_sacked += sb->sblk_end - sb->sblk_start;
-               if (nsackblocks == tcprexmtthresh ||
-                   bytes_sacked >= tcprexmtthresh * maxseg) {
+               if (nsackblocks == rxtthresh ||
+                   bytes_sacked >= rxtthresh * maxseg) {
                        scb->lostseq = sb->sblk_start;
                        return;
                }
index 39d2338..f484f59 100644 (file)
@@ -697,6 +697,7 @@ tcp_newtcpcb(struct inpcb *inp)
        bzero(tp, sizeof(struct tcpcb));
        LIST_INIT(&tp->t_segq);
        tp->t_maxseg = tp->t_maxopd = isipv6 ? tcp_v6mssdflt : tcp_mssdflt;
+       tp->t_rxtthresh = tcprexmtthresh;
 
        /* Set up our timeouts. */
        tp->tt_rexmt = &it->inp_tp_rexmt;
index 5448e7d..dc4d8de 100644 (file)
@@ -138,6 +138,7 @@ struct netmsg_tcp_timer;
 struct tcpcb {
        struct  tsegqe_head t_segq;
        int     t_dupacks;              /* consecutive dup acks recd */
+       int     t_rxtthresh;            /* # dup acks to start fast rxt */
        int     tt_cpu;                 /* sanity check the cpu */
 
        struct  tcp_callout *tt_rexmt;  /* retransmit timer */