@cryptotaxi247 / kubo / commits / b36ca66f7

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 +}