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.

> 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.

So my diff fixes it because now pf state key attach and tcp reuse
are confused in the same way.

> 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.

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?

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! */
                                }

Reply via email to