On Tue, Jun 21, 2016 at 16:08 +0200, Alexander Bluhm wrote: > On Tue, Jun 21, 2016 at 02:45:42PM +0200, Mike Belopuhov wrote: > > You're testing the sequence number > > of the new state with an existing one which has seen some > > traffic.. Are you sure this is correct? > > This is exactly what the stack does to distinguish between packets > that belong to an old connection and between a new one. >
Right, I've found it, but how can you tell that this is a new connection if iss changes a lot and you just test if it's greater than? The actual test should be if it's ouside of the window, isn't it? > > But > > since they don't belong to the same connection, this is > > inherently incorrect. > > Here is my logical error. The receiving TCP stack only thinks it > is a reuse of an existing connection. In this case, the sender is > reponsible to increase the initial sequence number. But the sender > has a different port or even a different IP. It is only NAT reusing > the port and address which confuses the stack. > Yep. > So my diff fixes it because now pf state key attach and tcp reuse > are confused in the same way. > Rather a bit sloppy, but yeah. > > Unless I'm wrong, I have to retract my OK and ask you to fix > > the sport bit instead. > > Yes, fixing it in pf_get_sport() is more correct. I will try > to make a diff. > Cool. > It would help a lot debugging such problems, if we would have more > log messages. So extend the existing log to the reuse case in > pf_state_key_attach() ? > > ok? > Sure. > bluhm > > Index: net/pf.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v > retrieving revision 1.977 > diff -u -p -r1.977 pf.c > --- net/pf.c 15 Jun 2016 11:49:34 -0000 1.977 > +++ net/pf.c 21 Jun 2016 13:50:01 -0000 > @@ -669,34 +669,34 @@ pf_state_key_attach(struct pf_state_key > si->s->key[PF_SK_STACK]->af && > sk->af == si->s->key[PF_SK_STACK]->af && > si->s->direction != s->direction))) { > + int reuse = 0; > + > if (sk->proto == IPPROTO_TCP && > si->s->src.state >= TCPS_FIN_WAIT_2 && > - si->s->dst.state >= TCPS_FIN_WAIT_2) { > + si->s->dst.state >= TCPS_FIN_WAIT_2) > + reuse = 1; > + if (pf_status.debug >= LOG_NOTICE) { > + log(LOG_NOTICE, > + "pf: %s key attach %s on %s: ", > + (idx == PF_SK_WIRE) ? > + "wire" : "stack", > + reuse ? "reuse" : "failed", > + s->kif->pfik_name); > + pf_print_state_parts(s, > + (idx == PF_SK_WIRE) ? sk : NULL, > + (idx == PF_SK_STACK) ? sk : NULL); > + addlog(", existing: "); > + pf_print_state_parts(si->s, > + (idx == PF_SK_WIRE) ? sk : NULL, > + (idx == PF_SK_STACK) ? sk : NULL); > + addlog("\n"); > + } > + if (reuse) { > si->s->src.state = si->s->dst.state = > TCPS_CLOSED; > /* remove late or sks can go away */ > olds = si->s; > } else { > - if (pf_status.debug >= LOG_NOTICE) { > - log(LOG_NOTICE, > - "pf: %s key attach " > - "failed on %s: ", > - (idx == PF_SK_WIRE) ? > - "wire" : "stack", > - s->kif->pfik_name); > - pf_print_state_parts(s, > - (idx == PF_SK_WIRE) ? > - sk : NULL, > - (idx == PF_SK_STACK) ? > - sk : NULL); > - addlog(", existing: "); > - pf_print_state_parts(si->s, > - (idx == PF_SK_WIRE) ? > - sk : NULL, > - (idx == PF_SK_STACK) ? > - sk : NULL); > - addlog("\n"); > - } > pool_put(&pf_state_key_pl, sk); > return (-1); /* collision! */ > }