mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
net/packet, wgengine{,/filter}: remove net/packet IPProto forwarding consts
Only use the ones in types/ipproto now. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
01b90df2fa
commit
1eb95c7e32
@ -4,7 +4,11 @@
|
||||
|
||||
package packet
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
// icmp4HeaderLength is the size of the ICMPv4 packet header, not
|
||||
// including the outer IP layer or the variable "response data"
|
||||
@ -66,7 +70,7 @@ func (h ICMP4Header) Marshal(buf []byte) error {
|
||||
return errLargePacket
|
||||
}
|
||||
// The caller does not need to set this.
|
||||
h.IPProto = ICMPv4
|
||||
h.IPProto = ipproto.ICMPv4
|
||||
|
||||
buf[20] = uint8(h.Type)
|
||||
buf[21] = uint8(h.Code)
|
||||
|
@ -15,17 +15,7 @@
|
||||
"tailscale.com/types/strbuilder"
|
||||
)
|
||||
|
||||
const (
|
||||
Unknown = ipproto.Unknown
|
||||
TCP = ipproto.TCP
|
||||
UDP = ipproto.UDP
|
||||
SCTP = ipproto.SCTP
|
||||
IGMP = ipproto.IGMP
|
||||
ICMPv4 = ipproto.ICMPv4
|
||||
ICMPv6 = ipproto.ICMPv6
|
||||
TSMP = ipproto.TSMP
|
||||
Fragment = ipproto.Fragment
|
||||
)
|
||||
const unknown = ipproto.Unknown
|
||||
|
||||
// RFC1858: prevent overlapping fragment attacks.
|
||||
const minFrag = 60 + 20 // max IPv4 header + basic TCP header
|
||||
@ -113,7 +103,7 @@ func (q *Parsed) Decode(b []byte) {
|
||||
|
||||
if len(b) < 1 {
|
||||
q.IPVersion = 0
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
|
||||
@ -125,7 +115,7 @@ func (q *Parsed) Decode(b []byte) {
|
||||
q.decode6(b)
|
||||
default:
|
||||
q.IPVersion = 0
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +128,7 @@ func (q *Parsed) StuffForTesting(len int) {
|
||||
func (q *Parsed) decode4(b []byte) {
|
||||
if len(b) < ip4HeaderLength {
|
||||
q.IPVersion = 0
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
|
||||
@ -147,7 +137,7 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.length = int(binary.BigEndian.Uint16(b[2:4]))
|
||||
if len(b) < q.length {
|
||||
// Packet was cut off before full IPv4 length.
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
|
||||
@ -158,7 +148,7 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.subofs = int((b[0] & 0x0F) << 2)
|
||||
if q.subofs > q.length {
|
||||
// next-proto starts beyond end of packet.
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
sub := b[q.subofs:]
|
||||
@ -183,29 +173,29 @@ func (q *Parsed) decode4(b []byte) {
|
||||
// This is the first fragment
|
||||
if moreFrags && len(sub) < minFrag {
|
||||
// Suspiciously short first fragment, dump it.
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
// otherwise, this is either non-fragmented (the usual case)
|
||||
// or a big enough initial fragment that we can read the
|
||||
// whole subprotocol header.
|
||||
switch q.IPProto {
|
||||
case ICMPv4:
|
||||
case ipproto.ICMPv4:
|
||||
if len(sub) < icmp4HeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = 0
|
||||
q.Dst.Port = 0
|
||||
q.dataofs = q.subofs + icmp4HeaderLength
|
||||
return
|
||||
case IGMP:
|
||||
case ipproto.IGMP:
|
||||
// Keep IPProto, but don't parse anything else
|
||||
// out.
|
||||
return
|
||||
case TCP:
|
||||
case ipproto.TCP:
|
||||
if len(sub) < tcpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
@ -214,29 +204,29 @@ func (q *Parsed) decode4(b []byte) {
|
||||
headerLength := (sub[12] & 0xF0) >> 2
|
||||
q.dataofs = q.subofs + int(headerLength)
|
||||
return
|
||||
case UDP:
|
||||
case ipproto.UDP:
|
||||
if len(sub) < udpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
q.Dst.Port = binary.BigEndian.Uint16(sub[2:4])
|
||||
q.dataofs = q.subofs + udpHeaderLength
|
||||
return
|
||||
case SCTP:
|
||||
case ipproto.SCTP:
|
||||
if len(sub) < sctpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
q.Dst.Port = binary.BigEndian.Uint16(sub[2:4])
|
||||
return
|
||||
case TSMP:
|
||||
case ipproto.TSMP:
|
||||
// Inter-tailscale messages.
|
||||
q.dataofs = q.subofs
|
||||
return
|
||||
default:
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -244,7 +234,7 @@ func (q *Parsed) decode4(b []byte) {
|
||||
if fragOfs < minFrag {
|
||||
// First frag was suspiciously short, so we can't
|
||||
// trust the followup either.
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
// otherwise, we have to permit the fragment to slide through.
|
||||
@ -253,7 +243,7 @@ func (q *Parsed) decode4(b []byte) {
|
||||
// but that would require statefulness. Anyway, receivers'
|
||||
// kernels know to drop fragments where the initial fragment
|
||||
// doesn't arrive.
|
||||
q.IPProto = Fragment
|
||||
q.IPProto = ipproto.Fragment
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -261,7 +251,7 @@ func (q *Parsed) decode4(b []byte) {
|
||||
func (q *Parsed) decode6(b []byte) {
|
||||
if len(b) < ip6HeaderLength {
|
||||
q.IPVersion = 0
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
|
||||
@ -269,7 +259,7 @@ func (q *Parsed) decode6(b []byte) {
|
||||
q.length = int(binary.BigEndian.Uint16(b[4:6])) + ip6HeaderLength
|
||||
if len(b) < q.length {
|
||||
// Packet was cut off before the full IPv6 length.
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
|
||||
@ -295,17 +285,17 @@ func (q *Parsed) decode6(b []byte) {
|
||||
sub = sub[:len(sub):len(sub)] // help the compiler do bounds check elimination
|
||||
|
||||
switch q.IPProto {
|
||||
case ICMPv6:
|
||||
case ipproto.ICMPv6:
|
||||
if len(sub) < icmp6HeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = 0
|
||||
q.Dst.Port = 0
|
||||
q.dataofs = q.subofs + icmp6HeaderLength
|
||||
case TCP:
|
||||
case ipproto.TCP:
|
||||
if len(sub) < tcpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
@ -314,28 +304,28 @@ func (q *Parsed) decode6(b []byte) {
|
||||
headerLength := (sub[12] & 0xF0) >> 2
|
||||
q.dataofs = q.subofs + int(headerLength)
|
||||
return
|
||||
case UDP:
|
||||
case ipproto.UDP:
|
||||
if len(sub) < udpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
q.Dst.Port = binary.BigEndian.Uint16(sub[2:4])
|
||||
q.dataofs = q.subofs + udpHeaderLength
|
||||
case SCTP:
|
||||
case ipproto.SCTP:
|
||||
if len(sub) < sctpHeaderLength {
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src.Port = binary.BigEndian.Uint16(sub[0:2])
|
||||
q.Dst.Port = binary.BigEndian.Uint16(sub[2:4])
|
||||
return
|
||||
case TSMP:
|
||||
case ipproto.TSMP:
|
||||
// Inter-tailscale messages.
|
||||
q.dataofs = q.subofs
|
||||
return
|
||||
default:
|
||||
q.IPProto = Unknown
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -396,13 +386,13 @@ func (q *Parsed) IsTCPSyn() bool {
|
||||
// IsError reports whether q is an ICMP "Error" packet.
|
||||
func (q *Parsed) IsError() bool {
|
||||
switch q.IPProto {
|
||||
case ICMPv4:
|
||||
case ipproto.ICMPv4:
|
||||
if len(q.b) < q.subofs+8 {
|
||||
return false
|
||||
}
|
||||
t := ICMP4Type(q.b[q.subofs])
|
||||
return t == ICMP4Unreachable || t == ICMP4TimeExceeded
|
||||
case ICMPv6:
|
||||
case ipproto.ICMPv6:
|
||||
if len(q.b) < q.subofs+8 {
|
||||
return false
|
||||
}
|
||||
@ -416,9 +406,9 @@ func (q *Parsed) IsError() bool {
|
||||
// IsEchoRequest reports whether q is an ICMP Echo Request.
|
||||
func (q *Parsed) IsEchoRequest() bool {
|
||||
switch q.IPProto {
|
||||
case ICMPv4:
|
||||
case ipproto.ICMPv4:
|
||||
return len(q.b) >= q.subofs+8 && ICMP4Type(q.b[q.subofs]) == ICMP4EchoRequest && ICMP4Code(q.b[q.subofs+1]) == ICMP4NoCode
|
||||
case ICMPv6:
|
||||
case ipproto.ICMPv6:
|
||||
return len(q.b) >= q.subofs+8 && ICMP6Type(q.b[q.subofs]) == ICMP6EchoRequest && ICMP6Code(q.b[q.subofs+1]) == ICMP6NoCode
|
||||
default:
|
||||
return false
|
||||
@ -428,9 +418,9 @@ func (q *Parsed) IsEchoRequest() bool {
|
||||
// IsEchoRequest reports whether q is an IPv4 ICMP Echo Response.
|
||||
func (q *Parsed) IsEchoResponse() bool {
|
||||
switch q.IPProto {
|
||||
case ICMPv4:
|
||||
case ipproto.ICMPv4:
|
||||
return len(q.b) >= q.subofs+8 && ICMP4Type(q.b[q.subofs]) == ICMP4EchoReply && ICMP4Code(q.b[q.subofs+1]) == ICMP4NoCode
|
||||
case ICMPv6:
|
||||
case ipproto.ICMPv6:
|
||||
return len(q.b) >= q.subofs+8 && ICMP6Type(q.b[q.subofs]) == ICMP6EchoReply && ICMP6Code(q.b[q.subofs+1]) == ICMP6NoCode
|
||||
default:
|
||||
return false
|
||||
|
@ -10,6 +10,19 @@
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
const (
|
||||
Unknown = ipproto.Unknown
|
||||
TCP = ipproto.TCP
|
||||
UDP = ipproto.UDP
|
||||
SCTP = ipproto.SCTP
|
||||
IGMP = ipproto.IGMP
|
||||
ICMPv4 = ipproto.ICMPv4
|
||||
ICMPv6 = ipproto.ICMPv6
|
||||
TSMP = ipproto.TSMP
|
||||
Fragment = ipproto.Fragment
|
||||
)
|
||||
|
||||
func mustIPPort(s string) netaddr.IPPort {
|
||||
|
@ -139,7 +139,7 @@ func (h TailscaleRejectedHeader) Marshal(buf []byte) error {
|
||||
}
|
||||
if h.Src.IP.Is4() {
|
||||
iph := IP4Header{
|
||||
IPProto: TSMP,
|
||||
IPProto: ipproto.TSMP,
|
||||
Src: h.IPSrc,
|
||||
Dst: h.IPDst,
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (h TailscaleRejectedHeader) Marshal(buf []byte) error {
|
||||
buf = buf[ip4HeaderLength:]
|
||||
} else if h.Src.IP.Is6() {
|
||||
iph := IP6Header{
|
||||
IPProto: TSMP,
|
||||
IPProto: ipproto.TSMP,
|
||||
Src: h.IPSrc,
|
||||
Dst: h.IPDst,
|
||||
}
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
package packet
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
// udpHeaderLength is the size of the UDP packet header, not including
|
||||
// the outer IP header.
|
||||
@ -31,7 +35,7 @@ func (h UDP4Header) Marshal(buf []byte) error {
|
||||
return errLargePacket
|
||||
}
|
||||
// The caller does not need to set this.
|
||||
h.IPProto = UDP
|
||||
h.IPProto = ipproto.UDP
|
||||
|
||||
length := len(buf) - h.IP4Header.Len()
|
||||
binary.BigEndian.PutUint16(buf[20:22], h.SrcPort)
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
package packet
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
// UDP6Header is an IPv6+UDP header.
|
||||
type UDP6Header struct {
|
||||
@ -27,7 +31,7 @@ func (h UDP6Header) Marshal(buf []byte) error {
|
||||
return errLargePacket
|
||||
}
|
||||
// The caller does not need to set this.
|
||||
h.IPProto = UDP
|
||||
h.IPProto = ipproto.UDP
|
||||
|
||||
length := len(buf) - h.IP6Header.Len()
|
||||
binary.BigEndian.PutUint16(buf[40:42], h.SrcPort)
|
||||
|
@ -268,7 +268,7 @@ func (f *Filter) CheckTCP(srcIP, dstIP netaddr.IP, dstPort uint16) Response {
|
||||
}
|
||||
pkt.Src.IP = srcIP
|
||||
pkt.Dst.IP = dstIP
|
||||
pkt.IPProto = packet.TCP
|
||||
pkt.IPProto = ipproto.TCP
|
||||
pkt.TCPFlags = packet.TCPSyn
|
||||
pkt.Src.Port = 0
|
||||
pkt.Dst.Port = dstPort
|
||||
@ -326,7 +326,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
|
||||
}
|
||||
|
||||
switch q.IPProto {
|
||||
case packet.ICMPv4:
|
||||
case ipproto.ICMPv4:
|
||||
if q.IsEchoResponse() || q.IsError() {
|
||||
// ICMP responses are allowed.
|
||||
// TODO(apenwarr): consider using conntrack state.
|
||||
@ -338,7 +338,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
|
||||
// If any port is open to an IP, allow ICMP to it.
|
||||
return Accept, "icmp ok"
|
||||
}
|
||||
case packet.TCP:
|
||||
case ipproto.TCP:
|
||||
// For TCP, we want to allow *outgoing* connections,
|
||||
// which means we want to allow return packets on those
|
||||
// connections. To make this restriction work, we need to
|
||||
@ -353,7 +353,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
|
||||
if f.matches4.match(q) {
|
||||
return Accept, "tcp ok"
|
||||
}
|
||||
case packet.UDP, packet.SCTP:
|
||||
case ipproto.UDP, ipproto.SCTP:
|
||||
t := flowtrack.Tuple{Proto: q.IPProto, Src: q.Src, Dst: q.Dst}
|
||||
|
||||
f.state.mu.Lock()
|
||||
@ -366,7 +366,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
|
||||
if f.matches4.match(q) {
|
||||
return Accept, "ok"
|
||||
}
|
||||
case packet.TSMP:
|
||||
case ipproto.TSMP:
|
||||
return Accept, "tsmp ok"
|
||||
default:
|
||||
return Drop, "Unknown proto"
|
||||
@ -383,7 +383,7 @@ func (f *Filter) runIn6(q *packet.Parsed) (r Response, why string) {
|
||||
}
|
||||
|
||||
switch q.IPProto {
|
||||
case packet.ICMPv6:
|
||||
case ipproto.ICMPv6:
|
||||
if q.IsEchoResponse() || q.IsError() {
|
||||
// ICMP responses are allowed.
|
||||
// TODO(apenwarr): consider using conntrack state.
|
||||
@ -395,7 +395,7 @@ func (f *Filter) runIn6(q *packet.Parsed) (r Response, why string) {
|
||||
// If any port is open to an IP, allow ICMP to it.
|
||||
return Accept, "icmp ok"
|
||||
}
|
||||
case packet.TCP:
|
||||
case ipproto.TCP:
|
||||
// For TCP, we want to allow *outgoing* connections,
|
||||
// which means we want to allow return packets on those
|
||||
// connections. To make this restriction work, we need to
|
||||
@ -404,13 +404,13 @@ func (f *Filter) runIn6(q *packet.Parsed) (r Response, why string) {
|
||||
// can't be initiated without first sending a SYN.
|
||||
// It happens to also be much faster.
|
||||
// TODO(apenwarr): Skip the rest of decoding in this path?
|
||||
if q.IPProto == packet.TCP && !q.IsTCPSyn() {
|
||||
if q.IPProto == ipproto.TCP && !q.IsTCPSyn() {
|
||||
return Accept, "tcp non-syn"
|
||||
}
|
||||
if f.matches6.match(q) {
|
||||
return Accept, "tcp ok"
|
||||
}
|
||||
case packet.UDP, packet.SCTP:
|
||||
case ipproto.UDP, ipproto.SCTP:
|
||||
t := flowtrack.Tuple{Proto: q.IPProto, Src: q.Src, Dst: q.Dst}
|
||||
|
||||
f.state.mu.Lock()
|
||||
@ -488,11 +488,11 @@ func (f *Filter) pre(q *packet.Parsed, rf RunFlags, dir direction) Response {
|
||||
}
|
||||
|
||||
switch q.IPProto {
|
||||
case packet.Unknown:
|
||||
case ipproto.Unknown:
|
||||
// Unknown packets are dangerous; always drop them.
|
||||
f.logRateLimit(rf, q, dir, Drop, "unknown")
|
||||
return Drop
|
||||
case packet.Fragment:
|
||||
case ipproto.Fragment:
|
||||
// Fragments after the first always need to be passed through.
|
||||
// Very small fragments are considered Junk by Parsed.
|
||||
f.logRateLimit(rf, q, dir, Accept, "fragment")
|
||||
@ -516,5 +516,5 @@ func omitDropLogging(p *packet.Parsed, dir direction) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return p.Dst.IP.IsMulticast() || (p.Dst.IP.IsLinkLocalUnicast() && p.Dst.IP != gcpDNSAddr) || p.IPProto == packet.IGMP
|
||||
return p.Dst.IP.IsMulticast() || (p.Dst.IP.IsLinkLocalUnicast() && p.Dst.IP != gcpDNSAddr) || p.IPProto == ipproto.IGMP
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func newFilter(logf logger.Logf) *Filter {
|
||||
}
|
||||
matches := []Match{
|
||||
m(nets("8.1.1.1", "8.2.2.2"), netports("1.2.3.4:22", "5.6.7.8:23-24")),
|
||||
m(nets("9.1.1.1", "9.2.2.2"), netports("1.2.3.4:22", "5.6.7.8:23-24"), packet.SCTP),
|
||||
m(nets("9.1.1.1", "9.2.2.2"), netports("1.2.3.4:22", "5.6.7.8:23-24"), ipproto.SCTP),
|
||||
m(nets("8.1.1.1", "8.2.2.2"), netports("5.6.7.8:27-28")),
|
||||
m(nets("2.2.2.2"), netports("8.1.1.1:22")),
|
||||
m(nets("0.0.0.0/0"), netports("100.122.98.50:*")),
|
||||
@ -66,48 +66,48 @@ type InOut struct {
|
||||
}
|
||||
tests := []InOut{
|
||||
// allow 8.1.1.1 => 1.2.3.4:22
|
||||
{Accept, parsed(packet.TCP, "8.1.1.1", "1.2.3.4", 999, 22)},
|
||||
{Accept, parsed(packet.ICMPv4, "8.1.1.1", "1.2.3.4", 0, 0)},
|
||||
{Drop, parsed(packet.TCP, "8.1.1.1", "1.2.3.4", 0, 0)},
|
||||
{Accept, parsed(packet.TCP, "8.1.1.1", "1.2.3.4", 0, 22)},
|
||||
{Drop, parsed(packet.TCP, "8.1.1.1", "1.2.3.4", 0, 21)},
|
||||
{Accept, parsed(ipproto.TCP, "8.1.1.1", "1.2.3.4", 999, 22)},
|
||||
{Accept, parsed(ipproto.ICMPv4, "8.1.1.1", "1.2.3.4", 0, 0)},
|
||||
{Drop, parsed(ipproto.TCP, "8.1.1.1", "1.2.3.4", 0, 0)},
|
||||
{Accept, parsed(ipproto.TCP, "8.1.1.1", "1.2.3.4", 0, 22)},
|
||||
{Drop, parsed(ipproto.TCP, "8.1.1.1", "1.2.3.4", 0, 21)},
|
||||
// allow 8.2.2.2. => 1.2.3.4:22
|
||||
{Accept, parsed(packet.TCP, "8.2.2.2", "1.2.3.4", 0, 22)},
|
||||
{Drop, parsed(packet.TCP, "8.2.2.2", "1.2.3.4", 0, 23)},
|
||||
{Drop, parsed(packet.TCP, "8.3.3.3", "1.2.3.4", 0, 22)},
|
||||
{Accept, parsed(ipproto.TCP, "8.2.2.2", "1.2.3.4", 0, 22)},
|
||||
{Drop, parsed(ipproto.TCP, "8.2.2.2", "1.2.3.4", 0, 23)},
|
||||
{Drop, parsed(ipproto.TCP, "8.3.3.3", "1.2.3.4", 0, 22)},
|
||||
// allow 8.1.1.1 => 5.6.7.8:23-24
|
||||
{Accept, parsed(packet.TCP, "8.1.1.1", "5.6.7.8", 0, 23)},
|
||||
{Accept, parsed(packet.TCP, "8.1.1.1", "5.6.7.8", 0, 24)},
|
||||
{Drop, parsed(packet.TCP, "8.1.1.3", "5.6.7.8", 0, 24)},
|
||||
{Drop, parsed(packet.TCP, "8.1.1.1", "5.6.7.8", 0, 22)},
|
||||
{Accept, parsed(ipproto.TCP, "8.1.1.1", "5.6.7.8", 0, 23)},
|
||||
{Accept, parsed(ipproto.TCP, "8.1.1.1", "5.6.7.8", 0, 24)},
|
||||
{Drop, parsed(ipproto.TCP, "8.1.1.3", "5.6.7.8", 0, 24)},
|
||||
{Drop, parsed(ipproto.TCP, "8.1.1.1", "5.6.7.8", 0, 22)},
|
||||
// allow * => *:443
|
||||
{Accept, parsed(packet.TCP, "17.34.51.68", "8.1.34.51", 0, 443)},
|
||||
{Drop, parsed(packet.TCP, "17.34.51.68", "8.1.34.51", 0, 444)},
|
||||
{Accept, parsed(ipproto.TCP, "17.34.51.68", "8.1.34.51", 0, 443)},
|
||||
{Drop, parsed(ipproto.TCP, "17.34.51.68", "8.1.34.51", 0, 444)},
|
||||
// allow * => 100.122.98.50:*
|
||||
{Accept, parsed(packet.TCP, "17.34.51.68", "100.122.98.50", 0, 999)},
|
||||
{Accept, parsed(packet.TCP, "17.34.51.68", "100.122.98.50", 0, 0)},
|
||||
{Accept, parsed(ipproto.TCP, "17.34.51.68", "100.122.98.50", 0, 999)},
|
||||
{Accept, parsed(ipproto.TCP, "17.34.51.68", "100.122.98.50", 0, 0)},
|
||||
|
||||
// allow ::1, ::2 => [2001::1]:22
|
||||
{Accept, parsed(packet.TCP, "::1", "2001::1", 0, 22)},
|
||||
{Accept, parsed(packet.ICMPv6, "::1", "2001::1", 0, 0)},
|
||||
{Accept, parsed(packet.TCP, "::2", "2001::1", 0, 22)},
|
||||
{Accept, parsed(packet.TCP, "::2", "2001::2", 0, 22)},
|
||||
{Drop, parsed(packet.TCP, "::1", "2001::1", 0, 23)},
|
||||
{Drop, parsed(packet.TCP, "::1", "2001::3", 0, 22)},
|
||||
{Drop, parsed(packet.TCP, "::3", "2001::1", 0, 22)},
|
||||
{Accept, parsed(ipproto.TCP, "::1", "2001::1", 0, 22)},
|
||||
{Accept, parsed(ipproto.ICMPv6, "::1", "2001::1", 0, 0)},
|
||||
{Accept, parsed(ipproto.TCP, "::2", "2001::1", 0, 22)},
|
||||
{Accept, parsed(ipproto.TCP, "::2", "2001::2", 0, 22)},
|
||||
{Drop, parsed(ipproto.TCP, "::1", "2001::1", 0, 23)},
|
||||
{Drop, parsed(ipproto.TCP, "::1", "2001::3", 0, 22)},
|
||||
{Drop, parsed(ipproto.TCP, "::3", "2001::1", 0, 22)},
|
||||
// allow * => *:443
|
||||
{Accept, parsed(packet.TCP, "::1", "2001::1", 0, 443)},
|
||||
{Drop, parsed(packet.TCP, "::1", "2001::1", 0, 444)},
|
||||
{Accept, parsed(ipproto.TCP, "::1", "2001::1", 0, 443)},
|
||||
{Drop, parsed(ipproto.TCP, "::1", "2001::1", 0, 444)},
|
||||
|
||||
// localNets prefilter - accepted by policy filter, but
|
||||
// unexpected dst IP.
|
||||
{Drop, parsed(packet.TCP, "8.1.1.1", "16.32.48.64", 0, 443)},
|
||||
{Drop, parsed(packet.TCP, "1::", "2602::1", 0, 443)},
|
||||
{Drop, parsed(ipproto.TCP, "8.1.1.1", "16.32.48.64", 0, 443)},
|
||||
{Drop, parsed(ipproto.TCP, "1::", "2602::1", 0, 443)},
|
||||
|
||||
// Don't allow protocols not specified by filter
|
||||
{Drop, parsed(packet.SCTP, "8.1.1.1", "1.2.3.4", 999, 22)},
|
||||
{Drop, parsed(ipproto.SCTP, "8.1.1.1", "1.2.3.4", 999, 22)},
|
||||
// But SCTP is allowed for 9.1.1.1
|
||||
{Accept, parsed(packet.SCTP, "9.1.1.1", "1.2.3.4", 999, 22)},
|
||||
{Accept, parsed(ipproto.SCTP, "9.1.1.1", "1.2.3.4", 999, 22)},
|
||||
}
|
||||
for i, test := range tests {
|
||||
aclFunc := acl.runIn4
|
||||
@ -117,7 +117,7 @@ type InOut struct {
|
||||
if got, why := aclFunc(&test.p); test.want != got {
|
||||
t.Errorf("#%d runIn got=%v want=%v why=%q packet:%v", i, got, test.want, why, test.p)
|
||||
}
|
||||
if test.p.IPProto == packet.TCP {
|
||||
if test.p.IPProto == ipproto.TCP {
|
||||
var got Response
|
||||
if test.p.IPVersion == 4 {
|
||||
got = acl.CheckTCP(test.p.Src.IP, test.p.Dst.IP, test.p.Dst.Port)
|
||||
@ -128,7 +128,7 @@ type InOut struct {
|
||||
t.Errorf("#%d CheckTCP got=%v want=%v packet:%v", i, got, test.want, test.p)
|
||||
}
|
||||
// TCP and UDP are treated equivalently in the filter - verify that.
|
||||
test.p.IPProto = packet.UDP
|
||||
test.p.IPProto = ipproto.UDP
|
||||
if got, why := aclFunc(&test.p); test.want != got {
|
||||
t.Errorf("#%d runIn (UDP) got=%v want=%v why=%q packet:%v", i, got, test.want, why, test.p)
|
||||
}
|
||||
@ -142,8 +142,8 @@ func TestUDPState(t *testing.T) {
|
||||
acl := newFilter(t.Logf)
|
||||
flags := LogDrops | LogAccepts
|
||||
|
||||
a4 := parsed(packet.UDP, "119.119.119.119", "102.102.102.102", 4242, 4343)
|
||||
b4 := parsed(packet.UDP, "102.102.102.102", "119.119.119.119", 4343, 4242)
|
||||
a4 := parsed(ipproto.UDP, "119.119.119.119", "102.102.102.102", 4242, 4343)
|
||||
b4 := parsed(ipproto.UDP, "102.102.102.102", "119.119.119.119", 4343, 4242)
|
||||
|
||||
// Unsollicited UDP traffic gets dropped
|
||||
if got := acl.RunIn(&a4, flags); got != Drop {
|
||||
@ -158,8 +158,8 @@ func TestUDPState(t *testing.T) {
|
||||
t.Fatalf("incoming response packet not accepted, got=%v: %v", got, a4)
|
||||
}
|
||||
|
||||
a6 := parsed(packet.UDP, "2001::2", "2001::1", 4242, 4343)
|
||||
b6 := parsed(packet.UDP, "2001::1", "2001::2", 4343, 4242)
|
||||
a6 := parsed(ipproto.UDP, "2001::2", "2001::1", 4242, 4343)
|
||||
b6 := parsed(ipproto.UDP, "2001::1", "2001::2", 4343, 4242)
|
||||
|
||||
// Unsollicited UDP traffic gets dropped
|
||||
if got := acl.RunIn(&a6, flags); got != Drop {
|
||||
@ -178,10 +178,10 @@ func TestUDPState(t *testing.T) {
|
||||
func TestNoAllocs(t *testing.T) {
|
||||
acl := newFilter(t.Logf)
|
||||
|
||||
tcp4Packet := raw4(packet.TCP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
udp4Packet := raw4(packet.UDP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
tcp6Packet := raw6(packet.TCP, "2001::1", "2001::2", 999, 22, 0)
|
||||
udp6Packet := raw6(packet.UDP, "2001::1", "2001::2", 999, 22, 0)
|
||||
tcp4Packet := raw4(ipproto.TCP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
udp4Packet := raw4(ipproto.UDP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
tcp6Packet := raw6(ipproto.TCP, "2001::1", "2001::2", 999, 22, 0)
|
||||
udp6Packet := raw6(ipproto.UDP, "2001::1", "2001::2", 999, 22, 0)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -262,13 +262,13 @@ func TestParseIPSet(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkFilter(b *testing.B) {
|
||||
tcp4Packet := raw4(packet.TCP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
udp4Packet := raw4(packet.UDP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
icmp4Packet := raw4(packet.ICMPv4, "8.1.1.1", "1.2.3.4", 0, 0, 0)
|
||||
tcp4Packet := raw4(ipproto.TCP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
udp4Packet := raw4(ipproto.UDP, "8.1.1.1", "1.2.3.4", 999, 22, 0)
|
||||
icmp4Packet := raw4(ipproto.ICMPv4, "8.1.1.1", "1.2.3.4", 0, 0, 0)
|
||||
|
||||
tcp6Packet := raw6(packet.TCP, "::1", "2001::1", 999, 22, 0)
|
||||
udp6Packet := raw6(packet.UDP, "::1", "2001::1", 999, 22, 0)
|
||||
icmp6Packet := raw6(packet.ICMPv6, "::1", "2001::1", 0, 0, 0)
|
||||
tcp6Packet := raw6(ipproto.TCP, "::1", "2001::1", 999, 22, 0)
|
||||
udp6Packet := raw6(ipproto.UDP, "::1", "2001::1", 999, 22, 0)
|
||||
icmp6Packet := raw6(ipproto.ICMPv6, "::1", "2001::1", 0, 0, 0)
|
||||
|
||||
benches := []struct {
|
||||
name string
|
||||
@ -315,11 +315,11 @@ func TestPreFilter(t *testing.T) {
|
||||
}{
|
||||
{"empty", Accept, []byte{}},
|
||||
{"short", Drop, []byte("short")},
|
||||
{"junk", Drop, raw4default(packet.Unknown, 10)},
|
||||
{"fragment", Accept, raw4default(packet.Fragment, 40)},
|
||||
{"tcp", noVerdict, raw4default(packet.TCP, 0)},
|
||||
{"udp", noVerdict, raw4default(packet.UDP, 0)},
|
||||
{"icmp", noVerdict, raw4default(packet.ICMPv4, 0)},
|
||||
{"junk", Drop, raw4default(ipproto.Unknown, 10)},
|
||||
{"fragment", Accept, raw4default(ipproto.Fragment, 40)},
|
||||
{"tcp", noVerdict, raw4default(ipproto.TCP, 0)},
|
||||
{"udp", noVerdict, raw4default(ipproto.UDP, 0)},
|
||||
{"icmp", noVerdict, raw4default(ipproto.ICMPv4, 0)},
|
||||
}
|
||||
f := NewAllowNone(t.Logf, &netaddr.IPSet{})
|
||||
for _, testPacket := range packets {
|
||||
@ -341,7 +341,7 @@ func TestOmitDropLogging(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "v4_tcp_out",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP},
|
||||
dir: out,
|
||||
want: false,
|
||||
},
|
||||
@ -439,73 +439,73 @@ func TestLoggingPrivacy(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "ts_to_ts_v4_out",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: ts4, Dst: ts4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: ts4, Dst: ts4},
|
||||
dir: out,
|
||||
logged: true,
|
||||
},
|
||||
{
|
||||
name: "ts_to_internet_v4_out",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: ts4, Dst: internet4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: ts4, Dst: internet4},
|
||||
dir: out,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "internet_to_ts_v4_out",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: internet4, Dst: ts4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: internet4, Dst: ts4},
|
||||
dir: out,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "ts_to_ts_v4_in",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: ts4, Dst: ts4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: ts4, Dst: ts4},
|
||||
dir: in,
|
||||
logged: true,
|
||||
},
|
||||
{
|
||||
name: "ts_to_internet_v4_in",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: ts4, Dst: internet4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: ts4, Dst: internet4},
|
||||
dir: in,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "internet_to_ts_v4_in",
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: packet.TCP, Src: internet4, Dst: ts4},
|
||||
pkt: &packet.Parsed{IPVersion: 4, IPProto: ipproto.TCP, Src: internet4, Dst: ts4},
|
||||
dir: in,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "ts_to_ts_v6_out",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: ts6, Dst: ts6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: ts6, Dst: ts6},
|
||||
dir: out,
|
||||
logged: true,
|
||||
},
|
||||
{
|
||||
name: "ts_to_internet_v6_out",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: ts6, Dst: internet6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: ts6, Dst: internet6},
|
||||
dir: out,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "internet_to_ts_v6_out",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: internet6, Dst: ts6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: internet6, Dst: ts6},
|
||||
dir: out,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "ts_to_ts_v6_in",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: ts6, Dst: ts6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: ts6, Dst: ts6},
|
||||
dir: in,
|
||||
logged: true,
|
||||
},
|
||||
{
|
||||
name: "ts_to_internet_v6_in",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: ts6, Dst: internet6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: ts6, Dst: internet6},
|
||||
dir: in,
|
||||
logged: false,
|
||||
},
|
||||
{
|
||||
name: "internet_to_ts_v6_in",
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: packet.TCP, Src: internet6, Dst: ts6},
|
||||
pkt: &packet.Parsed{IPVersion: 6, IPProto: ipproto.TCP, Src: internet6, Dst: ts6},
|
||||
dir: in,
|
||||
logged: false,
|
||||
},
|
||||
@ -607,7 +607,7 @@ func raw4(proto ipproto.Proto, src, dst string, sport, dport uint16, trimLength
|
||||
|
||||
// UDP marshaling clobbers IPProto, so override it here.
|
||||
switch proto {
|
||||
case packet.Unknown, packet.Fragment:
|
||||
case ipproto.Unknown, ipproto.Fragment:
|
||||
default:
|
||||
u.IP4Header.IPProto = proto
|
||||
}
|
||||
@ -615,7 +615,7 @@ func raw4(proto ipproto.Proto, src, dst string, sport, dport uint16, trimLength
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if proto == packet.Fragment {
|
||||
if proto == ipproto.Fragment {
|
||||
// Set some fragment offset. This makes the IP
|
||||
// checksum wrong, but we don't validate the checksum
|
||||
// when parsing.
|
||||
@ -751,10 +751,10 @@ func TestMatchesFromFilterRules(t *testing.T) {
|
||||
want: []Match{
|
||||
{
|
||||
IPProto: []ipproto.Proto{
|
||||
packet.TCP,
|
||||
packet.UDP,
|
||||
packet.ICMPv4,
|
||||
packet.ICMPv6,
|
||||
ipproto.TCP,
|
||||
ipproto.UDP,
|
||||
ipproto.ICMPv4,
|
||||
ipproto.ICMPv6,
|
||||
},
|
||||
Dsts: []NetPortRange{
|
||||
{
|
||||
@ -776,7 +776,7 @@ func TestMatchesFromFilterRules(t *testing.T) {
|
||||
name: "explicit_protos",
|
||||
in: []tailcfg.FilterRule{
|
||||
{
|
||||
IPProto: []int{int(packet.TCP)},
|
||||
IPProto: []int{int(ipproto.TCP)},
|
||||
SrcIPs: []string{"100.64.1.1"},
|
||||
DstPorts: []tailcfg.NetPortRange{{
|
||||
IP: "1.2.0.0/16",
|
||||
@ -787,7 +787,7 @@ func TestMatchesFromFilterRules(t *testing.T) {
|
||||
want: []Match{
|
||||
{
|
||||
IPProto: []ipproto.Proto{
|
||||
packet.TCP,
|
||||
ipproto.TCP,
|
||||
},
|
||||
Dsts: []NetPortRange{
|
||||
{
|
||||
|
@ -9,16 +9,15 @@
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
var defaultProtos = []ipproto.Proto{
|
||||
packet.TCP,
|
||||
packet.UDP,
|
||||
packet.ICMPv4,
|
||||
packet.ICMPv6,
|
||||
ipproto.TCP,
|
||||
ipproto.UDP,
|
||||
ipproto.ICMPv4,
|
||||
ipproto.ICMPv6,
|
||||
}
|
||||
|
||||
// MatchesFromFilterRules converts tailcfg FilterRules into Matches.
|
||||
|
@ -14,6 +14,7 @@
|
||||
"tailscale.com/net/flowtrack"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
"tailscale.com/wgengine/filter"
|
||||
"tailscale.com/wgengine/tstun"
|
||||
)
|
||||
@ -68,7 +69,7 @@ func (e *userspaceEngine) noteFlowProblemFromPeer(f flowtrack.Tuple, problem pac
|
||||
func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.TUN) (res filter.Response) {
|
||||
res = filter.Accept // always
|
||||
|
||||
if pp.IPProto == packet.TSMP {
|
||||
if pp.IPProto == ipproto.TSMP {
|
||||
res = filter.DropSilently
|
||||
rh, ok := pp.AsTailscaleRejectedHeader()
|
||||
if !ok {
|
||||
@ -83,7 +84,7 @@ func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.TUN)
|
||||
}
|
||||
|
||||
if pp.IPVersion == 0 ||
|
||||
pp.IPProto != packet.TCP ||
|
||||
pp.IPProto != ipproto.TCP ||
|
||||
pp.TCPFlags&(packet.TCPSyn|packet.TCPRst) == 0 {
|
||||
return
|
||||
}
|
||||
@ -102,7 +103,7 @@ func (e *userspaceEngine) trackOpenPostFilterOut(pp *packet.Parsed, t *tstun.TUN
|
||||
res = filter.Accept // always
|
||||
|
||||
if pp.IPVersion == 0 ||
|
||||
pp.IPProto != packet.TCP ||
|
||||
pp.IPProto != ipproto.TCP ||
|
||||
pp.TCPFlags&packet.TCPSyn == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
"github.com/tailscale/wireguard-go/tun"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/types/ipproto"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/wgengine/filter"
|
||||
)
|
||||
@ -340,7 +341,7 @@ func (t *TUN) filterIn(buf []byte) filter.Response {
|
||||
// Their host networking stack can translate this into ICMP
|
||||
// or whatnot as required. But notably, their GUI or tailscale CLI
|
||||
// can show them a rejection history with reasons.
|
||||
if p.IPVersion == 4 && p.IPProto == packet.TCP && p.TCPFlags&packet.TCPSyn != 0 {
|
||||
if p.IPVersion == 4 && p.IPProto == ipproto.TCP && p.TCPFlags&packet.TCPSyn != 0 {
|
||||
rj := packet.TailscaleRejectedHeader{
|
||||
IPSrc: p.Dst.IP,
|
||||
IPDst: p.Src.IP,
|
||||
|
@ -108,8 +108,8 @@ func netports(netPorts ...string) (ret []filter.NetPortRange) {
|
||||
|
||||
func setfilter(logf logger.Logf, tun *TUN) {
|
||||
protos := []ipproto.Proto{
|
||||
packet.TCP,
|
||||
packet.UDP,
|
||||
ipproto.TCP,
|
||||
ipproto.UDP,
|
||||
}
|
||||
matches := []filter.Match{
|
||||
{IPProto: protos, Srcs: nets("5.6.7.8"), Dsts: netports("1.2.3.4:89-90")},
|
||||
|
@ -35,6 +35,7 @@
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tshttpproxy"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ipproto"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/netmap"
|
||||
@ -462,7 +463,7 @@ func (e *userspaceEngine) isLocalAddr(ip netaddr.IP) bool {
|
||||
|
||||
// handleDNS is an outbound pre-filter resolving Tailscale domains.
|
||||
func (e *userspaceEngine) handleDNS(p *packet.Parsed, t *tstun.TUN) filter.Response {
|
||||
if p.Dst.IP == magicDNSIP && p.Dst.Port == magicDNSPort && p.IPProto == packet.UDP {
|
||||
if p.Dst.IP == magicDNSIP && p.Dst.Port == magicDNSPort && p.IPProto == ipproto.UDP {
|
||||
request := tsdns.Packet{
|
||||
Payload: append([]byte(nil), p.Payload()...),
|
||||
Addr: netaddr.IPPort{IP: p.Src.IP, Port: p.Src.Port},
|
||||
|
Loading…
Reference in New Issue
Block a user