This is conform with the terminology in
M.Mathis and J.Mahdavi, "Forward Acknowledgement: Refining TCP Congestion Control" SIGCOMM'96, August 1996. Submitted by: Noritoshi Demizu, Raja Mukerji
This commit is contained in:
parent
a0ef9a2b74
commit
8512119a50
@ -1840,9 +1840,8 @@ trimthenstep6:
|
||||
else if (++tp->t_dupacks > tcprexmtthresh ||
|
||||
((tcp_do_newreno || tp->sack_enable) &&
|
||||
IN_FASTRECOVERY(tp))) {
|
||||
|
||||
if (tp->sack_enable && IN_FASTRECOVERY(tp)) {
|
||||
int data_in_pipe;
|
||||
int awnd;
|
||||
|
||||
/*
|
||||
* Compute the amount of data in flight first.
|
||||
@ -1850,9 +1849,9 @@ trimthenstep6:
|
||||
* we have less than 1/2 the original window's
|
||||
* worth of data in flight.
|
||||
*/
|
||||
data_in_pipe = (tp->snd_nxt - tp->rcv_lastsack) +
|
||||
awnd = (tp->snd_nxt - tp->snd_fack) +
|
||||
tp->sackhint.sack_bytes_rexmit;
|
||||
if (data_in_pipe < tp->snd_ssthresh) {
|
||||
if (awnd < tp->snd_ssthresh) {
|
||||
tp->snd_cwnd += tp->t_maxseg;
|
||||
if (tp->snd_cwnd > tp->snd_ssthresh)
|
||||
tp->snd_cwnd = tp->snd_ssthresh;
|
||||
|
@ -1840,9 +1840,8 @@ trimthenstep6:
|
||||
else if (++tp->t_dupacks > tcprexmtthresh ||
|
||||
((tcp_do_newreno || tp->sack_enable) &&
|
||||
IN_FASTRECOVERY(tp))) {
|
||||
|
||||
if (tp->sack_enable && IN_FASTRECOVERY(tp)) {
|
||||
int data_in_pipe;
|
||||
int awnd;
|
||||
|
||||
/*
|
||||
* Compute the amount of data in flight first.
|
||||
@ -1850,9 +1849,9 @@ trimthenstep6:
|
||||
* we have less than 1/2 the original window's
|
||||
* worth of data in flight.
|
||||
*/
|
||||
data_in_pipe = (tp->snd_nxt - tp->rcv_lastsack) +
|
||||
awnd = (tp->snd_nxt - tp->snd_fack) +
|
||||
tp->sackhint.sack_bytes_rexmit;
|
||||
if (data_in_pipe < tp->snd_ssthresh) {
|
||||
if (awnd < tp->snd_ssthresh) {
|
||||
tp->snd_cwnd += tp->t_maxseg;
|
||||
if (tp->snd_cwnd > tp->snd_ssthresh)
|
||||
tp->snd_cwnd = tp->snd_ssthresh;
|
||||
|
@ -389,12 +389,12 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
|
||||
}
|
||||
if (TAILQ_EMPTY(&tp->snd_holes))
|
||||
/*
|
||||
* Empty scoreboard. Need to initialize rcv_lastsack (it may be
|
||||
* Empty scoreboard. Need to initialize snd_fack (it may be
|
||||
* uninitialized or have a bogus value). Scoreboard holes
|
||||
* (from the sack blocks received) are created later below (in
|
||||
* the logic that adds holes to the tail of the scoreboard).
|
||||
*/
|
||||
tp->rcv_lastsack = tp->snd_una;
|
||||
tp->snd_fack = tp->snd_una;
|
||||
next_sack_blk = 0;
|
||||
cur = TAILQ_FIRST(&tp->snd_holes);
|
||||
/*
|
||||
@ -403,7 +403,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
|
||||
*/
|
||||
while ((next_sack_blk < num_sack_blks) && (cur != NULL)) {
|
||||
sack = sack_blocks[next_sack_blk];
|
||||
if (SEQ_LT(tp->rcv_lastsack, sack.start))
|
||||
if (SEQ_LT(tp->snd_fack, sack.start))
|
||||
/*
|
||||
* The sack block acks data to the right of all the holes
|
||||
* in the scoreboard. No need to iterate over the
|
||||
@ -495,19 +495,19 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
|
||||
* sack.start and sack.end seem redundant, but they're necessary
|
||||
* to deal with overlapping sack blocks.
|
||||
*/
|
||||
if (SEQ_LT(tp->rcv_lastsack, sack.start)) {
|
||||
if (SEQ_LT(tp->snd_fack, sack.start)) {
|
||||
/* Need to append new hole at end. */
|
||||
temp = tcp_sackhole_alloc(tp, tp->rcv_lastsack,
|
||||
temp = tcp_sackhole_alloc(tp, tp->snd_fack,
|
||||
sack.start);
|
||||
if (temp == NULL)
|
||||
continue; /* ENOBUFS */
|
||||
TAILQ_INSERT_TAIL(&tp->snd_holes, temp, scblink);
|
||||
tp->rcv_lastsack = sack.end;
|
||||
tp->snd_fack = sack.end;
|
||||
if (tp->sackhint.nexthole == NULL)
|
||||
tp->sackhint.nexthole = temp;
|
||||
}
|
||||
if (SEQ_LT(tp->rcv_lastsack, sack.end))
|
||||
tp->rcv_lastsack = sack.end;
|
||||
if (SEQ_LT(tp->snd_fack, sack.end))
|
||||
tp->snd_fack = sack.end;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -689,12 +689,12 @@ tcp_sack_adjust(struct tcpcb *tp)
|
||||
INP_LOCK_ASSERT(tp->t_inpcb);
|
||||
if (cur == NULL)
|
||||
return; /* No holes */
|
||||
if (SEQ_GEQ(tp->snd_nxt, tp->rcv_lastsack))
|
||||
if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack))
|
||||
return; /* We're already beyond any SACKed blocks */
|
||||
/*
|
||||
* Two cases for which we want to advance snd_nxt:
|
||||
* i) snd_nxt lies between end of one hole and beginning of another
|
||||
* ii) snd_nxt lies between end of last hole and rcv_lastsack
|
||||
* ii) snd_nxt lies between end of last hole and snd_fack
|
||||
*/
|
||||
while ((p = TAILQ_NEXT(cur, scblink)) != NULL) {
|
||||
if (SEQ_LT(tp->snd_nxt, cur->end))
|
||||
@ -708,6 +708,6 @@ tcp_sack_adjust(struct tcpcb *tp)
|
||||
}
|
||||
if (SEQ_LT(tp->snd_nxt, cur->end))
|
||||
return;
|
||||
tp->snd_nxt = tp->rcv_lastsack;
|
||||
tp->snd_nxt = tp->snd_fack;
|
||||
return;
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ struct tcpcb {
|
||||
int sack_enable; /* enable SACK for this connection */
|
||||
int snd_numholes; /* number of holes seen by sender */
|
||||
TAILQ_HEAD(, sackhole) snd_holes; /* SACK scoreboard (sorted) */
|
||||
tcp_seq rcv_lastsack; /* last seq number(+1) sack'd by rcv'r*/
|
||||
tcp_seq snd_fack; /* last seq number(+1) sack'd by rcv'r*/
|
||||
int rcv_numsacks; /* # distinct sack blks present */
|
||||
struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */
|
||||
tcp_seq sack_newdata; /* New data xmitted in this recovery
|
||||
|
Loading…
x
Reference in New Issue
Block a user