diff --git a/multiaddr_test.go b/multiaddr_test.go index 59e50c4..2cb0cb7 100644 --- a/multiaddr_test.go +++ b/multiaddr_test.go @@ -23,6 +23,9 @@ func TestConstructFails(t *testing.T) { "/ip4/::1", "/ip4/fdpsofodsajfdoisa", "/ip6", + "/ip6zone", + "/ip6zone/", + "/ip6zone//ip6/fe80::1", "/udp", "/tcp", "/sctp", @@ -65,6 +68,10 @@ func TestConstructSucceeds(t *testing.T) { "/ip6/::1", "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21", "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21/udp/1234/quic", + "/ip6zone/x/ip6/fe80::1", + "/ip6zone/x%y/ip6/fe80::1", + "/ip6zone/x%y/ip6/::", + "/ip6zone/x/ip6/fe80::1/udp/1234/quic", "/onion/timaq4ygg2iegci7:1234", "/onion/timaq4ygg2iegci7:80/http", "/udp/0", @@ -492,3 +499,32 @@ func TestInvalidP2PAddr(t *testing.T) { _ = ma.String() } } + +func TestZone(t *testing.T) { + ip6String := "/ip6zone/eth0/ip6/::1" + ip6Bytes := []byte{ + 0x2a, 4, + 'e', 't', 'h', '0', + 0x29, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + } + + ma, err := NewMultiaddr(ip6String) + if err != nil { + t.Error(err) + } + if !bytes.Equal(ma.Bytes(), ip6Bytes) { + t.Errorf("expected %x, got %x", ip6Bytes, ma.Bytes()) + } + + ma2, err2 := NewMultiaddrBytes(ip6Bytes) + if err2 != nil { + t.Error(err) + } + if ma2.String() != ip6String { + t.Errorf("expected %s, got %s", ip6String, ma2.String()) + } +} diff --git a/protocols.go b/protocols.go index bc123a7..d466598 100644 --- a/protocols.go +++ b/protocols.go @@ -6,21 +6,22 @@ package multiaddr // TODO: Use a single source of truth for all multicodecs instead of // distributing them like this... const ( - P_IP4 = 0x0004 - P_TCP = 0x0006 - P_UDP = 0x0111 - P_DCCP = 0x0021 - P_IP6 = 0x0029 - P_QUIC = 0x01CC - P_SCTP = 0x0084 - P_UDT = 0x012D - P_UTP = 0x012E - P_UNIX = 0x0190 - P_P2P = 0x01A5 - P_IPFS = 0x01A5 // alias for backwards compatability - P_HTTP = 0x01E0 - P_HTTPS = 0x01BB - P_ONION = 0x01BC + P_IP4 = 0x0004 + P_TCP = 0x0006 + P_UDP = 0x0111 + P_DCCP = 0x0021 + P_IP6 = 0x0029 + P_IP6ZONE = 0x002A + P_QUIC = 0x01CC + P_SCTP = 0x0084 + P_UDT = 0x012D + P_UTP = 0x012E + P_UNIX = 0x0190 + P_P2P = 0x01A5 + P_IPFS = 0x01A5 // alias for backwards compatability + P_HTTP = 0x01E0 + P_HTTPS = 0x01BB + P_ONION = 0x01BC ) var ( @@ -64,6 +65,14 @@ var ( Transcoder: TranscoderIP6, } // these require varint + protoIP6ZONE = Protocol{ + Name: "ip6zone", + Code: P_IP6ZONE, + VCode: CodeToVarint(P_IP6ZONE), + Size: LengthPrefixedVarSize, + Path: false, + Transcoder: TranscoderIP6Zone, + } protoSCTP = Protocol{ Name: "sctp", Code: P_SCTP, @@ -127,6 +136,7 @@ func init() { protoUDP, protoDCCP, protoIP6, + protoIP6ZONE, protoSCTP, protoONION, protoUTP, diff --git a/transcoders.go b/transcoders.go index 7e31afa..fe64f50 100644 --- a/transcoders.go +++ b/transcoders.go @@ -47,6 +47,7 @@ func (t twrp) ValidateBytes(b []byte) error { var TranscoderIP4 = NewTranscoderFromFunctions(ip4StB, ipBtS, nil) var TranscoderIP6 = NewTranscoderFromFunctions(ip6StB, ipBtS, nil) +var TranscoderIP6Zone = NewTranscoderFromFunctions(ip6zoneStB, ip6zoneBtS, nil) func ip4StB(s string) ([]byte, error) { i := net.ParseIP(s).To4() @@ -56,6 +57,20 @@ func ip4StB(s string) ([]byte, error) { return i, nil } +func ip6zoneStB(s string) ([]byte, error) { + if len(s) == 0 { + return nil, fmt.Errorf("empty ip6zone") + } + return []byte(s), nil +} + +func ip6zoneBtS(b []byte) (string, error) { + if len(b) == 0 { + return "", fmt.Errorf("invalid length (should be > 0)") + } + return string(b), nil +} + func ip6StB(s string) ([]byte, error) { i := net.ParseIP(s).To16() if i == nil {