diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-06-07 21:25:37 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-06-07 21:25:37 +0000 |
commit | 87739f251b80651d7bf5e456e0dc04696a638f9b (patch) | |
tree | 8a36dbdfa9d45f950ffcc830260b168b4eb45f94 /sys | |
parent | 1001fef5168442fee0d557002fbdd7ba550de37a (diff) |
Add "(max <number>)" option for "keep/modulate state" to limit the number
of concurrent connections a rule can create. ok frantzen@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/pf.c | 38 | ||||
-rw-r--r-- | sys/net/pfvar.h | 5 |
2 files changed, 31 insertions, 12 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 676a54dfebc..a47e9f737fb 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.216 2002/06/07 21:14:02 frantzen Exp $ */ +/* $OpenBSD: pf.c,v 1.217 2002/06/07 21:25:35 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -628,12 +628,12 @@ pf_purge_expired_states(void) KASSERT(peer->state == cur->state); RB_REMOVE(pf_state_tree, &tree_lan_ext, peer); - /* release NAT resources */ if (STATE_TRANSLATE(cur->state)) pf_put_sport(cur->state->proto, htons(cur->state->gwy.port)); - + if (cur->state->rule.ptr != NULL) + cur->state->rule.ptr->states--; pool_put(&pf_state_pl, cur->state); pool_put(&pf_tree_pl, cur); pool_put(&pf_tree_pl, peer); @@ -3168,16 +3168,20 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, binat != NULL || rdr != NULL) { /* create new state */ u_int16_t len; - struct pf_state *s; + struct pf_state *s = NULL; len = pd->tot_len - off - (th->th_off << 2); - s = pool_get(&pf_state_pl, PR_NOWAIT); + if (*rm == NULL || !(*rm)->max_states || + (*rm)->states < (*rm)->max_states) + s = pool_get(&pf_state_pl, PR_NOWAIT); if (s == NULL) { if (nport && nat != NULL) pf_put_sport(IPPROTO_TCP, nport); REASON_SET(&reason, PFRES_MEMORY); return (PF_DROP); } + if (*rm != NULL) + (*rm)->states++; s->rule.ptr = *rm; s->allow_opts = *rm && (*rm)->allow_opts; @@ -3417,14 +3421,18 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, if ((*rm != NULL && (*rm)->keep_state) || nat != NULL || binat != NULL || rdr != NULL) { /* create new state */ - struct pf_state *s; + struct pf_state *s = NULL; - s = pool_get(&pf_state_pl, PR_NOWAIT); + if (*rm == NULL || !(*rm)->max_states || + (*rm)->states < (*rm)->max_states) + s = pool_get(&pf_state_pl, PR_NOWAIT); if (s == NULL) { if (nport && nat != NULL) pf_put_sport(IPPROTO_UDP, nport); return (PF_DROP); } + if (*rm != NULL) + (*rm)->states++; s->rule.ptr = *rm; s->allow_opts = *rm && (*rm)->allow_opts; @@ -3682,11 +3690,15 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, if (!state_icmp && ((*rm != NULL && (*rm)->keep_state) || nat != NULL || rdr != NULL || binat != NULL)) { /* create new state */ - struct pf_state *s; + struct pf_state *s = NULL; - s = pool_get(&pf_state_pl, PR_NOWAIT); + if (*rm == NULL || !(*rm)->max_states || + (*rm)->states < (*rm)->max_states) + s = pool_get(&pf_state_pl, PR_NOWAIT); if (s == NULL) return (PF_DROP); + if (*rm != NULL) + (*rm)->states++; s->rule.ptr = *rm; s->allow_opts = *rm && (*rm)->allow_opts; @@ -3886,11 +3898,15 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, if ((*rm != NULL && (*rm)->keep_state) || nat != NULL || rdr != NULL || binat != NULL) { /* create new state */ - struct pf_state *s; + struct pf_state *s = NULL; - s = pool_get(&pf_state_pl, PR_NOWAIT); + if (*rm == NULL || !(*rm)->max_states || + (*rm)->states < (*rm)->max_states) + s = pool_get(&pf_state_pl, PR_NOWAIT); if (s == NULL) return (PF_DROP); + if (*rm != NULL) + (*rm)->states++; s->rule.ptr = *rm; s->allow_opts = *rm && (*rm)->allow_opts; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 5f500e768e9..9222f40c498 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.74 2002/06/07 21:14:02 frantzen Exp $ */ +/* $OpenBSD: pfvar.h,v 1.75 2002/06/07 21:25:35 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -244,6 +244,9 @@ struct pf_rule { struct ifnet *ifp; struct ifnet *rt_ifp; + u_int32_t states; + u_int32_t max_states; + u_int16_t nr; u_int16_t return_icmp; u_int16_t max_mss; |