updated multiaddr
Juan Batiz-Benet committed
Jan 9, 2015 at 05:51 UTC
19a5f088d53551a917dc5e0620db7242c331ce9d
8 files changed
+174
-38
Godeps/Godeps.json
+2
-2
@@ -122,8 +122,8 @@
122
},
123
{
124
"ImportPath": "github.com/jbenet/go-multiaddr",
125
- "Comment": "0.1.2-30-g99cf3ed",
126
- "Rev": "99cf3edc711751cf7b43505fac0e3913f6b9a75c"
125
+ "Comment": "0.1.2-34-g0d7b54b",
126
+ "Rev": "0d7b54ba432fda14bac37cdad717bd6270eacc85"
127
},
128
{
129
"ImportPath": "github.com/jbenet/go-multiaddr-net",
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md
+3
-3
@@ -28,9 +28,9 @@ m2.Equal(m1)
28
```go
29
// get the multiaddr protocol description objects
30
addr.Protocols()
31
-// []*Protocol{
32
-// &Protocol{ Code: 4, Name: 'ip4', Size: 32},
33
-// &Protocol{ Code: 17, Name: 'udp', Size: 16},
31
+// []Protocol{
32
+// Protocol{ Code: 4, Name: 'ip4', Size: 32},
33
+// Protocol{ Code: 17, Name: 'udp', Size: 16},
34
// }
35
```
36
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go
+31
-13
@@ -25,14 +25,20 @@ func stringToBytes(s string) ([]byte, error) {
25
26
for len(sp) > 0 {
27
p := ProtocolWithName(sp[0])
28
- if p == nil {
28
+ if p.Code == 0 {
29
return nil, fmt.Errorf("no protocol with name %s", sp[0])
30
}
31
b = append(b, CodeToVarint(p.Code)...)
32
sp = sp[1:]
33
34
if p.Size > 0 {
35
- a := addressStringToBytes(p, sp[0])
35
+ if len(sp) < 1 {
36
+ return nil, fmt.Errorf("protocol requires address, none given: %s", p.Name)
37
+ }
38
+ a, err := addressStringToBytes(p, sp[0])
39
+ if err != nil {
40
+ return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err)
41
+ }
42
b = append(b, a...)
43
sp = sp[1:]
44
}
@@ -56,7 +62,7 @@ func bytesToString(b []byte) (ret string, err error) {
62
code, n := ReadVarintCode(b)
63
b = b[n:]
64
p := ProtocolWithCode(code)
59
- if p == nil {
65
+ if p.Code == 0 {
66
return "", fmt.Errorf("no protocol with code %d", code)
67
}
68
s = strings.Join([]string{s, "/", p.Name}, "")
@@ -86,7 +92,7 @@ func bytesSplit(b []byte) (ret [][]byte, err error) {
92
for len(b) > 0 {
93
code, n := ReadVarintCode(b)
94
p := ProtocolWithCode(code)
89
- if p == nil {
95
+ if p.Code == 0 {
96
return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0])
97
}
98
@@ -98,29 +104,41 @@ func bytesSplit(b []byte) (ret [][]byte, err error) {
104
return ret, nil
105
}
106
101
-func addressStringToBytes(p *Protocol, s string) []byte {
107
+func addressStringToBytes(p Protocol, s string) ([]byte, error) {
108
switch p.Code {
109
110
case P_IP4: // ipv4
105
- return net.ParseIP(s).To4()
111
+ i := net.ParseIP(s).To4()
112
+ if i == nil {
113
+ return nil, fmt.Errorf("failed to parse ip4 addr: %s", s)
114
+ }
115
+ return i, nil
116
117
case P_IP6: // ipv6
108
- return net.ParseIP(s).To16()
118
+ i := net.ParseIP(s).To16()
119
+ if i == nil {
120
+ return nil, fmt.Errorf("failed to parse ip6 addr: %s", s)
121
+ }
122
+ return i, nil
123
124
// tcp udp dccp sctp
125
case P_TCP, P_UDP, P_DCCP, P_SCTP:
112
- b := make([]byte, 2)
126
i, err := strconv.Atoi(s)
114
- if err == nil {
115
- binary.BigEndian.PutUint16(b, uint16(i))
127
+ if err != nil {
128
+ return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, err)
129
+ }
130
+ if i >= 65536 {
131
+ return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "greater than 65536")
132
}
117
- return b
133
+ b := make([]byte, 2)
134
+ binary.BigEndian.PutUint16(b, uint16(i))
135
+ return b, nil
136
}
137
120
- return []byte{}
138
+ return []byte{}, fmt.Errorf("failed to parse %s addr: unknown", p.Name)
139
}
140
123
-func addressBytesToString(p *Protocol, b []byte) string {
141
+func addressBytesToString(p Protocol, b []byte) string {
142
switch p.Code {
143
144
// ipv4,6
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/interface.go
+1
-1
@@ -26,7 +26,7 @@ type Multiaddr interface {
26
27
// Protocols returns the list of Protocols this Multiaddr includes
28
// will panic if protocol code incorrect (and bytes accessed incorrectly)
29
- Protocols() []*Protocol
29
+ Protocols() []Protocol
30
31
// Encapsulate wraps this Multiaddr around another. For example:
32
//
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go
+3
-3
@@ -54,7 +54,7 @@ func (m *multiaddr) String() string {
54
55
// Protocols returns the list of protocols this Multiaddr has.
56
// will panic in case we access bytes incorrectly.
57
-func (m *multiaddr) Protocols() []*Protocol {
57
+func (m *multiaddr) Protocols() []Protocol {
58
59
// panic handler, in case we try accessing bytes incorrectly.
60
defer func() {
@@ -64,12 +64,12 @@ func (m *multiaddr) Protocols() []*Protocol {
64
}
65
}()
66
67
- ps := []*Protocol{}
67
+ ps := []Protocol{}
68
b := m.bytes[:]
69
for len(b) > 0 {
70
code, n := ReadVarintCode(b)
71
p := ProtocolWithCode(code)
72
- if p == nil {
72
+ if p.Code == 0 {
73
// this is a panic (and not returning err) because this should've been
74
// caught on constructing the Multiaddr
75
panic(fmt.Errorf("no protocol with code %d", b[0]))
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go
+99
-2
@@ -14,6 +14,63 @@ func newMultiaddr(t *testing.T, a string) Multiaddr {
14
return m
15
}
16
17
+func TestConstructFails(t *testing.T) {
18
+ cases := []string{
19
+ "/ip4",
20
+ "/ip4/::1",
21
+ "/ip4/fdpsofodsajfdoisa",
22
+ "/ip6",
23
+ "/udp",
24
+ "/tcp",
25
+ "/sctp",
26
+ "/udp/65536",
27
+ "/tcp/65536",
28
+ "/udp/1234/sctp",
29
+ "/udp/1234/udt/1234",
30
+ "/udp/1234/utp/1234",
31
+ "/ip4/127.0.0.1/udp/jfodsajfidosajfoidsa",
32
+ "/ip4/127.0.0.1/udp",
33
+ "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa",
34
+ "/ip4/127.0.0.1/tcp",
35
+ }
36
+
37
+ for _, a := range cases {
38
+ if _, err := NewMultiaddr(a); err == nil {
39
+ t.Errorf("should have failed: %s", a)
40
+ }
41
+ }
42
+}
43
+
44
+func TestConstructSucceeds(t *testing.T) {
45
+ cases := []string{
46
+ "/ip4/1.2.3.4",
47
+ "/ip4/0.0.0.0",
48
+ "/ip6/::1",
49
+ "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21",
50
+ "/udp/0",
51
+ "/tcp/0",
52
+ "/sctp/0",
53
+ "/udp/1234",
54
+ "/tcp/1234",
55
+ "/sctp/1234",
56
+ "/udp/65535",
57
+ "/tcp/65535",
58
+ "/udp/1234/sctp/1234",
59
+ "/udp/1234/udt",
60
+ "/udp/1234/utp",
61
+ "/ip4/127.0.0.1/udp/1234",
62
+ "/ip4/127.0.0.1/udp/0",
63
+ "/ip4/127.0.0.1/tcp/1234",
64
+ "/ip4/127.0.0.1/tcp/1234/",
65
+ }
66
+
67
+ for _, a := range cases {
68
+ if _, err := NewMultiaddr(a); err != nil {
69
+ t.Errorf("should have succeeded: %s", a)
70
+ }
71
+ }
72
+}
73
+
74
func TestEqual(t *testing.T) {
75
m1 := newMultiaddr(t, "/ip4/127.0.0.1/udp/1234")
76
m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")
@@ -147,18 +204,58 @@ func TestProtocols(t *testing.T) {
204
}
205
206
ps := m.Protocols()
150
- if ps[0] != ProtocolWithName("ip4") {
207
+ if ps[0].Code != ProtocolWithName("ip4").Code {
208
t.Error(ps[0], ProtocolWithName("ip4"))
209
t.Error("failed to get ip4 protocol")
210
}
211
155
- if ps[1] != ProtocolWithName("udp") {
212
+ if ps[1].Code != ProtocolWithName("udp").Code {
213
t.Error(ps[1], ProtocolWithName("udp"))
214
t.Error("failed to get udp protocol")
215
}
216
217
}
218
219
+func TestProtocolsWithString(t *testing.T) {
220
+ pwn := ProtocolWithName
221
+ good := map[string][]Protocol{
222
+ "/ip4": []Protocol{pwn("ip4")},
223
+ "/ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")},
224
+ "ip4/tcp/udp/ip6": []Protocol{pwn("ip4"), pwn("tcp"), pwn("udp"), pwn("ip6")},
225
+ "////////ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")},
226
+ "ip4/udp/////////": []Protocol{pwn("ip4"), pwn("udp")},
227
+ "////////ip4/tcp////////": []Protocol{pwn("ip4"), pwn("tcp")},
228
+ }
229
+
230
+ for s, ps1 := range good {
231
+ ps2, err := ProtocolsWithString(s)
232
+ if err != nil {
233
+ t.Error("ProtocolsWithString(%s) should have succeeded", s)
234
+ }
235
+
236
+ for i, ps1p := range ps1 {
237
+ ps2p := ps2[i]
238
+ if ps1p.Code != ps2p.Code {
239
+ t.Errorf("mismatch: %s != %s, %s", ps1p.Name, ps2p.Name, s)
240
+ }
241
+ }
242
+ }
243
+
244
+ bad := []string{
245
+ "dsijafd", // bogus proto
246
+ "/ip4/tcp/fidosafoidsa", // bogus proto
247
+ "////////ip4/tcp/21432141/////////", // bogus proto
248
+ "////////ip4///////tcp/////////", // empty protos in between
249
+ }
250
+
251
+ for _, s := range bad {
252
+ if _, err := ProtocolsWithString(s); err == nil {
253
+ t.Error("ProtocolsWithString(%s) should have failed", s)
254
+ }
255
+ }
256
+
257
+}
258
+
259
func TestEncapsulate(t *testing.T) {
260
m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
261
if err != nil {
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.go
+34
-13
@@ -2,6 +2,8 @@ package multiaddr
2
3
import (
4
"encoding/binary"
5
+ "fmt"
6
+ "strings"
7
)
8
9
// Protocol is a Multiaddr protocol description structure.
@@ -28,38 +30,57 @@ const (
30
)
31
32
// Protocols is the list of multiaddr protocols supported by this module.
31
-var Protocols = []*Protocol{
32
- &Protocol{P_IP4, 32, "ip4", CodeToVarint(P_IP4)},
33
- &Protocol{P_TCP, 16, "tcp", CodeToVarint(P_TCP)},
34
- &Protocol{P_UDP, 16, "udp", CodeToVarint(P_UDP)},
35
- &Protocol{P_DCCP, 16, "dccp", CodeToVarint(P_DCCP)},
36
- &Protocol{P_IP6, 128, "ip6", CodeToVarint(P_IP6)},
33
+var Protocols = []Protocol{
34
+ Protocol{P_IP4, 32, "ip4", CodeToVarint(P_IP4)},
35
+ Protocol{P_TCP, 16, "tcp", CodeToVarint(P_TCP)},
36
+ Protocol{P_UDP, 16, "udp", CodeToVarint(P_UDP)},
37
+ Protocol{P_DCCP, 16, "dccp", CodeToVarint(P_DCCP)},
38
+ Protocol{P_IP6, 128, "ip6", CodeToVarint(P_IP6)},
39
// these require varint:
38
- &Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)},
39
- &Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)},
40
- &Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)},
40
+ Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)},
41
+ Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)},
42
+ Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)},
43
// {480, 0, "http"},
44
// {443, 0, "https"},
45
}
46
47
// ProtocolWithName returns the Protocol description with given string name.
46
-func ProtocolWithName(s string) *Protocol {
48
+func ProtocolWithName(s string) Protocol {
49
for _, p := range Protocols {
50
if p.Name == s {
51
return p
52
}
53
}
52
- return nil
54
+ return Protocol{}
55
}
56
57
// ProtocolWithCode returns the Protocol description with given protocol code.
56
-func ProtocolWithCode(c int) *Protocol {
58
+func ProtocolWithCode(c int) Protocol {
59
for _, p := range Protocols {
60
if p.Code == c {
61
return p
62
}
63
}
62
- return nil
64
+ return Protocol{}
65
+}
66
+
67
+// ProtocolsWithString returns a slice of protocols matching given string.
68
+func ProtocolsWithString(s string) ([]Protocol, error) {
69
+ s = strings.Trim(s, "/")
70
+ sp := strings.Split(s, "/")
71
+ if len(sp) == 0 {
72
+ return nil, nil
73
+ }
74
+
75
+ t := make([]Protocol, len(sp))
76
+ for i, name := range sp {
77
+ p := ProtocolWithName(name)
78
+ if p.Code == 0 {
79
+ return nil, fmt.Errorf("no protocol with name: %s", name)
80
+ }
81
+ t[i] = p
82
+ }
83
+ return t, nil
84
}
85
86
// CodeToVarint converts an integer to a varint-encoded []byte
p2p/net/conn/dial.go
+1
-1
@@ -100,7 +100,7 @@ func MultiaddrProtocolsMatch(a, b ma.Multiaddr) bool {
100
}
101
102
for i, api := range ap {
103
- if api != bp[i] {
103
+ if api.Code != bp[i].Code {
104
return false
105
}
106
}