multiaddr update: recognize link local ip6
Juan Batiz-Benet committed
Jan 12, 2015 at 11:39 UTC
b36ca66f7cacea3067c6c9c5c742eb01be473eec
8 files changed
+181
-17
Godeps/Godeps.json
+1
-1
@@ -135,7 +135,7 @@
135
},
136
{
137
"ImportPath": "github.com/jbenet/go-multiaddr-net",
138
- "Rev": "2b8f35303d2855c79f9f3f9b3584338a1ff7edbd"
138
+ "Rev": "04044c2289504304472715d827a8f564fa3759a8"
139
},
140
{
141
"ImportPath": "github.com/jbenet/go-multihash",
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/.travis.yml
new
+11
@@ -0,0 +1,11 @@
1
+language: go
2
+
3
+go:
4
+ - 1.3
5
+ - release
6
+ - tip
7
+
8
+script:
9
+ - make test
10
+
11
+env: TEST_VERBOSE=1
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/Makefile
+3
@@ -12,5 +12,8 @@ vendor: godep
12
install: dep
13
cd multiaddr && go install
14
15
+test:
16
+ go test ./...
17
+
18
dep:
19
cd multiaddr && go get ./...
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert.go
+6
-4
@@ -112,13 +112,13 @@ func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
112
}
113
114
switch network {
115
- case "tcp":
115
+ case "tcp", "tcp4", "tcp6":
116
return net.ResolveTCPAddr(network, host)
117
- case "udp":
117
+ case "udp", "udp4", "udp6":
118
return net.ResolveUDPAddr(network, host)
119
- case "utp":
119
+ case "utp", "utp4", "utp6":
120
return utp.ResolveUTPAddr(network, host)
121
- case "ip":
121
+ case "ip", "ip4", "ip6":
122
return net.ResolveIPAddr(network, host)
123
}
124
@@ -158,8 +158,10 @@ func DialArgs(m ma.Multiaddr) (string, string, error) {
158
var host string
159
switch parts[0] {
160
case "ip4":
161
+ network = network + "4"
162
host = strings.Join([]string{parts[1], parts[3]}, ":")
163
case "ip6":
164
+ network = network + "6"
165
host = fmt.Sprintf("[%s]:%s", parts[1], parts[3])
166
}
167
return network, host, nil
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert_test.go
+6
-3
@@ -152,7 +152,10 @@ func TestDialArgs(t *testing.T) {
152
}
153
}
154
155
- test("/ip4/127.0.0.1/udp/1234", "udp", "127.0.0.1:1234")
156
- test("/ip4/127.0.0.1/tcp/4321", "tcp", "127.0.0.1:4321")
157
- test("/ip4/127.0.0.1/udp/1234/utp", "utp", "127.0.0.1:1234")
155
+ test("/ip4/127.0.0.1/udp/1234", "udp4", "127.0.0.1:1234")
156
+ test("/ip4/127.0.0.1/tcp/4321", "tcp4", "127.0.0.1:4321")
157
+ test("/ip4/127.0.0.1/udp/1234/utp", "utp4", "127.0.0.1:1234")
158
+ test("/ip6/::1/udp/1234", "udp6", "[::1]:1234")
159
+ test("/ip6/::1/tcp/4321", "tcp6", "[::1]:4321")
160
+ test("/ip6/::1/udp/1234/utp", "utp6", "[::1]:1234")
161
}
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/ip.go
+9
-1
@@ -57,7 +57,7 @@ func IsIPLoopback(m ma.Multiaddr) bool {
57
b := m.Bytes()
58
59
// /ip4/127 prefix (_entire_ /8 is loopback...)
60
- if bytes.HasPrefix(b, []byte{4, 127}) {
60
+ if bytes.HasPrefix(b, []byte{ma.P_IP4, 127}) {
61
return true
62
}
63
@@ -69,6 +69,14 @@ func IsIPLoopback(m ma.Multiaddr) bool {
69
return false
70
}
71
72
+// IP6 Link Local addresses are non routable. The prefix is technically
73
+// fe80::/10, but we test fe80::/16 for simplicity (no need to mask).
74
+// So far, no hardware interfaces exist long enough to use those 2 bits.
75
+// Send a PR if there is.
76
+func IsIP6LinkLocal(m ma.Multiaddr) bool {
77
+ return bytes.HasPrefix(m.Bytes(), []byte{ma.P_IP6, 0xfe, 0x80})
78
+}
79
+
80
// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address
81
// This means either /ip4/0.0.0.0 or /ip6/::
82
func IsIPUnspecified(m ma.Multiaddr) bool {
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net.go
+37
-2
@@ -106,12 +106,12 @@ func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {
106
// ok, Dial!
107
var nconn net.Conn
108
switch rnet {
109
- case "tcp":
109
+ case "tcp", "tcp4", "tcp6":
110
nconn, err = d.Dialer.Dial(rnet, rnaddr)
111
if err != nil {
112
return nil, err
113
}
114
- case "utp":
114
+ case "udp", "udp4", "udp6":
115
return nil, fmt.Errorf("utp is currently broken")
116
117
// // construct utp dialer, with options on our net.Dialer
@@ -236,6 +236,14 @@ func Listen(laddr ma.Multiaddr) (Listener, error) {
236
return nil, err
237
}
238
239
+ // we need to fetch the new multiaddr from the listener, as it
240
+ // may have resolved to some other value.
241
+ nladdr, err := FromNetAddr(nl.Addr())
242
+ if err != nil {
243
+ return nil, err
244
+ }
245
+ laddr = nladdr
246
+
247
return &maListener{
248
Listener: nl,
249
laddr: laddr,
@@ -258,3 +266,30 @@ func InterfaceMultiaddrs() ([]ma.Multiaddr, error) {
266
}
267
return maddrs, nil
268
}
269
+
270
+// AddrMatch returns the Multiaddrs that match the protocol stack on addr
271
+func AddrMatch(match ma.Multiaddr, addrs []ma.Multiaddr) []ma.Multiaddr {
272
+
273
+ // we should match transports entirely.
274
+ p1s := match.Protocols()
275
+
276
+ out := make([]ma.Multiaddr, 0, len(addrs))
277
+ for _, a := range addrs {
278
+ p2s := a.Protocols()
279
+ if len(p1s) != len(p2s) {
280
+ continue
281
+ }
282
+
283
+ match := true
284
+ for i, p2 := range p2s {
285
+ if p1s[i].Code != p2.Code {
286
+ match = false
287
+ break
288
+ }
289
+ }
290
+ if match {
291
+ out = append(out, a)
292
+ }
293
+ }
294
+ return out
295
+}
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net_test.go
+108
-6
@@ -2,6 +2,7 @@ package manet
2
3
import (
4
"bytes"
5
+ "fmt"
6
"net"
7
"sync"
8
"testing"
@@ -140,7 +141,10 @@ func TestListen(t *testing.T) {
141
142
func TestListenAddrs(t *testing.T) {
143
143
- test := func(addr string, succeed bool) {
144
+ test := func(addr, resaddr string, succeed bool) {
145
+ if resaddr == "" {
146
+ resaddr = addr
147
+ }
148
149
maddr := newMultiaddr(t, addr)
150
l, err := Listen(maddr)
@@ -151,10 +155,13 @@ func TestListenAddrs(t *testing.T) {
155
return
156
}
157
if succeed && err != nil {
154
- t.Fatal("failed to listen", addr, err)
158
+ t.Error("failed to listen", addr, err)
159
}
160
if l == nil {
157
- t.Fatal("failed to listen", addr, succeed, err)
161
+ t.Error("failed to listen", addr, succeed, err)
162
+ }
163
+ if l.Multiaddr().String() != resaddr {
164
+ t.Error("listen addr did not resolve properly", l.Multiaddr().String(), resaddr, succeed, err)
165
}
166
167
if err = l.Close(); err != nil {
@@ -162,9 +169,18 @@ func TestListenAddrs(t *testing.T) {
169
}
170
}
171
165
- test("/ip4/127.0.0.1/tcp/4324", true)
166
- test("/ip4/127.0.0.1/udp/4325", false)
167
- test("/ip4/127.0.0.1/udp/4326/udt", false)
172
+ test("/ip4/127.0.0.1/tcp/4324", "", true)
173
+ test("/ip4/127.0.0.1/udp/4325", "", false)
174
+ test("/ip4/127.0.0.1/udp/4326/udt", "", false)
175
+ test("/ip4/0.0.0.0/tcp/4324", "", true)
176
+ test("/ip4/0.0.0.0/udp/4325", "", false)
177
+ test("/ip4/0.0.0.0/udp/4326/udt", "", false)
178
+ test("/ip6/::1/tcp/4324", "", true)
179
+ test("/ip6/::1/udp/4325", "", false)
180
+ test("/ip6/::1/udp/4326/udt", "", false)
181
+ test("/ip6/::/tcp/4324", "", true)
182
+ test("/ip6/::/udp/4325", "", false)
183
+ test("/ip6/::/udp/4326/udt", "", false)
184
// test("/ip4/127.0.0.1/udp/4326/utp", true)
185
}
186
@@ -334,3 +350,89 @@ func TestIPUnspecified(t *testing.T) {
350
t.Error("IsIPUnspecified failed (IP6Unspecified)")
351
}
352
}
353
+
354
+func TestIP6LinkLocal(t *testing.T) {
355
+ if !IsIP6LinkLocal(IP6LinkLocalLoopback) {
356
+ t.Error("IsIP6LinkLocal failed (IP6LinkLocalLoopback)")
357
+ }
358
+
359
+ for a := 0; a < 65536; a++ {
360
+ isLinkLocal := (a == 0xfe80)
361
+ m := newMultiaddr(t, fmt.Sprintf("/ip6/%x::1", a))
362
+ if IsIP6LinkLocal(m) != isLinkLocal {
363
+ t.Error("IsIP6LinkLocal failed (%s != %v)", m, isLinkLocal)
364
+ }
365
+ }
366
+}
367
+
368
+func TestAddrMatch(t *testing.T) {
369
+
370
+ test := func(m ma.Multiaddr, input, expect []ma.Multiaddr) {
371
+ actual := AddrMatch(m, input)
372
+ testSliceEqual(t, expect, actual)
373
+ }
374
+
375
+ a := []ma.Multiaddr{
376
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
377
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"),
378
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
379
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
380
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
381
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
382
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
383
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
384
+ newMultiaddr(t, "/ip6/::1/tcp/1234"),
385
+ newMultiaddr(t, "/ip6/::1/tcp/2345"),
386
+ newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
387
+ newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
388
+ newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
389
+ newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
390
+ newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
391
+ newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
392
+ }
393
+
394
+ test(a[0], a, []ma.Multiaddr{
395
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
396
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"),
397
+ })
398
+ test(a[2], a, []ma.Multiaddr{
399
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
400
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
401
+ })
402
+ test(a[4], a, []ma.Multiaddr{
403
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
404
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
405
+ })
406
+ test(a[6], a, []ma.Multiaddr{
407
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
408
+ newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
409
+ })
410
+ test(a[8], a, []ma.Multiaddr{
411
+ newMultiaddr(t, "/ip6/::1/tcp/1234"),
412
+ newMultiaddr(t, "/ip6/::1/tcp/2345"),
413
+ })
414
+ test(a[10], a, []ma.Multiaddr{
415
+ newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
416
+ newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
417
+ })
418
+ test(a[12], a, []ma.Multiaddr{
419
+ newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
420
+ newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
421
+ })
422
+ test(a[14], a, []ma.Multiaddr{
423
+ newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
424
+ newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
425
+ })
426
+
427
+}
428
+
429
+func testSliceEqual(t *testing.T, a, b []ma.Multiaddr) {
430
+ if len(a) != len(b) {
431
+ t.Error("differ", a, b)
432
+ }
433
+ for i, addrA := range a {
434
+ if !addrA.Equal(b[i]) {
435
+ t.Error("differ", a, b)
436
+ }
437
+ }
438
+}