wgengine/filter: add a method to run the packet filter without a packet.

The goal is to move some of the shenanigans we have elsewhere into the filter
package, so that all the weird things to do with poking at the filter is in
a single place, behind clean APIs.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson 2020-11-09 23:22:23 -08:00
parent 7a54910990
commit c48253e63b
2 changed files with 29 additions and 1 deletions

View File

@ -176,6 +176,29 @@ func (f *Filter) logRateLimit(runflags RunFlags, q *packet.ParsedPacket, dir dir
}
}
// dummyPacket is a 20-byte slice of garbage, to pass the filter
// pre-check when evaluating synthesized packets.
var dummyPacket = []byte{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}
// CheckTCP determines whether TCP traffic from srcIP to dstIP:dstPort
// is allowed.
func (f *Filter) CheckTCP(srcIP, dstIP netaddr.IP, dstPort uint16) Response {
pkt := &packet.ParsedPacket{}
pkt.Decode(dummyPacket) // initialize private fields
pkt.IPVersion = 4
pkt.IPProto = packet.TCP
pkt.TCPFlags = packet.TCPSyn
pkt.SrcIP = packet.IP4FromNetaddr(srcIP) // TODO: IPv6
pkt.DstIP = packet.IP4FromNetaddr(dstIP)
pkt.SrcPort = 0
pkt.DstPort = dstPort
return f.RunIn(pkt, 0)
}
// RunIn determines whether this node is allowed to receive q from a
// Tailscale peer.
func (f *Filter) RunIn(q *packet.ParsedPacket, rf RunFlags) Response {

View File

@ -165,7 +165,12 @@ type InOut struct {
}
for i, test := range tests {
if got, _ := acl.runIn(&test.p); test.want != got {
t.Errorf("#%d got=%v want=%v packet:%v\n", i, got, test.want, test.p)
t.Errorf("#%d runIn got=%v want=%v packet:%v", i, got, test.want, test.p)
}
if test.p.IPProto == TCP {
if got := acl.CheckTCP(test.p.SrcIP.Netaddr(), test.p.DstIP.Netaddr(), test.p.DstPort); test.want != got {
t.Errorf("#%d CheckTCP got=%v want=%v packet:%v", i, got, test.want, test.p)
}
}
// Update UDP state
_, _ = acl.runOut(&test.p)