From 4069fad297f6bda0e4ac5be7b647b93002e92d9b Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Wed, 16 Aug 2023 10:34:05 +0200 Subject: [PATCH 1/2] slayers: unmap IPv4-mapped IPv6 addresses The Go standard library can produce IPv4-mapped IPv6 addresses when resolving IP addresses. These IP addresses need to be unmapped before putting them on the wire. Before this patch, we could observe the following with tshark: Len=1304 SCION 1-ff00:0:110,[::ffff:172.20.2.2] -> 1-ff00:0:111,[::ffff:172.20.3.2] UDP 32769 -> 32768 1208 The regression was introduced in #4346, which removed the unmapping behavior in slayers.PackAddr. This patch restores the behavior to ensure only unmapped IPv4 addresses make it on the wire. --- pkg/slayers/scion.go | 4 ++++ pkg/slayers/scion_test.go | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/slayers/scion.go b/pkg/slayers/scion.go index 7e24772f14..5fdc8f26fa 100644 --- a/pkg/slayers/scion.go +++ b/pkg/slayers/scion.go @@ -398,6 +398,10 @@ func PackAddr(host addr.Host) (AddrType, []byte, error) { if !ip.IsValid() { break } + // If the IP is IPv4-in-IPv6, we need to unmap it. + if ip.Is4In6() { + return T4Ip, ip.Unmap().AsSlice(), nil + } t := T4Ip if ip.Is6() { t = T16Ip diff --git a/pkg/slayers/scion_test.go b/pkg/slayers/scion_test.go index 06d4967551..a794587614 100644 --- a/pkg/slayers/scion_test.go +++ b/pkg/slayers/scion_test.go @@ -33,10 +33,11 @@ import ( ) var ( - ip6Addr = addr.MustParseHost("2001:db8::68") - ip4Addr = addr.MustParseHost("10.0.0.100") - svcAddr = addr.MustParseHost("Wildcard") - rawPath = func() []byte { + ip6Addr = addr.MustParseHost("2001:db8::68") + ip4Addr = addr.MustParseHost("10.0.0.100") + ip4in6Addr = addr.MustParseHost("::ffff:10.0.0.100") + svcAddr = addr.MustParseHost("Wildcard") + rawPath = func() []byte { return []byte("\x00\x00\x20\x80\x00\x00\x01\x11\x00\x00\x01\x00\x01\x00\x02\x22\x00" + "\x00\x01\x00\x00\x3f\x00\x01\x00\x00\x01\x02\x03\x04\x05\x06\x00\x3f\x00\x03\x00" + "\x02\x01\x02\x03\x04\x05\x06\x00\x3f\x00\x00\x00\x02\x01\x02\x03\x04\x05\x06\x00" + @@ -311,6 +312,12 @@ func TestPackAddr(t *testing.T) { rawAddr: ip4Addr.IP().AsSlice(), errorFunc: assert.NoError, }, + "pack IPv4-mapped IPv6": { + addr: ip4in6Addr, + addrType: slayers.T4Ip, + rawAddr: []byte{0xa, 0x0, 0x0, 0x64}, + errorFunc: assert.NoError, + }, "pack IPv6": { addr: ip6Addr, addrType: slayers.T16Ip, From 7c8847d58c9f142961896e3c5955ce6dae24b256 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Mon, 21 Aug 2023 13:11:37 +0200 Subject: [PATCH 2/2] simplify code --- pkg/slayers/scion.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pkg/slayers/scion.go b/pkg/slayers/scion.go index 5fdc8f26fa..66ff20c755 100644 --- a/pkg/slayers/scion.go +++ b/pkg/slayers/scion.go @@ -394,19 +394,16 @@ func ParseAddr(addrType AddrType, raw []byte) (addr.Host, error) { func PackAddr(host addr.Host) (AddrType, []byte, error) { switch host.Type() { case addr.HostTypeIP: - ip := host.IP() + // The IP is potentially IPv4-in-IPv6. We need to unmap it to ensure + // we only have true IPv4 or IPv6 addresses. + ip := host.IP().Unmap() if !ip.IsValid() { break } - // If the IP is IPv4-in-IPv6, we need to unmap it. - if ip.Is4In6() { - return T4Ip, ip.Unmap().AsSlice(), nil - } - t := T4Ip if ip.Is6() { - t = T16Ip + return T16Ip, ip.AsSlice(), nil } - return t, ip.AsSlice(), nil + return T4Ip, ip.AsSlice(), nil case addr.HostTypeSVC: raw := make([]byte, 4) binary.BigEndian.PutUint16(raw, uint16(host.SVC()))