From 024257ef5aea749939a0b42c77f75c60d37d81b8 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 12 Sep 2022 11:37:56 -0700 Subject: [PATCH] net/stun: unmap IPv4 addresses in 16 byte STUN replies Updates #5602 Change-Id: I2276ad2bfb415b9ff52f37444f2a1d74b38543b1 Signed-off-by: Brad Fitzpatrick --- net/stun/stun.go | 24 +++++++----------------- net/stun/stun_test.go | 9 +++++++++ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/net/stun/stun.go b/net/stun/stun.go index 834b9e8c9..1acb8bf1b 100644 --- a/net/stun/stun.go +++ b/net/stun/stun.go @@ -208,7 +208,7 @@ func ParseResponse(b []byte) (tID TxID, addr netip.AddrPort, err error) { b = b[:attrsLen] // trim trailing packet bytes } - var addr6, fallbackAddr, fallbackAddr6 netip.AddrPort + var fallbackAddr netip.AddrPort // Read through the attributes. // The the addr+port reported by XOR-MAPPED-ADDRESS @@ -218,24 +218,20 @@ func ParseResponse(b []byte) (tID TxID, addr netip.AddrPort, err error) { if err := foreachAttr(b, func(attrType uint16, attr []byte) error { switch attrType { case attrXorMappedAddress, attrXorMappedAddressAlt: - a, p, err := xorMappedAddress(tID, attr) + ipSlice, port, err := xorMappedAddress(tID, attr) if err != nil { return err } - if len(a) == 16 { - addr6 = netip.AddrPortFrom(netip.AddrFrom16(*(*[16]byte)([]byte(a))), p) - } else { - addr = netip.AddrPortFrom(netip.AddrFrom4(*(*[4]byte)([]byte(a))), p) + if ip, ok := netip.AddrFromSlice(ipSlice); ok { + addr = netip.AddrPortFrom(ip.Unmap(), port) } case attrMappedAddress: - a, p, err := mappedAddress(attr) + ipSlice, port, err := mappedAddress(attr) if err != nil { return ErrMalformedAttrs } - if len(a) == 16 { - fallbackAddr6 = netip.AddrPortFrom(netip.AddrFrom16(*(*[16]byte)([]byte(a))), p) - } else { - fallbackAddr = netip.AddrPortFrom(netip.AddrFrom4(*(*[4]byte)([]byte(a))), p) + if ip, ok := netip.AddrFromSlice(ipSlice); ok { + fallbackAddr = netip.AddrPortFrom(ip.Unmap(), port) } } return nil @@ -250,12 +246,6 @@ func ParseResponse(b []byte) (tID TxID, addr netip.AddrPort, err error) { if fallbackAddr.IsValid() { return tID, fallbackAddr, nil } - if addr6.IsValid() { - return tID, addr6, nil - } - if fallbackAddr6.IsValid() { - return tID, fallbackAddr6, nil - } return tID, netip.AddrPort{}, ErrMalformedAttrs } diff --git a/net/stun/stun_test.go b/net/stun/stun_test.go index 4e3f78a0b..30922ed9c 100644 --- a/net/stun/stun_test.go +++ b/net/stun/stun_test.go @@ -6,11 +6,13 @@ package stun_test import ( "bytes" + "encoding/hex" "fmt" "net/netip" "testing" "tailscale.com/net/stun" + "tailscale.com/util/must" ) // TODO(bradfitz): fuzz this. @@ -175,6 +177,13 @@ var responseTests = []struct { wantAddr: netip.AddrFrom4([4]byte{127, 0, 0, 1}), wantPort: 61300, }, + { + name: "no-4in6", + data: must.Get(hex.DecodeString("010100182112a4424fd5d202dcb37d31fc773306002000140002cd3d2112a4424fd5d202dcb382ce2dc3fcc7")), + wantTID: []byte{79, 213, 210, 2, 220, 179, 125, 49, 252, 119, 51, 6}, + wantAddr: netip.AddrFrom4([4]byte{209, 180, 207, 193}), + wantPort: 60463, + }, } func TestParseResponse(t *testing.T) {