Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 2,570 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
tp->t_dupacks = 0; | tp->t_dupacks = 0; | ||||
else if (++tp->t_dupacks > tcprexmtthresh || | else if (++tp->t_dupacks > tcprexmtthresh || | ||||
IN_FASTRECOVERY(tp->t_flags)) { | IN_FASTRECOVERY(tp->t_flags)) { | ||||
cc_ack_received(tp, th, nsegs, | cc_ack_received(tp, th, nsegs, | ||||
CC_DUPACK); | CC_DUPACK); | ||||
if (V_tcp_do_prr && | if (V_tcp_do_prr && | ||||
IN_FASTRECOVERY(tp->t_flags) && | IN_FASTRECOVERY(tp->t_flags) && | ||||
(tp->t_flags & TF_SACK_PERMIT)) { | (tp->t_flags & TF_SACK_PERMIT)) { | ||||
int snd_cnt = 0, limit = 0; | tcp_do_prr_ack(tp, th); | ||||
int del_data = 0, pipe = 0; | |||||
/* | |||||
* In a duplicate ACK del_data is only the | |||||
* diff_in_sack. If no SACK is used del_data | |||||
* will be 0. Pipe is the amount of data we | |||||
* estimate to be in the network. | |||||
*/ | |||||
del_data = tp->sackhint.delivered_data; | |||||
if (V_tcp_do_rfc6675_pipe) | |||||
pipe = tcp_compute_pipe(tp); | |||||
else | |||||
pipe = (tp->snd_nxt - tp->snd_fack) + | |||||
tp->sackhint.sack_bytes_rexmit; | |||||
tp->sackhint.prr_delivered += del_data; | |||||
if (pipe >= tp->snd_ssthresh) { | |||||
if (tp->sackhint.recover_fs == 0) | |||||
tp->sackhint.recover_fs = | |||||
imax(1, tp->snd_nxt - tp->snd_una); | |||||
snd_cnt = howmany((long)tp->sackhint.prr_delivered * | |||||
tp->snd_ssthresh, tp->sackhint.recover_fs) - | |||||
tp->sackhint.prr_out; | |||||
} else { | |||||
if (V_tcp_do_prr_conservative) | |||||
limit = tp->sackhint.prr_delivered - | |||||
tp->sackhint.prr_out; | |||||
else | |||||
limit = imax(tp->sackhint.prr_delivered - | |||||
tp->sackhint.prr_out, | |||||
del_data) + maxseg; | |||||
snd_cnt = imin(tp->snd_ssthresh - pipe, limit); | |||||
} | |||||
snd_cnt = imax(snd_cnt, 0) / maxseg; | |||||
/* | |||||
* Send snd_cnt new data into the network in | |||||
* response to this ACK. If there is a going | |||||
* to be a SACK retransmission, adjust snd_cwnd | |||||
* accordingly. | |||||
*/ | |||||
tp->snd_cwnd = imax(maxseg, tp->snd_nxt - tp->snd_recover + | |||||
tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg)); | |||||
} else if ((tp->t_flags & TF_SACK_PERMIT) && | } else if ((tp->t_flags & TF_SACK_PERMIT) && | ||||
(to.to_flags & TOF_SACK) && | (to.to_flags & TOF_SACK) && | ||||
IN_FASTRECOVERY(tp->t_flags)) { | IN_FASTRECOVERY(tp->t_flags)) { | ||||
int awnd; | int awnd; | ||||
/* | /* | ||||
* Compute the amount of data in flight first. | * Compute the amount of data in flight first. | ||||
* We can inject new data into the pipe iff | * We can inject new data into the pipe iff | ||||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | resume_partialack: | ||||
/* | /* | ||||
* If the congestion window was inflated to account | * If the congestion window was inflated to account | ||||
* for the other side's cached packets, retract it. | * for the other side's cached packets, retract it. | ||||
*/ | */ | ||||
if (IN_FASTRECOVERY(tp->t_flags)) { | if (IN_FASTRECOVERY(tp->t_flags)) { | ||||
if (SEQ_LT(th->th_ack, tp->snd_recover)) { | if (SEQ_LT(th->th_ack, tp->snd_recover)) { | ||||
if (tp->t_flags & TF_SACK_PERMIT) | if (tp->t_flags & TF_SACK_PERMIT) | ||||
if (V_tcp_do_prr && to.to_flags & TOF_SACK) | if (V_tcp_do_prr && to.to_flags & TOF_SACK) { | ||||
tcp_prr_partialack(tp, th); | tcp_timer_activate(tp, TT_REXMT, 0); | ||||
else | tp->t_rtttime = 0; | ||||
tcp_do_prr_ack(tp, th); | |||||
tp->t_flags |= TF_ACKNOW; | |||||
(void) tcp_output(tp); | |||||
} else | |||||
tcp_sack_partialack(tp, th); | tcp_sack_partialack(tp, th); | ||||
else | else | ||||
tcp_newreno_partial_ack(tp, th); | tcp_newreno_partial_ack(tp, th); | ||||
} else | } else | ||||
cc_post_recovery(tp, th); | cc_post_recovery(tp, th); | ||||
} | } | ||||
/* | /* | ||||
* If we reach this point, ACK is not a duplicate, | * If we reach this point, ACK is not a duplicate, | ||||
▲ Show 20 Lines • Show All 1,113 Lines • ▼ Show 20 Lines | if (maxmtu && thcmtu) | ||||
mss = min(maxmtu, thcmtu) - min_protoh; | mss = min(maxmtu, thcmtu) - min_protoh; | ||||
else if (maxmtu || thcmtu) | else if (maxmtu || thcmtu) | ||||
mss = max(maxmtu, thcmtu) - min_protoh; | mss = max(maxmtu, thcmtu) - min_protoh; | ||||
return (mss); | return (mss); | ||||
} | } | ||||
void | void | ||||
tcp_prr_partialack(struct tcpcb *tp, struct tcphdr *th) | tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th) | ||||
{ | { | ||||
int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0; | int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0; | ||||
int maxseg = tcp_maxseg(tp); | int maxseg = tcp_maxseg(tp); | ||||
INP_WLOCK_ASSERT(tp->t_inpcb); | INP_WLOCK_ASSERT(tp->t_inpcb); | ||||
tcp_timer_activate(tp, TT_REXMT, 0); | |||||
tp->t_rtttime = 0; | |||||
/* | /* | ||||
* Compute the amount of data that this ACK is indicating | * Compute the amount of data that this ACK is indicating | ||||
* (del_data) and an estimate of how many bytes are in the | * (del_data) and an estimate of how many bytes are in the | ||||
* network. | * network. | ||||
*/ | */ | ||||
del_data = tp->sackhint.delivered_data; | del_data = tp->sackhint.delivered_data; | ||||
if (V_tcp_do_rfc6675_pipe) | if (V_tcp_do_rfc6675_pipe) | ||||
pipe = tcp_compute_pipe(tp); | pipe = tcp_compute_pipe(tp); | ||||
Show All 23 Lines | tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th) | ||||
snd_cnt = imax(snd_cnt, 0) / maxseg; | snd_cnt = imax(snd_cnt, 0) / maxseg; | ||||
/* | /* | ||||
* Send snd_cnt new data into the network in response to this ack. | * Send snd_cnt new data into the network in response to this ack. | ||||
* If there is going to be a SACK retransmission, adjust snd_cwnd | * If there is going to be a SACK retransmission, adjust snd_cwnd | ||||
* accordingly. | * accordingly. | ||||
*/ | */ | ||||
tp->snd_cwnd = imax(maxseg, tp->snd_nxt - tp->snd_recover + | tp->snd_cwnd = imax(maxseg, tp->snd_nxt - tp->snd_recover + | ||||
tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg)); | tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg)); | ||||
tp->t_flags |= TF_ACKNOW; | |||||
(void) tcp_output(tp); | |||||
} | } | ||||
/* | /* | ||||
* On a partial ack arrives, force the retransmission of the | * On a partial ack arrives, force the retransmission of the | ||||
* next unacknowledged segment. Do not clear tp->t_dupacks. | * next unacknowledged segment. Do not clear tp->t_dupacks. | ||||
* By setting snd_nxt to ti_ack, this forces retransmission timer to | * By setting snd_nxt to ti_ack, this forces retransmission timer to | ||||
* be started again. | * be started again. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |