summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2014-01-18 21:14:46 +0000
committerbluhm <bluhm@openbsd.org>2014-01-18 21:14:46 +0000
commit7852398faa660e45e49c3342464a3add6a670303 (patch)
tree45678cd9b138e0c09b908931f3a72de573c339a8
parentmove atapiscsi to iopools by making the entire ata layer use them too. (diff)
downloadwireguard-openbsd-7852398faa660e45e49c3342464a3add6a670303.tar.xz
wireguard-openbsd-7852398faa660e45e49c3342464a3add6a670303.zip
There was an awkward behaviour after a connection had been diverted
to a socket. When the application removed the socket, the pf state would persist. A new connection did not hit the divert rule as the state still grabed the packet. The solution is to unlink the associated divert state when the socket gets destroyed. This is possible as both are linked together and a divert state without socket does not make sense. OK mikeb@
-rw-r--r--sys/netinet/in_pcb.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 0c57d1140b4..67333ec24d2 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.146 2013/12/20 02:04:08 krw Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.147 2014/01/18 21:14:46 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -495,8 +495,21 @@ in_pcbdetach(struct inpcb *inp)
ipsec_delete_policy(inp->inp_ipo);
#endif
#if NPF > 0
- if (inp->inp_pf_sk)
- inp->inp_pf_sk->inp = NULL;
+ if (inp->inp_pf_sk) {
+ struct pf_state_key *sk;
+ struct pf_state_item *si;
+
+ sk = inp->inp_pf_sk;
+ TAILQ_FOREACH(si, &sk->states, entry)
+ if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr &&
+ si->s->rule.ptr->divert.port) {
+ pf_unlink_state(si->s);
+ break;
+ }
+ /* pf_unlink_state() may have detached the state */
+ if (inp->inp_pf_sk)
+ inp->inp_pf_sk->inp = NULL;
+ }
#endif
s = splnet();
LIST_REMOVE(inp, inp_lhash);