Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_input.c
Show First 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_VNET | CTLFLAG_RW, | ||||
"Delay ACK to try and piggyback it onto a data packet"); | "Delay ACK to try and piggyback it onto a data packet"); | ||||
VNET_DEFINE(int, drop_synfin) = 0; | VNET_DEFINE(int, drop_synfin) = 0; | ||||
#define V_drop_synfin VNET(drop_synfin) | #define V_drop_synfin VNET(drop_synfin) | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(drop_synfin), 0, | &VNET_NAME(drop_synfin), 0, | ||||
"Drop TCP packets with SYN+FIN set"); | "Drop TCP packets with SYN+FIN set"); | ||||
VNET_DEFINE(int, tcp_do_rfc6675_pipe) = 0; | |||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_pipe, CTLFLAG_VNET | CTLFLAG_RW, | |||||
&VNET_NAME(tcp_do_rfc6675_pipe), 0, | |||||
"Use calculated pipe/in-flight bytes per RFC 6675"); | |||||
VNET_DEFINE(int, tcp_do_rfc3042) = 1; | VNET_DEFINE(int, tcp_do_rfc3042) = 1; | ||||
#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) | #define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_do_rfc3042), 0, | &VNET_NAME(tcp_do_rfc3042), 0, | ||||
"Enable RFC 3042 (Limited Transmit)"); | "Enable RFC 3042 (Limited Transmit)"); | ||||
VNET_DEFINE(int, tcp_do_rfc3390) = 1; | VNET_DEFINE(int, tcp_do_rfc3390) = 1; | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_VNET | CTLFLAG_RW, | ||||
▲ Show 20 Lines • Show All 2,256 Lines • ▼ Show 20 Lines | case TCPS_LAST_ACK: | ||||
if (SEQ_GT(th->th_ack, tp->snd_max)) { | if (SEQ_GT(th->th_ack, tp->snd_max)) { | ||||
TCPSTAT_INC(tcps_rcvacktoomuch); | TCPSTAT_INC(tcps_rcvacktoomuch); | ||||
goto dropafterack; | goto dropafterack; | ||||
} | } | ||||
if ((tp->t_flags & TF_SACK_PERMIT) && | if ((tp->t_flags & TF_SACK_PERMIT) && | ||||
((to.to_flags & TOF_SACK) || | ((to.to_flags & TOF_SACK) || | ||||
!TAILQ_EMPTY(&tp->snd_holes))) | !TAILQ_EMPTY(&tp->snd_holes))) | ||||
tcp_sack_doack(tp, &to, th->th_ack); | tcp_sack_doack(tp, &to, th->th_ack); | ||||
else | |||||
/* | |||||
* Reset the value so that previous (valid) value | |||||
* from the last ack with SACK doesn't get used. | |||||
*/ | |||||
tp->sackhint.sacked_bytes = 0; | |||||
/* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ | /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ | ||||
hhook_run_tcp_est_in(tp, th, &to); | hhook_run_tcp_est_in(tp, th, &to); | ||||
if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
if (tlen == 0 && tiwin == tp->snd_wnd) { | if (tlen == 0 && tiwin == tp->snd_wnd) { | ||||
/* | /* | ||||
* If this is the first time we've seen a | * If this is the first time we've seen a | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
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 | ||||
* we have less than 1/2 the original window's | * we have less than 1/2 the original window's | ||||
* worth of data in flight. | * worth of data in flight. | ||||
*/ | */ | ||||
if (V_tcp_do_rfc6675_pipe) | |||||
awnd = tcp_compute_pipe(tp); | |||||
else | |||||
awnd = (tp->snd_nxt - tp->snd_fack) + | awnd = (tp->snd_nxt - tp->snd_fack) + | ||||
tp->sackhint.sack_bytes_rexmit; | tp->sackhint.sack_bytes_rexmit; | ||||
if (awnd < tp->snd_ssthresh) { | if (awnd < tp->snd_ssthresh) { | ||||
tp->snd_cwnd += tp->t_maxseg; | tp->snd_cwnd += tp->t_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; | ||||
} | } | ||||
} else | } else | ||||
tp->snd_cwnd += tp->t_maxseg; | tp->snd_cwnd += tp->t_maxseg; | ||||
(void) tcp_output(tp); | (void) tcp_output(tp); | ||||
▲ Show 20 Lines • Show All 1,227 Lines • ▼ Show 20 Lines | tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th) | ||||
* Partial window deflation. Relies on fact that tp->snd_una | * Partial window deflation. Relies on fact that tp->snd_una | ||||
* not updated yet. | * not updated yet. | ||||
*/ | */ | ||||
if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) | if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) | ||||
tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); | tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); | ||||
else | else | ||||
tp->snd_cwnd = 0; | tp->snd_cwnd = 0; | ||||
tp->snd_cwnd += tp->t_maxseg; | tp->snd_cwnd += tp->t_maxseg; | ||||
} | |||||
int | |||||
tcp_compute_pipe(struct tcpcb *tp) | |||||
{ | |||||
return (tp->snd_max - tp->snd_una + | |||||
tp->sackhint.sack_bytes_rexmit - | |||||
tp->sackhint.sacked_bytes); | |||||
} | } |