Index: pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1193 diff -u -p -r1.1193 pf.c --- pf.c 10 Jan 2024 16:44:30 -0000 1.1193 +++ pf.c 23 Feb 2024 04:10:26 -0000 @@ -202,6 +202,8 @@ int pf_tcp_track_full(struct pf_pdesc struct pf_state **, u_short *, int *, int); int pf_tcp_track_sloppy(struct pf_pdesc *, struct pf_state **, u_short *); +static __inline int pf_synproxy_ack(struct pf_rule *, struct pf_pdesc *, + struct pf_state **, struct pf_rule_actions *); static __inline int pf_synproxy(struct pf_pdesc *, struct pf_state **, u_short *); int pf_test_state(struct pf_pdesc *, struct pf_state **, @@ -4524,6 +4526,14 @@ pf_test_rule(struct pf_pdesc *pd, struct if (action != PF_PASS) goto cleanup; + + if (pd->proto == IPPROTO_TCP && + r->keep_state == PF_STATE_SYNPROXY && pd->dir == PF_IN) { + action = pf_synproxy_ack(r, pd, sm, &ctx.act); + if (action != PF_PASS) + return (action); /* PF_SYNPROXY_DROP */ + } + if (sks != skw) { struct pf_state_key *sk; @@ -4591,7 +4601,6 @@ pf_create_state(struct pf_pdesc *pd, str { struct pf_state *st = NULL; struct tcphdr *th = &pd->hdr.tcp; - u_int16_t mss = tcp_mssdflt; u_short reason; u_int i; @@ -4756,24 +4765,6 @@ pf_create_state(struct pf_pdesc *pd, str pf_tag_ref(tag); st->tag = tag; } - if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) == - TH_SYN && r->keep_state == PF_STATE_SYNPROXY && pd->dir == PF_IN) { - int rtid = pd->rdomain; - if (act->rtableid >= 0) - rtid = act->rtableid; - pf_set_protostate(st, PF_PEER_SRC, PF_TCPS_PROXY_SRC); - st->src.seqhi = arc4random(); - /* Find mss option */ - mss = pf_get_mss(pd); - mss = pf_calc_mss(pd->src, pd->af, rtid, mss); - mss = pf_calc_mss(pd->dst, pd->af, rtid, mss); - st->src.mss = mss; - pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport, - th->th_sport, st->src.seqhi, ntohl(th->th_seq) + 1, - TH_SYN|TH_ACK, 0, st->src.mss, 0, 1, 0, pd->rdomain); - REASON_SET(&reason, PFRES_SYNPROXY); - return (PF_SYNPROXY_DROP); - } return (PF_PASS); @@ -5374,6 +5365,38 @@ pf_synproxy(struct pf_pdesc *pd, struct } } return (PF_PASS); +} + +static __inline int +pf_synproxy_ack(struct pf_rule *r, struct pf_pdesc *pd, struct pf_state **sm, + struct pf_rule_actions *act) +{ + struct tcphdr *th = &pd->hdr.tcp; + struct pf_state *s; + u_int16_t mss; + int rtid; + u_short reason; + + if ((th->th_flags & (TH_SYN|TH_ACK)) != TH_SYN) + return (PF_PASS); + + s = *sm; + rtid = (act->rtableid >= 0) ? act->rtableid : pd->rdomain; + + pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC); + s->src.seqhi = arc4random(); + /* Find mss option */ + mss = pf_get_mss(pd); + mss = pf_calc_mss(pd->src, pd->af, rtid, mss); + mss = pf_calc_mss(pd->dst, pd->af, rtid, mss); + s->src.mss = mss; + + pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport, + th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, + TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, pd->rdomain); + + REASON_SET(&reason, PFRES_SYNPROXY); + return (PF_SYNPROXY_DROP); } int