Skip to content

Commit

Permalink
slayers: unmap IPv4-mapped IPv6 addresses (#4377)
Browse files Browse the repository at this point in the history
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.


Handling the unmapping in the code that generates the addresses and only
checking this in slayers would seem ideal, but these calls are often
very far away from the place that would then trigger an error. Thus
handling this in slayers seems like a compromise that saves us and the
users of the slayers package a lot of trouble.
  • Loading branch information
oncilla authored Oct 10, 2023
1 parent 54a26ba commit 1774cbf
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
9 changes: 5 additions & 4 deletions pkg/slayers/scion.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +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
}
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()))
Expand Down
15 changes: 11 additions & 4 deletions pkg/slayers/scion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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" +
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 1774cbf

Please sign in to comment.