Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_sack.c
Show First 20 Lines • Show All 744 Lines • ▼ Show 20 Lines | while (sblkp >= sack_blocks && cur != NULL) { | ||||
* we're done with the sack block or the sack hole. | * we're done with the sack block or the sack hole. | ||||
* Accordingly, we advance one or the other. | * Accordingly, we advance one or the other. | ||||
*/ | */ | ||||
if (SEQ_LEQ(sblkp->start, cur->start)) | if (SEQ_LEQ(sblkp->start, cur->start)) | ||||
cur = TAILQ_PREV(cur, sackhole_head, scblink); | cur = TAILQ_PREV(cur, sackhole_head, scblink); | ||||
else | else | ||||
sblkp--; | sblkp--; | ||||
} | } | ||||
if (!(to->to_flags & TOF_SACK)) | |||||
/* | |||||
* If this ACK did not contain any | |||||
* SACK blocks, any only moved the | |||||
* left edge right, it is a pure | |||||
* cumulative ACK. Do not count | |||||
* DupAck for this. Also required | |||||
* for RFC6675 rescue retransmission. | |||||
*/ | |||||
sack_changed = 0; | |||||
tp->sackhint.delivered_data = delivered_data; | tp->sackhint.delivered_data = delivered_data; | ||||
tp->sackhint.sacked_bytes += delivered_data - left_edge_delta; | tp->sackhint.sacked_bytes += delivered_data - left_edge_delta; | ||||
KASSERT((delivered_data >= 0), ("delivered_data < 0")); | KASSERT((delivered_data >= 0), ("delivered_data < 0")); | ||||
KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0")); | KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0")); | ||||
return (sack_changed); | return (sack_changed); | ||||
} | } | ||||
/* | /* | ||||
Show All 34 Lines | tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th) | ||||
/* Send one or 2 segments based on how much new data was acked. */ | /* Send one or 2 segments based on how much new data was acked. */ | ||||
if ((BYTES_THIS_ACK(tp, th) / maxseg) >= 2) | if ((BYTES_THIS_ACK(tp, th) / maxseg) >= 2) | ||||
num_segs = 2; | num_segs = 2; | ||||
tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit + | tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit + | ||||
(tp->snd_nxt - tp->snd_recover) + num_segs * maxseg); | (tp->snd_nxt - tp->snd_recover) + num_segs * maxseg); | ||||
if (tp->snd_cwnd > tp->snd_ssthresh) | if (tp->snd_cwnd > tp->snd_ssthresh) | ||||
tp->snd_cwnd = tp->snd_ssthresh; | tp->snd_cwnd = tp->snd_ssthresh; | ||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
/* | |||||
* RFC6675 rescue retransmission | |||||
* Add a hole between th_ack (snd_una is not yet set) and snd_max, | |||||
* if this was a pure cumulative ACK and no data was send beyond | |||||
* recovery point. Since the data in the socket has not been freed | |||||
* at this point, we check if the scoreboard is empty, and the ACK | |||||
* delivered some new data, indicating a full ACK. Also, if the | |||||
* recovery point is still at snd_max, we are probably application | |||||
* limited. However, this inference might not always be true. The | |||||
* rescue retransmission may rarely be slightly premature | |||||
* compared to RFC6675. | |||||
* The corresponding ACK+SACK will cause any further outstanding | |||||
* segments to be retransmitted. This addresses a corner case, when | |||||
* the trailing packets of a window are lost and no further data | |||||
* is available for sending. | |||||
*/ | |||||
if ((V_tcp_do_rfc6675_pipe) && | |||||
SEQ_LT(th->th_ack, tp->snd_recover) && | |||||
(tp->snd_recover == tp->snd_max) && | |||||
TAILQ_EMPTY(&tp->snd_holes) && | |||||
(tp->sackhint.delivered_data > 0)) { | |||||
struct sackhole *hole; | |||||
int maxseg = tcp_maxseg(tp); | |||||
hole = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack, tp->snd_max - maxseg), tp->snd_max, NULL); | |||||
} | |||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
} | } | ||||
#if 0 | #if 0 | ||||
/* | /* | ||||
* Debug version of tcp_sack_output() that walks the scoreboard. Used for | * Debug version of tcp_sack_output() that walks the scoreboard. Used for | ||||
* now to sanity check the hint. | * now to sanity check the hint. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines |