net/stun: unmap IPv4 addresses in 16 byte STUN replies

Updates #5602

Change-Id: I2276ad2bfb415b9ff52f37444f2a1d74b38543b1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/5605/head
Brad Fitzpatrick 2 years ago committed by Brad Fitzpatrick
parent eb5939289c
commit 024257ef5a

@ -208,7 +208,7 @@ func ParseResponse(b []byte) (tID TxID, addr netip.AddrPort, err error) {
b = b[:attrsLen] // trim trailing packet bytes b = b[:attrsLen] // trim trailing packet bytes
} }
var addr6, fallbackAddr, fallbackAddr6 netip.AddrPort var fallbackAddr netip.AddrPort
// Read through the attributes. // Read through the attributes.
// The the addr+port reported by XOR-MAPPED-ADDRESS // 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 { if err := foreachAttr(b, func(attrType uint16, attr []byte) error {
switch attrType { switch attrType {
case attrXorMappedAddress, attrXorMappedAddressAlt: case attrXorMappedAddress, attrXorMappedAddressAlt:
a, p, err := xorMappedAddress(tID, attr) ipSlice, port, err := xorMappedAddress(tID, attr)
if err != nil { if err != nil {
return err return err
} }
if len(a) == 16 { if ip, ok := netip.AddrFromSlice(ipSlice); ok {
addr6 = netip.AddrPortFrom(netip.AddrFrom16(*(*[16]byte)([]byte(a))), p) addr = netip.AddrPortFrom(ip.Unmap(), port)
} else {
addr = netip.AddrPortFrom(netip.AddrFrom4(*(*[4]byte)([]byte(a))), p)
} }
case attrMappedAddress: case attrMappedAddress:
a, p, err := mappedAddress(attr) ipSlice, port, err := mappedAddress(attr)
if err != nil { if err != nil {
return ErrMalformedAttrs return ErrMalformedAttrs
} }
if len(a) == 16 { if ip, ok := netip.AddrFromSlice(ipSlice); ok {
fallbackAddr6 = netip.AddrPortFrom(netip.AddrFrom16(*(*[16]byte)([]byte(a))), p) fallbackAddr = netip.AddrPortFrom(ip.Unmap(), port)
} else {
fallbackAddr = netip.AddrPortFrom(netip.AddrFrom4(*(*[4]byte)([]byte(a))), p)
} }
} }
return nil return nil
@ -250,12 +246,6 @@ func ParseResponse(b []byte) (tID TxID, addr netip.AddrPort, err error) {
if fallbackAddr.IsValid() { if fallbackAddr.IsValid() {
return tID, fallbackAddr, nil return tID, fallbackAddr, nil
} }
if addr6.IsValid() {
return tID, addr6, nil
}
if fallbackAddr6.IsValid() {
return tID, fallbackAddr6, nil
}
return tID, netip.AddrPort{}, ErrMalformedAttrs return tID, netip.AddrPort{}, ErrMalformedAttrs
} }

@ -6,11 +6,13 @@ package stun_test
import ( import (
"bytes" "bytes"
"encoding/hex"
"fmt" "fmt"
"net/netip" "net/netip"
"testing" "testing"
"tailscale.com/net/stun" "tailscale.com/net/stun"
"tailscale.com/util/must"
) )
// TODO(bradfitz): fuzz this. // TODO(bradfitz): fuzz this.
@ -175,6 +177,13 @@ var responseTests = []struct {
wantAddr: netip.AddrFrom4([4]byte{127, 0, 0, 1}), wantAddr: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
wantPort: 61300, 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) { func TestParseResponse(t *testing.T) {

Loading…
Cancel
Save