summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-06-27 22:27:42 +0000
committerps <ps@FreeBSD.org>2005-06-27 22:27:42 +0000
commit5dc6983c1de217ad36b70fde8b35a410d96b2dc2 (patch)
tree59028efed8605154623d895586bd0c855841c39b /sys/netinet/tcp_input.c
parent4df35786e2cf2d7ff569269ced581b360f767498 (diff)
downloadFreeBSD-src-5dc6983c1de217ad36b70fde8b35a410d96b2dc2.zip
FreeBSD-src-5dc6983c1de217ad36b70fde8b35a410d96b2dc2.tar.gz
- Postpone SACK option processing until after PAWS checks. SACK option
processing is now done in the ACK processing case. - Merge tcp_sack_option() and tcp_del_sackholes() into a new function called tcp_sack_doack(). - Test (SEG.ACK < SND.MAX) before processing the ACK. Submitted by: Noritoshi Demizu Reveiewed by: Mohan Srinivasan, Raja Mukerji Approved by: re
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index eda9eb4..6762232 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -164,8 +164,7 @@ struct inpcbhead tcb;
struct inpcbinfo tcbinfo;
struct mtx *tcbinfo_mtx;
-static void tcp_dooptions(struct tcpcb *, struct tcpopt *, u_char *,
- int, int, struct tcphdr *);
+static void tcp_dooptions(struct tcpopt *, u_char *, int, int);
static void tcp_pulloutofband(struct socket *,
struct tcphdr *, struct mbuf *, int);
@@ -747,7 +746,7 @@ findpcb:
* present in a SYN segment. See tcp_timewait().
*/
if (thflags & TH_SYN)
- tcp_dooptions((struct tcpcb *)NULL, &to, optp, optlen, 1, th);
+ tcp_dooptions(&to, optp, optlen, 1);
if (tcp_timewait((struct tcptw *)inp->inp_ppcb,
&to, th, m, tlen))
goto findpcb;
@@ -961,7 +960,7 @@ findpcb:
tcp_trace(TA_INPUT, ostate, tp,
(void *)tcp_saveipgen, &tcp_savetcp, 0);
#endif
- tcp_dooptions(tp, &to, optp, optlen, 1, th);
+ tcp_dooptions(&to, optp, optlen, 1);
if (!syncache_add(&inc, &to, th, &so, m))
goto drop;
if (so == NULL) {
@@ -1082,7 +1081,7 @@ after_listen:
* for incoming connections is handled in tcp_syncache.
* XXX this is traditional behavior, may need to be cleaned up.
*/
- tcp_dooptions(tp, &to, optp, optlen, thflags & TH_SYN, th);
+ tcp_dooptions(&to, optp, optlen, thflags & TH_SYN);
if (thflags & TH_SYN) {
if (to.to_flags & TOF_SCALE) {
tp->t_flags |= TF_RCVD_SCALE;
@@ -1104,11 +1103,6 @@ after_listen:
}
- if (tp->sack_enable) {
- /* Delete stale (cumulatively acked) SACK holes */
- tcp_del_sackholes(tp, th);
- }
-
/*
* Header prediction: check for the two common cases
* of a uni-directional data xfer. If the packet has
@@ -1153,7 +1147,7 @@ after_listen:
((!tcp_do_newreno && !tp->sack_enable &&
tp->t_dupacks < tcprexmtthresh) ||
((tcp_do_newreno || tp->sack_enable) &&
- !IN_FASTRECOVERY(tp)))) {
+ !IN_FASTRECOVERY(tp) && to.to_nsacks == 0))) {
KASSERT(headlocked, ("headlocked"));
INP_INFO_WUNLOCK(&tcbinfo);
headlocked = 0;
@@ -1824,6 +1818,12 @@ trimthenstep6:
case TCPS_LAST_ACK:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait"));
+ if (SEQ_GT(th->th_ack, tp->snd_max)) {
+ tcpstat.tcps_rcvacktoomuch++;
+ goto dropafterack;
+ }
+ if (tp->sack_enable)
+ tcp_sack_doack(tp, &to, th->th_ack);
if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
if (tlen == 0 && tiwin == tp->snd_wnd) {
tcpstat.tcps_rcvdupack++;
@@ -2002,10 +2002,6 @@ trimthenstep6:
tp->snd_cwnd = tp->snd_ssthresh;
}
tp->t_dupacks = 0;
- if (SEQ_GT(th->th_ack, tp->snd_max)) {
- tcpstat.tcps_rcvacktoomuch++;
- goto dropafterack;
- }
/*
* If we reach this point, ACK is not a duplicate,
* i.e., it ACKs something we sent.
@@ -2560,13 +2556,11 @@ drop:
* Parse TCP options and place in tcpopt.
*/
static void
-tcp_dooptions(tp, to, cp, cnt, is_syn, th)
- struct tcpcb *tp;
+tcp_dooptions(to, cp, cnt, is_syn)
struct tcpopt *to;
u_char *cp;
int cnt;
int is_syn;
- struct tcphdr *th;
{
int opt, optlen;
@@ -2642,10 +2636,12 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, th)
to->to_flags |= TOF_SACK;
}
break;
-
case TCPOPT_SACK:
- if (!tp || tcp_sack_option(tp, th, cp, optlen))
+ if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0)
continue;
+ to->to_nsacks = (optlen - 2) / TCPOLEN_SACK;
+ to->to_sacks = cp + 2;
+ tcpstat.tcps_sack_rcv_blocks++;
break;
default:
continue;
OpenPOWER on IntegriCloud