summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Frantzen <frantzen@cvs.openbsd.org>2003-05-12 22:53:48 +0000
committerMike Frantzen <frantzen@cvs.openbsd.org>2003-05-12 22:53:48 +0000
commit7eec008f4d88d2df26525bff1140297214df962b (patch)
treef02d99919410b1d97c4d189f556e9af26ce40dab /sys
parentceadd66ed0816d0a05a6e422b5d103d960980b8f (diff)
- TCP window scaling is not applied to the SYNs' window so we must retract the
initial maximum window by the scaling factor. otherwise our view of the allowable sequence window is too big. back out the scaling factor adjustment from the max window if the other endpoint rejects window scaling - window scale the forward ACK skew check ok dhartmei@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index bbe4a72d276..02687cb2e9d 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.347 2003/05/12 17:49:03 mcbride Exp $ */
+/* $OpenBSD: pf.c,v 1.348 2003/05/12 22:53:47 frantzen Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -2145,9 +2145,16 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
s->src.seqhi++;
s->src.wscale = pf_get_wscale(m, off, th->th_off, af);
}
+ s->src.max_win = MAX(ntohs(th->th_win), 1);
+ if (s->src.wscale & PF_WSCALE_MASK) {
+ /* Remove scale factor from initial window */
+ int win = s->src.max_win;
+ win += 1 << (s->src.wscale & PF_WSCALE_MASK);
+ s->src.max_win = (win - 1) >>
+ (s->src.wscale & PF_WSCALE_MASK);
+ }
if (th->th_flags & TH_FIN)
s->src.seqhi++;
- s->src.max_win = MAX(ntohs(th->th_win), 1);
s->dst.seqlo = 0; /* Haven't seen these yet */
s->dst.seqhi = 1;
s->dst.max_win = 1;
@@ -2989,7 +2996,24 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
end = seq + pd->p_len;
if (th->th_flags & TH_SYN) {
end++;
- src->wscale = pf_get_wscale(m, off, th->th_off, pd->af);
+ if (dst->wscale & PF_WSCALE_FLAG) {
+ src->wscale = pf_get_wscale(m, off, th->th_off,
+ pd->af);
+ if (src->wscale & PF_WSCALE_FLAG) {
+ /* Remove scale factor from initial
+ * window */
+ sws = src->wscale & PF_WSCALE_MASK;
+ win = ((u_int32_t)win + (1 << sws) - 1)
+ >> sws;
+ dws = dst->wscale & PF_WSCALE_MASK;
+ } else {
+ /* fixup other window */
+ dst->max_win <<= dst->wscale &
+ PF_WSCALE_MASK;
+ /* in case of a retrans SYN|ACK */
+ dst->wscale = 0;
+ }
+ }
}
if (th->th_flags & TH_FIN)
end++;
@@ -3052,8 +3076,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
/* Retrans: not more than one window back */
(ackskew >= -MAXACKWINDOW) &&
- /* Acking not more than one window back */
- (ackskew <= MAXACKWINDOW)) {
+ /* Acking not more than one reassembled fragment backwards */
+ (ackskew <= (MAXACKWINDOW << dws))) {
/* Acking not more than one window forward */
(*state)->packets++;