Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SCION addresses #243

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions multiaddr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ func TestConstructFails(t *testing.T) {
"/",
"",
"/p2p/QmxoHT6iViN5xAjoz1VZ553cL31U9F94ht3QvWR1FrEbZY", // sha256 multihash with digest len > 32
"/scion",
"/scion//udp/1234",
"/scion/0-",
"/scion/1234",
}

for _, a := range cases {
Expand Down Expand Up @@ -192,6 +196,10 @@ var good = []string{
"/ip4/127.0.0.1/tcp/127/wss",
"/ip4/127.0.0.1/tcp/127/webrtc-direct",
"/ip4/127.0.0.1/tcp/127/webrtc",
"/scion/0-0",
"/scion/1-ff00:0:110",
"/scion/1-ff00:0:110/ip4/1.2.3.4",
"/scion/1-ff00:0:110/ip6/::ffff:127.0.0.1/udp/111",
"/http-path/tmp%2Fbar",
"/http-path/tmp%2Fbar%2Fbaz",
"/http-path/foo",
Expand Down Expand Up @@ -438,6 +446,12 @@ func TestEncapsulate(t *testing.T) {
if d != nil {
t.Error("decapsulate /ip4 failed: ", d)
}

m5, _ := NewMultiaddr("/scion/1-ff00:0:110")
e := m5.Encapsulate(m)
if s := e.String(); s != "/scion/1-ff00:0:110/ip4/127.0.0.1/udp/1234" {
t.Error("encapsulate /scion/1-ff00:0:110/ip4/127.0.0.1/udp/1234 failed.", s)
}
}

func TestDecapsulateComment(t *testing.T) {
Expand Down Expand Up @@ -546,6 +560,11 @@ func TestGetValue(t *testing.T) {
a = newMultiaddr(t, "/ip4/0.0.0.0/unix/a/b/c/d") // ending in a path one.
assertValueForProto(t, a, P_IP4, "0.0.0.0")
assertValueForProto(t, a, P_UNIX, "/a/b/c/d")

a = newMultiaddr(t, "/scion/1-ff00:0:110/ip4/127.0.0.1/udp/1234")
assertValueForProto(t, a, P_SCION, "1-ff00:0:110")
assertValueForProto(t, a, P_IP4, "127.0.0.1")
assertValueForProto(t, a, P_UDP, "1234")
}

func FuzzNewMultiaddrBytes(f *testing.F) {
Expand Down Expand Up @@ -632,6 +651,7 @@ func TestRoundTrip(t *testing.T) {
"/ip4/127.0.0.1/udp/1234/quic-v1/webtransport/certhash/uEiDDq4_xNyDorZBH3TlGazyJdOWSwvo4PUo5YHFMrvDE8g",
"/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP",
"/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP/unix/a/b/c",
"/scion/1-ff00:0:110/ip6/::ffff:127.0.0.1/tcp/111",
"/http-path/tmp%2Fbar",
} {
ma, err := NewMultiaddr(s)
Expand Down
10 changes: 10 additions & 0 deletions protocols.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
P_PLAINTEXTV2 = 7367777
P_WEBRTC_DIRECT = 280
P_WEBRTC = 281
P_SCION = 13639680
)

var (
Expand Down Expand Up @@ -281,6 +282,14 @@ var (
Code: P_WEBRTC,
VCode: CodeToVarint(P_WEBRTC),
}
protoSCION = Protocol{
Name: "scion",
Code: P_SCION,
VCode: CodeToVarint(P_SCION),
Size: LengthPrefixedVarSize,
Path: false,
Transcoder: TranscoderSCION,
}
)

func init() {
Expand Down Expand Up @@ -322,6 +331,7 @@ func init() {
protoPlaintextV2,
protoWebRTCDirect,
protoWebRTC,
protoSCION,
} {
if err := AddProtocol(p); err != nil {
panic(err)
Expand Down
30 changes: 30 additions & 0 deletions transcoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,36 @@ func validateCertHash(b []byte) error {
return err
}

var TranscoderSCION = NewTranscoderFromFunctions(scionStB, scionBtS, scionVal)

func scionVal(b []byte) error {
// SCION IA is 16 bit ISD and 48 bit AS numbers separated by "-"
// ISD numbers formatted as decimal, AS numbering similar to IPv6
// E.g.: "0-0" or "1234-ff00:0:110"
if len(b) < 3 {
return fmt.Errorf("byte slice too short: %d", len(b))
}
if minus := bytes.IndexByte(b, '-'); minus < 0 {
return errors.New("scion addresses must contain '-'")
}
return nil
}

func scionStB(s string) ([]byte, error) {
b := []byte(s)
if err := scionVal(b); err != nil {
return nil, err
}
return b, nil
}

func scionBtS(b []byte) (string, error) {
if err := scionVal(b); err != nil {
return "", err
}
return string(b), nil
}

var TranscoderHTTPPath = NewTranscoderFromFunctions(httpPathStB, httpPathBtS, validateHTTPPath)

func httpPathStB(s string) ([]byte, error) {
Expand Down