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

Adding sam and bob #107

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
106 changes: 106 additions & 0 deletions multiaddr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,76 @@ func TestConstructFails(t *testing.T) {
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu:80",
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq:-1",
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu@",
"/sam3/8|7|6|6|2|2",
"/sam3/0|8|6|6|2|2",
"/sam3/0|2|0|6|2|2",
"/sam3/0|2|6|0|2|2",
"/sam3/0|2|7|6|2|2",
"/sam3/0|2|6|7|2|2",
"/sam3/0|7|6|6|-1|2",
"/sam3/3|0|6|6|2|-1",
"/sam3/3|0|6|6|3|2",
"/sam3/3|0|6|6|2|3",
"/sam3/-1|0|6|6|2|2",
"/sam3/3|-1|6|6|2|2",
"/sam3/3|2|6|6|-2|2",
"/sam3/3|2|6|6|2|-2",
"/sam3/3|2|6|6|2|2|7",
"/sam3/a|2|6|6|2|2",
"/sam3/2|a|6|6|2|2",
"/sam3/2|2|a|6|2|2",
"/sam3/2|2|6|a|2|2",
"/sam3/2|2|6|6|a|2",
"/sam3/2|2|6|6|2|a",
"/sam3/3|2|6|6|2",
"/sam2/8|7|6|6|2|2",
"/sam2/0|8|6|6|2|2",
"/sam2/0|2|0|6|2|2",
"/sam2/0|2|6|0|2|2",
"/sam2/0|2|7|6|2|2",
"/sam2/0|2|6|7|2|2",
"/sam2/0|7|6|6|-1|2",
"/sam2/3|0|6|6|2|-1",
"/sam2/3|0|6|6|3|2",
"/sam2/3|0|6|6|2|3",
"/sam2/-1|0|6|6|2|2",
"/sam2/3|-1|6|6|2|2",
"/sam2/3|2|6|6|-2|2",
"/sam2/3|2|6|6|2|-2",
"/sam2/3|2|6|6|2|2|7",
"/sam2/3|2|6|6|2",
"/sam1/8|7|6|6|2|2",
"/sam1/0|8|6|6|2|2",
"/sam1/0|2|0|6|2|2",
"/sam1/0|2|6|0|2|2",
"/sam1/0|2|7|6|2|2",
"/sam1/0|2|6|7|2|2",
"/sam1/0|7|6|6|-1|2",
"/sam1/3|0|6|6|2|-1",
"/sam1/3|0|6|6|3|2",
"/sam1/3|0|6|6|2|3",
"/sam1/-1|0|6|6|2|2",
"/sam1/3|-1|6|6|2|2",
"/sam1/3|2|6|6|-2|2",
"/sam1/3|2|6|6|2|-2",
"/sam1/3|2|6|6|2|2|7",
"/sam1/3|2|6|6|2",
"/bob/8|7|6|6|2|2",
"/bob/0|8|6|6|2|2",
"/bob/0|2|0|6|2|2",
"/bob/0|2|6|0|2|2",
"/bob/0|2|7|6|2|2",
"/bob/0|2|6|7|2|2",
"/bob/0|7|6|6|-1|2",
"/bob/3|0|6|6|2|-1",
"/bob/3|0|6|6|3|2",
"/bob/3|0|6|6|2|3",
"/bob/-1|0|6|6|2|2",
"/bob/3|-1|6|6|2|2",
"/bob/3|2|6|6|-2|2",
"/bob/3|2|6|6|2|-2",
"/bob/3|2|6|6|2|2|7",
"/bob/3|2|6|6|2",
"/udp/1234/sctp",
"/udp/1234/udt/1234",
"/udp/1234/utp/1234",
Expand Down Expand Up @@ -117,6 +187,18 @@ func TestConstructSucceeds(t *testing.T) {
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq/http",
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq/tcp/8080",
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq/udp/8080",
"/sam3/0|0|1|1|0|0",
"/sam3/4|4|6|6|-1|-1",
"/sam3/3|3|6|6|2|2",
"/sam2/0|0|1|1|0|0",
"/sam2/4|4|6|6|-1|-1",
"/sam2/3|3|6|6|2|2",
"/sam1/0|0|1|1|0|0",
"/sam1/4|4|6|6|-1|-1",
"/sam1/3|3|6|6|2|2",
"/bob/0|0|1|1|0|0",
"/bob/4|4|6|6|-1|-1",
"/bob/3|3|6|6|2|2",
"/udp/0",
"/tcp/0",
"/sctp/0",
Expand Down Expand Up @@ -163,6 +245,14 @@ func TestEqual(t *testing.T) {
m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")
m3 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")
m4 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234/")
m5 := newMultiaddr(t, "/sam3/4|4|6|6|-1|-1")
m6 := newMultiaddr(t, "/sam3/3|3|6|6|2|2")
m7 := newMultiaddr(t, "/sam2/4|4|6|6|-1|-1")
m8 := newMultiaddr(t, "/sam2/3|3|6|6|2|2")
m9 := newMultiaddr(t, "/sam1/4|4|6|6|-1|-1")
m10 := newMultiaddr(t, "/sam1/3|3|6|6|2|2")
m11 := newMultiaddr(t, "/bob/4|4|6|6|-1|-1")
m12 := newMultiaddr(t, "/bob/3|3|6|6|2|2")

if m1.Equal(m2) {
t.Error("should not be equal")
Expand Down Expand Up @@ -191,6 +281,22 @@ func TestEqual(t *testing.T) {
if !m4.Equal(m3) {
t.Error("should be equal")
}

if !m5.Equal(m6) {
t.Error("should be equal")
}

if !m7.Equal(m8) {
t.Error("should be equal")
}

if !m9.Equal(m10) {
t.Error("should be equal")
}

if !m11.Equal(m12) {
t.Error("should be equal")
}
}

func TestStringToBytes(t *testing.T) {
Expand Down
36 changes: 36 additions & 0 deletions protocols.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const (
P_ONION3 = 0x01BD
P_GARLIC64 = 0x01BE
P_GARLIC32 = 0x01BF
P_BOB = 0x01FE
P_SAM3 = 0x0205
P_SAM2 = 0x0204
P_SAM1 = 0x0203
P_P2P_WEBRTC_DIRECT = 0x0114
)

Expand Down Expand Up @@ -109,6 +113,34 @@ var (
Size: LengthPrefixedVarSize,
Transcoder: TranscoderGarlic32,
}
protoBOB = Protocol{
Name: "bob",
Code: P_BOB,
VCode: CodeToVarint(P_BOB),
Size: LengthGarlicBridgeSize,
Transcoder: TranscoderGarlicBridge,
}
protoSAM3 = Protocol{
Name: "sam3",
Code: P_SAM3,
VCode: CodeToVarint(P_SAM3),
Size: LengthGarlicBridgeSize,
Transcoder: TranscoderGarlicBridge,
}
protoSAM2 = Protocol{
Name: "sam2",
Code: P_SAM2,
VCode: CodeToVarint(P_SAM2),
Size: LengthGarlicBridgeSize,
Transcoder: TranscoderGarlicBridge,
}
protoSAM1 = Protocol{
Name: "sam1",
Code: P_SAM1,
VCode: CodeToVarint(P_SAM1),
Size: LengthGarlicBridgeSize,
Transcoder: TranscoderGarlicBridge,
}
protoUTP = Protocol{
Name: "utp",
Code: P_UTP,
Expand Down Expand Up @@ -169,6 +201,10 @@ func init() {
protoONION3,
protoGARLIC64,
protoGARLIC32,
protoSAM3,
protoSAM2,
protoSAM1,
protoBOB,
protoUTP,
protoUDT,
protoQUIC,
Expand Down
126 changes: 126 additions & 0 deletions transcoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,132 @@ func garlic32Validate(b []byte) error {
return nil
}

var LengthGarlicBridgeSize = 2
var TranscoderGarlicBridge = NewTranscoderFromFunctions(garlicBridgeStB, garlicBridgeBtS, garlicBridgeValidate)

var errorGarlicBridgeUpstreamNegativeHop = fmt.Errorf("A garlic bridge can't have a negative number of hops (your alterator is making this), check upstream.")
var errorGarlicBridgeDownstreamNegativeHop = fmt.Errorf("A garlic bridge can't have a negative number of hops (your alterator is making this), check downstream.")

func garlicBridgeStB(s string) ([]byte, error) {
sl := strings.SplitN(s, "|", 7)
if len(sl) != 6 {
return nil, fmt.Errorf("A garlic bridge should have 6 params separated by 5 \"|\", not %d.", len(sl))
}
v1, err := strconv.Atoi(sl[0])
if err != nil {
return nil, err
}
if v1 < 0 || v1 > 7 {
return nil, fmt.Errorf("A garlic bridge can't have more than 7 hops, not %d, check upstream.", v1)
}
v2, err := strconv.Atoi(sl[1])
if err != nil {
return nil, err
}
if v2 < 0 || v2 > 7 {
return nil, fmt.Errorf("A garlic bridge can't have more than 7 hops, not %d, check downstream.", v2)
}
v3, err := strconv.Atoi(sl[2])
if err != nil {
return nil, err
}
if v3 < 1 || v3 > 6 {
return nil, fmt.Errorf("A garlic bridge must have 1 up to 6 tunnel, not %d, check upstream.", v3)
}
v4, err := strconv.Atoi(sl[3])
if err != nil {
return nil, err
}
if v4 < 1 || v4 > 6 {
return nil, fmt.Errorf("A garlic bridge must have 1 up to 6 tunnel, not %d, check downstream.", v4)
}
v5, err := strconv.Atoi(sl[4])
if err != nil {
return nil, err
}
if v5 < -1 || v5 > 2 {
return nil, fmt.Errorf("A garlic bridge alterator must be between -1 and 2 (included), not %d, check upstream.", v5)
}
if v5 == -1 {
if v1 == 0 {
return nil, errorGarlicBridgeUpstreamNegativeHop
}
v1 -= 1
v5 = 2
}
v6, err := strconv.Atoi(sl[5])
if err != nil {
return nil, err
}
if v6 < -1 || v6 > 2 {
return nil, fmt.Errorf("A garlic bridge alterator must be between -1 and 2 (included), not %d, check downstream.", v6)
}
if v6 == -1 {
if v2 == 0 {
return nil, errorGarlicBridgeDownstreamNegativeHop
}
v2 -= 1
v6 = 2
}

return []byte{
byte((v1 << 5) + (v2 << 2) + (v3 >> 1)),
byte((v3 << 7) + (v4 << 4) + (v5 << 2) + v6),
}, nil
}

func garlicExtractor(b []byte) [6]uint8 {
// Don't transform the uint8 in a uint, this stricity is used to colide with
// border in conversion.
u := [2]uint8{uint8(b[0]), uint8(b[1])}
var r [6]uint8
r[5] = (u[1] << 6) >> 6
r[4] = (u[1] << 4) >> 6
r[3] = (u[1] << 1) >> 5
r[2] = ((u[0] << 6) >> 5) + (u[1] >> 7)
r[1] = (u[0] << 3) >> 5
r[0] = u[0] >> 5

return r
}

func garlicBridgeBtS(b []byte) (string, error) {
err := garlicBridgeValidate(b)
if err != nil {
return "", err
}
var rs string
for i, e := range garlicExtractor(b) {
rs += strconv.Itoa(int(e))
if i != 5 {
rs += "|"
}
}
return rs, nil
}

func garlicBridgeValidate(b []byte) error {
if len(b) != 2 {
return fmt.Errorf("A garlic bridge compiled version length must be 2, not %d.", len(b))
}
lv := garlicExtractor(b)

if lv[2] < 1 || lv[2] > 6 {
return fmt.Errorf("A garlic bridge must have 1 up to 6 tunnel, not %d, check upstream.", lv[2])
}
if lv[3] < 1 || lv[3] > 6 {
return fmt.Errorf("A garlic bridge must have 1 up to 6 tunnel, not %d, check downstream.", lv[3])
}
if lv[4] > 2 {
return fmt.Errorf("A garlic bridge alterator compiled can't be bigger than 2, not %d, check upstream.", lv[4])
}
if lv[5] > 2 {
return fmt.Errorf("A garlic bridge alterator compiled can't be bigger than 2, not %d, check downstream.", lv[5])
}

return nil
}

var TranscoderP2P = NewTranscoderFromFunctions(p2pStB, p2pBtS, p2pVal)

func p2pStB(s string) ([]byte, error) {
Expand Down
42 changes: 42 additions & 0 deletions transcoders_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package multiaddr

import "testing"

func TestGarlicBridge(t *testing.T) {
// Simple code and decode
fS := "7|7|6|6|2|2"
B, err := garlicBridgeStB(fS)
if err != nil {
t.Error(err)
}
err = garlicBridgeValidate(B)
if err != nil {
t.Error(err)
}
S, err := garlicBridgeBtS(B)
if err != nil {
t.Error(err)
}
if fS != S {
t.Fatalf("Got %v instead of %v.", S, fS)
}

shouldFail := [][]byte{ // sample (7|7|6|6|2|2) : []byte{0xFF,0x6A},
[]byte{0xFF, 0xEA},
[]byte{0xFF, 0x7A},
[]byte{0xFF, 0x7E},
[]byte{0xFF, 0x7B},
[]byte{0xFC, 0x4A},
[]byte{0xFE, 0x0A},
[]byte{0xFE, 0xDE},
[]byte{0xFE, 0xDB},
[]byte{0xFF, 0x7B, 0xFF},
[]byte{0xFF},
}
for _, e := range shouldFail {
S, err = garlicBridgeBtS(e)
if err == nil || S != "" {
t.Fatalf("Should fail but works with %v, and got %v.", e, S)
}
}
}