mirror of
https://github.com/ipfs/kubo.git
synced 2025-07-01 19:24:14 +08:00
Merge pull request #544 from jbenet/fix/linklocal
dont send ip6 link local addrs
This commit is contained in:
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -135,7 +135,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/jbenet/go-multiaddr-net",
|
"ImportPath": "github.com/jbenet/go-multiaddr-net",
|
||||||
"Rev": "2b8f35303d2855c79f9f3f9b3584338a1ff7edbd"
|
"Rev": "04044c2289504304472715d827a8f564fa3759a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/jbenet/go-multihash",
|
"ImportPath": "github.com/jbenet/go-multihash",
|
||||||
|
11
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/.travis.yml
generated
vendored
Normal file
11
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.3
|
||||||
|
- release
|
||||||
|
- tip
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make test
|
||||||
|
|
||||||
|
env: TEST_VERBOSE=1
|
3
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/Makefile
generated
vendored
3
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/Makefile
generated
vendored
@ -12,5 +12,8 @@ vendor: godep
|
|||||||
install: dep
|
install: dep
|
||||||
cd multiaddr && go install
|
cd multiaddr && go install
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test ./...
|
||||||
|
|
||||||
dep:
|
dep:
|
||||||
cd multiaddr && go get ./...
|
cd multiaddr && go get ./...
|
||||||
|
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert.go
generated
vendored
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert.go
generated
vendored
@ -112,13 +112,13 @@ func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch network {
|
switch network {
|
||||||
case "tcp":
|
case "tcp", "tcp4", "tcp6":
|
||||||
return net.ResolveTCPAddr(network, host)
|
return net.ResolveTCPAddr(network, host)
|
||||||
case "udp":
|
case "udp", "udp4", "udp6":
|
||||||
return net.ResolveUDPAddr(network, host)
|
return net.ResolveUDPAddr(network, host)
|
||||||
case "utp":
|
case "utp", "utp4", "utp6":
|
||||||
return utp.ResolveUTPAddr(network, host)
|
return utp.ResolveUTPAddr(network, host)
|
||||||
case "ip":
|
case "ip", "ip4", "ip6":
|
||||||
return net.ResolveIPAddr(network, host)
|
return net.ResolveIPAddr(network, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +158,10 @@ func DialArgs(m ma.Multiaddr) (string, string, error) {
|
|||||||
var host string
|
var host string
|
||||||
switch parts[0] {
|
switch parts[0] {
|
||||||
case "ip4":
|
case "ip4":
|
||||||
|
network = network + "4"
|
||||||
host = strings.Join([]string{parts[1], parts[3]}, ":")
|
host = strings.Join([]string{parts[1], parts[3]}, ":")
|
||||||
case "ip6":
|
case "ip6":
|
||||||
|
network = network + "6"
|
||||||
host = fmt.Sprintf("[%s]:%s", parts[1], parts[3])
|
host = fmt.Sprintf("[%s]:%s", parts[1], parts[3])
|
||||||
}
|
}
|
||||||
return network, host, nil
|
return network, host, nil
|
||||||
|
9
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert_test.go
generated
vendored
9
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/convert_test.go
generated
vendored
@ -152,7 +152,10 @@ func TestDialArgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("/ip4/127.0.0.1/udp/1234", "udp", "127.0.0.1:1234")
|
test("/ip4/127.0.0.1/udp/1234", "udp4", "127.0.0.1:1234")
|
||||||
test("/ip4/127.0.0.1/tcp/4321", "tcp", "127.0.0.1:4321")
|
test("/ip4/127.0.0.1/tcp/4321", "tcp4", "127.0.0.1:4321")
|
||||||
test("/ip4/127.0.0.1/udp/1234/utp", "utp", "127.0.0.1:1234")
|
test("/ip4/127.0.0.1/udp/1234/utp", "utp4", "127.0.0.1:1234")
|
||||||
|
test("/ip6/::1/udp/1234", "udp6", "[::1]:1234")
|
||||||
|
test("/ip6/::1/tcp/4321", "tcp6", "[::1]:4321")
|
||||||
|
test("/ip6/::1/udp/1234/utp", "utp6", "[::1]:1234")
|
||||||
}
|
}
|
||||||
|
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/ip.go
generated
vendored
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/ip.go
generated
vendored
@ -57,7 +57,7 @@ func IsIPLoopback(m ma.Multiaddr) bool {
|
|||||||
b := m.Bytes()
|
b := m.Bytes()
|
||||||
|
|
||||||
// /ip4/127 prefix (_entire_ /8 is loopback...)
|
// /ip4/127 prefix (_entire_ /8 is loopback...)
|
||||||
if bytes.HasPrefix(b, []byte{4, 127}) {
|
if bytes.HasPrefix(b, []byte{ma.P_IP4, 127}) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +69,14 @@ func IsIPLoopback(m ma.Multiaddr) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IP6 Link Local addresses are non routable. The prefix is technically
|
||||||
|
// fe80::/10, but we test fe80::/16 for simplicity (no need to mask).
|
||||||
|
// So far, no hardware interfaces exist long enough to use those 2 bits.
|
||||||
|
// Send a PR if there is.
|
||||||
|
func IsIP6LinkLocal(m ma.Multiaddr) bool {
|
||||||
|
return bytes.HasPrefix(m.Bytes(), []byte{ma.P_IP6, 0xfe, 0x80})
|
||||||
|
}
|
||||||
|
|
||||||
// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address
|
// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address
|
||||||
// This means either /ip4/0.0.0.0 or /ip6/::
|
// This means either /ip4/0.0.0.0 or /ip6/::
|
||||||
func IsIPUnspecified(m ma.Multiaddr) bool {
|
func IsIPUnspecified(m ma.Multiaddr) bool {
|
||||||
|
39
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net.go
generated
vendored
39
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net.go
generated
vendored
@ -106,12 +106,12 @@ func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {
|
|||||||
// ok, Dial!
|
// ok, Dial!
|
||||||
var nconn net.Conn
|
var nconn net.Conn
|
||||||
switch rnet {
|
switch rnet {
|
||||||
case "tcp":
|
case "tcp", "tcp4", "tcp6":
|
||||||
nconn, err = d.Dialer.Dial(rnet, rnaddr)
|
nconn, err = d.Dialer.Dial(rnet, rnaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case "utp":
|
case "udp", "udp4", "udp6":
|
||||||
return nil, fmt.Errorf("utp is currently broken")
|
return nil, fmt.Errorf("utp is currently broken")
|
||||||
|
|
||||||
// // construct utp dialer, with options on our net.Dialer
|
// // construct utp dialer, with options on our net.Dialer
|
||||||
@ -236,6 +236,14 @@ func Listen(laddr ma.Multiaddr) (Listener, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to fetch the new multiaddr from the listener, as it
|
||||||
|
// may have resolved to some other value.
|
||||||
|
nladdr, err := FromNetAddr(nl.Addr())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
laddr = nladdr
|
||||||
|
|
||||||
return &maListener{
|
return &maListener{
|
||||||
Listener: nl,
|
Listener: nl,
|
||||||
laddr: laddr,
|
laddr: laddr,
|
||||||
@ -258,3 +266,30 @@ func InterfaceMultiaddrs() ([]ma.Multiaddr, error) {
|
|||||||
}
|
}
|
||||||
return maddrs, nil
|
return maddrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddrMatch returns the Multiaddrs that match the protocol stack on addr
|
||||||
|
func AddrMatch(match ma.Multiaddr, addrs []ma.Multiaddr) []ma.Multiaddr {
|
||||||
|
|
||||||
|
// we should match transports entirely.
|
||||||
|
p1s := match.Protocols()
|
||||||
|
|
||||||
|
out := make([]ma.Multiaddr, 0, len(addrs))
|
||||||
|
for _, a := range addrs {
|
||||||
|
p2s := a.Protocols()
|
||||||
|
if len(p1s) != len(p2s) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
match := true
|
||||||
|
for i, p2 := range p2s {
|
||||||
|
if p1s[i].Code != p2.Code {
|
||||||
|
match = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if match {
|
||||||
|
out = append(out, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
114
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net_test.go
generated
vendored
114
Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/net_test.go
generated
vendored
@ -2,6 +2,7 @@ package manet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@ -140,7 +141,10 @@ func TestListen(t *testing.T) {
|
|||||||
|
|
||||||
func TestListenAddrs(t *testing.T) {
|
func TestListenAddrs(t *testing.T) {
|
||||||
|
|
||||||
test := func(addr string, succeed bool) {
|
test := func(addr, resaddr string, succeed bool) {
|
||||||
|
if resaddr == "" {
|
||||||
|
resaddr = addr
|
||||||
|
}
|
||||||
|
|
||||||
maddr := newMultiaddr(t, addr)
|
maddr := newMultiaddr(t, addr)
|
||||||
l, err := Listen(maddr)
|
l, err := Listen(maddr)
|
||||||
@ -151,10 +155,13 @@ func TestListenAddrs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if succeed && err != nil {
|
if succeed && err != nil {
|
||||||
t.Fatal("failed to listen", addr, err)
|
t.Error("failed to listen", addr, err)
|
||||||
}
|
}
|
||||||
if l == nil {
|
if l == nil {
|
||||||
t.Fatal("failed to listen", addr, succeed, err)
|
t.Error("failed to listen", addr, succeed, err)
|
||||||
|
}
|
||||||
|
if l.Multiaddr().String() != resaddr {
|
||||||
|
t.Error("listen addr did not resolve properly", l.Multiaddr().String(), resaddr, succeed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = l.Close(); err != nil {
|
if err = l.Close(); err != nil {
|
||||||
@ -162,9 +169,18 @@ func TestListenAddrs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("/ip4/127.0.0.1/tcp/4324", true)
|
test("/ip4/127.0.0.1/tcp/4324", "", true)
|
||||||
test("/ip4/127.0.0.1/udp/4325", false)
|
test("/ip4/127.0.0.1/udp/4325", "", false)
|
||||||
test("/ip4/127.0.0.1/udp/4326/udt", false)
|
test("/ip4/127.0.0.1/udp/4326/udt", "", false)
|
||||||
|
test("/ip4/0.0.0.0/tcp/4324", "", true)
|
||||||
|
test("/ip4/0.0.0.0/udp/4325", "", false)
|
||||||
|
test("/ip4/0.0.0.0/udp/4326/udt", "", false)
|
||||||
|
test("/ip6/::1/tcp/4324", "", true)
|
||||||
|
test("/ip6/::1/udp/4325", "", false)
|
||||||
|
test("/ip6/::1/udp/4326/udt", "", false)
|
||||||
|
test("/ip6/::/tcp/4324", "", true)
|
||||||
|
test("/ip6/::/udp/4325", "", false)
|
||||||
|
test("/ip6/::/udp/4326/udt", "", false)
|
||||||
// test("/ip4/127.0.0.1/udp/4326/utp", true)
|
// test("/ip4/127.0.0.1/udp/4326/utp", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,3 +350,89 @@ func TestIPUnspecified(t *testing.T) {
|
|||||||
t.Error("IsIPUnspecified failed (IP6Unspecified)")
|
t.Error("IsIPUnspecified failed (IP6Unspecified)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIP6LinkLocal(t *testing.T) {
|
||||||
|
if !IsIP6LinkLocal(IP6LinkLocalLoopback) {
|
||||||
|
t.Error("IsIP6LinkLocal failed (IP6LinkLocalLoopback)")
|
||||||
|
}
|
||||||
|
|
||||||
|
for a := 0; a < 65536; a++ {
|
||||||
|
isLinkLocal := (a == 0xfe80)
|
||||||
|
m := newMultiaddr(t, fmt.Sprintf("/ip6/%x::1", a))
|
||||||
|
if IsIP6LinkLocal(m) != isLinkLocal {
|
||||||
|
t.Error("IsIP6LinkLocal failed (%s != %v)", m, isLinkLocal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddrMatch(t *testing.T) {
|
||||||
|
|
||||||
|
test := func(m ma.Multiaddr, input, expect []ma.Multiaddr) {
|
||||||
|
actual := AddrMatch(m, input)
|
||||||
|
testSliceEqual(t, expect, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
|
||||||
|
}
|
||||||
|
|
||||||
|
test(a[0], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"),
|
||||||
|
})
|
||||||
|
test(a[2], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"),
|
||||||
|
})
|
||||||
|
test(a[4], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"),
|
||||||
|
})
|
||||||
|
test(a[6], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"),
|
||||||
|
})
|
||||||
|
test(a[8], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/2345"),
|
||||||
|
})
|
||||||
|
test(a[10], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"),
|
||||||
|
})
|
||||||
|
test(a[12], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"),
|
||||||
|
})
|
||||||
|
test(a[14], a, []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"),
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSliceEqual(t *testing.T, a, b []ma.Multiaddr) {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
t.Error("differ", a, b)
|
||||||
|
}
|
||||||
|
for i, addrA := range a {
|
||||||
|
if !addrA.Equal(b[i]) {
|
||||||
|
t.Error("differ", a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -117,7 +117,7 @@ func connect(ctx context.Context, ps peer.Peerstore, r *dht.IpfsDHT, peers []pee
|
|||||||
err := r.Connect(ctx, p.ID)
|
err := r.Connect(ctx, p.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Event(ctx, "bootstrapFailed", p.ID)
|
log.Event(ctx, "bootstrapFailed", p.ID)
|
||||||
log.Criticalf("failed to bootstrap with %v", p.ID)
|
log.Criticalf("failed to bootstrap with %v: %s", p.ID, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Event(ctx, "bootstrapSuccess", p.ID)
|
log.Event(ctx, "bootstrapSuccess", p.ID)
|
||||||
|
13
core/core.go
13
core/core.go
@ -24,6 +24,7 @@ import (
|
|||||||
p2phost "github.com/jbenet/go-ipfs/p2p/host"
|
p2phost "github.com/jbenet/go-ipfs/p2p/host"
|
||||||
p2pbhost "github.com/jbenet/go-ipfs/p2p/host/basic"
|
p2pbhost "github.com/jbenet/go-ipfs/p2p/host/basic"
|
||||||
swarm "github.com/jbenet/go-ipfs/p2p/net/swarm"
|
swarm "github.com/jbenet/go-ipfs/p2p/net/swarm"
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
||||||
path "github.com/jbenet/go-ipfs/path"
|
path "github.com/jbenet/go-ipfs/path"
|
||||||
pin "github.com/jbenet/go-ipfs/pin"
|
pin "github.com/jbenet/go-ipfs/pin"
|
||||||
@ -352,11 +353,18 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
|
|||||||
// isolates the complex initialization steps
|
// isolates the complex initialization steps
|
||||||
func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *config.Config, id peer.ID, ps peer.Peerstore) (p2phost.Host, error) {
|
func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *config.Config, id peer.ID, ps peer.Peerstore) (p2phost.Host, error) {
|
||||||
listenAddrs, err := listenAddresses(cfg)
|
listenAddrs, err := listenAddresses(cfg)
|
||||||
// make sure we dont error out if our config includes some addresses we cant use.
|
|
||||||
filteredAddrs := swarm.FilterAddrs(listenAddrs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, debugerror.Wrap(err)
|
return nil, debugerror.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure we error out if our config does not have addresses we can use
|
||||||
|
log.Debugf("Config.Addresses.Swarm:%s", listenAddrs)
|
||||||
|
filteredAddrs := addrutil.FilterAddrs(listenAddrs)
|
||||||
|
log.Debugf("Config.Addresses.Swarm:%s (filtered)", listenAddrs)
|
||||||
|
if len(filteredAddrs) < 1 {
|
||||||
|
return nil, debugerror.Errorf("addresses in config not usable: %s", listenAddrs)
|
||||||
|
}
|
||||||
|
|
||||||
network, err := swarm.NewNetwork(ctx, filteredAddrs, id, ps)
|
network, err := swarm.NewNetwork(ctx, filteredAddrs, id, ps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, debugerror.Wrap(err)
|
return nil, debugerror.Wrap(err)
|
||||||
@ -371,6 +379,7 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, debugerror.Wrap(err)
|
return nil, debugerror.Wrap(err)
|
||||||
}
|
}
|
||||||
|
log.Info("Swarm listening at: %s", addrs)
|
||||||
ps.AddAddresses(id, addrs)
|
ps.AddAddresses(id, addrs)
|
||||||
return peerhost, nil
|
return peerhost, nil
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func (d *Dialer) String() string {
|
|||||||
// Example: d.DialAddr(ctx, peer.Addresses()[0], peer)
|
// Example: d.DialAddr(ctx, peer.Addresses()[0], peer)
|
||||||
func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (Conn, error) {
|
func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (Conn, error) {
|
||||||
|
|
||||||
network, _, err := manet.DialArgs(raddr)
|
_, _, err := manet.DialArgs(raddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -31,17 +31,20 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (
|
|||||||
return nil, debugerror.Errorf("Attempted to connect to zero address: %s", raddr)
|
return nil, debugerror.Errorf("Attempted to connect to zero address: %s", raddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
var laddr ma.Multiaddr
|
|
||||||
if len(d.LocalAddrs) > 0 {
|
if len(d.LocalAddrs) > 0 {
|
||||||
// laddr := MultiaddrNetMatch(raddr, d.LocalAddrs)
|
laddrs := manet.AddrMatch(raddr, d.LocalAddrs)
|
||||||
laddr = NetAddress(network, d.LocalAddrs)
|
if len(laddrs) < 1 {
|
||||||
if laddr == nil {
|
return nil, debugerror.Errorf("No local address matches %s %s", raddr, d.LocalAddrs)
|
||||||
return nil, debugerror.Errorf("No local address for network %s", network)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: try to get reusing addr/ports to work.
|
// TODO pick with a good heuristic
|
||||||
// d.Dialer.LocalAddr = laddr
|
// we use a random one for now to prevent bad addresses from making nodes unreachable
|
||||||
|
// with a random selection, multiple tries may work.
|
||||||
|
// laddr := laddrs[rand.Intn(len(laddrs))]
|
||||||
|
|
||||||
|
// TODO: try to get reusing addr/ports to work.
|
||||||
|
// d.Dialer.LocalAddr = laddr
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("%s dialing %s %s", d.LocalPeer, remote, raddr)
|
log.Debugf("%s dialing %s %s", d.LocalPeer, remote, raddr)
|
||||||
maconn, err := d.Dialer.Dial(raddr)
|
maconn, err := d.Dialer.Dial(raddr)
|
||||||
@ -116,15 +119,3 @@ func MultiaddrNetMatch(tgt ma.Multiaddr, srcs []ma.Multiaddr) ma.Multiaddr {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetAddress returns the first Multiaddr found for a given network.
|
|
||||||
func NetAddress(n string, addrs []ma.Multiaddr) ma.Multiaddr {
|
|
||||||
for _, a := range addrs {
|
|
||||||
for _, p := range a.Protocols() {
|
|
||||||
if p.Name == n {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -102,11 +102,7 @@ func (l *listener) Addr() net.Addr {
|
|||||||
// If there is an error converting from net.Addr to ma.Multiaddr,
|
// If there is an error converting from net.Addr to ma.Multiaddr,
|
||||||
// the return value will be nil.
|
// the return value will be nil.
|
||||||
func (l *listener) Multiaddr() ma.Multiaddr {
|
func (l *listener) Multiaddr() ma.Multiaddr {
|
||||||
maddr, err := manet.FromNetAddr(l.Addr())
|
return l.Listener.Multiaddr()
|
||||||
if err != nil {
|
|
||||||
return nil // error
|
|
||||||
}
|
|
||||||
return maddr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalPeer is the identity of the local Peer.
|
// LocalPeer is the identity of the local Peer.
|
||||||
@ -140,7 +136,7 @@ func Listen(ctx context.Context, addr ma.Multiaddr, local peer.ID, sk ic.PrivKey
|
|||||||
}
|
}
|
||||||
l.cg.SetTeardown(l.teardown)
|
l.cg.SetTeardown(l.teardown)
|
||||||
|
|
||||||
log.Infof("swarm listening on %s", l.Multiaddr())
|
log.Debugf("Conn Listener on %s", l.Multiaddr())
|
||||||
log.Event(ctx, "swarmListen", l)
|
log.Event(ctx, "swarmListen", l)
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
@ -1,193 +0,0 @@
|
|||||||
package swarm
|
|
||||||
|
|
||||||
import (
|
|
||||||
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
|
||||||
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
|
|
||||||
|
|
||||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
|
||||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
|
||||||
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SupportedTransportStrings is the list of supported transports for the swarm.
|
|
||||||
// These are strings of encapsulated multiaddr protocols. E.g.:
|
|
||||||
// /ip4/tcp
|
|
||||||
var SupportedTransportStrings = []string{
|
|
||||||
"/ip4/tcp",
|
|
||||||
"/ip6/tcp",
|
|
||||||
// "/ip4/udp/utp", disabled because the lib is broken
|
|
||||||
// "/ip6/udp/utp", disabled because the lib is broken
|
|
||||||
// "/ip4/udp/udt", disabled because the lib doesnt work on arm
|
|
||||||
// "/ip6/udp/udt", disabled because the lib doesnt work on arm
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportedTransportProtocols is the list of supported transports for the swarm.
|
|
||||||
// These are []ma.Protocol lists. Populated at runtime from SupportedTransportStrings
|
|
||||||
var SupportedTransportProtocols = [][]ma.Protocol{}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// initialize SupportedTransportProtocols
|
|
||||||
transports := make([][]ma.Protocol, len(SupportedTransportStrings))
|
|
||||||
for _, s := range SupportedTransportStrings {
|
|
||||||
t, err := ma.ProtocolsWithString(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err) // important to fix this in the codebase
|
|
||||||
}
|
|
||||||
transports = append(transports, t)
|
|
||||||
}
|
|
||||||
SupportedTransportProtocols = transports
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterAddrs is a filter that removes certain addresses
|
|
||||||
// from a list. the addresses removed are those known NOT
|
|
||||||
// to work with swarm. Namely, addresses with UTP.
|
|
||||||
func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
|
|
||||||
b := make([]ma.Multiaddr, 0, len(a))
|
|
||||||
for _, addr := range a {
|
|
||||||
if AddrUsable(addr) {
|
|
||||||
b = append(b, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddrUsable returns whether the swarm can use this addr.
|
|
||||||
func AddrUsable(a ma.Multiaddr) bool {
|
|
||||||
// test the address protocol list is in SupportedTransportProtocols
|
|
||||||
|
|
||||||
matches := func(a, b []ma.Protocol) bool {
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range a {
|
|
||||||
if a[i].Code != b[i].Code {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
transport := a.Protocols()
|
|
||||||
for _, supported := range SupportedTransportProtocols {
|
|
||||||
if matches(supported, transport) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListenAddresses returns a list of addresses at which this swarm listens.
|
|
||||||
func (s *Swarm) ListenAddresses() []ma.Multiaddr {
|
|
||||||
listeners := s.swarm.Listeners()
|
|
||||||
addrs := make([]ma.Multiaddr, 0, len(listeners))
|
|
||||||
for _, l := range listeners {
|
|
||||||
if l2, ok := l.NetListener().(conn.Listener); ok {
|
|
||||||
addrs = append(addrs, l2.Multiaddr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addrs
|
|
||||||
}
|
|
||||||
|
|
||||||
// InterfaceListenAddresses returns a list of addresses at which this swarm
|
|
||||||
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
|
|
||||||
// use the known local interfaces.
|
|
||||||
func InterfaceListenAddresses(s *Swarm) ([]ma.Multiaddr, error) {
|
|
||||||
return resolveUnspecifiedAddresses(s.ListenAddresses())
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
|
|
||||||
// use the known local interfaces.
|
|
||||||
func resolveUnspecifiedAddresses(unspecifiedAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
|
||||||
var outputAddrs []ma.Multiaddr
|
|
||||||
|
|
||||||
// todo optimize: only fetch these if we have a "any" addr.
|
|
||||||
ifaceAddrs, err := interfaceAddresses()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, a := range unspecifiedAddrs {
|
|
||||||
|
|
||||||
// split address into its components
|
|
||||||
split := ma.Split(a)
|
|
||||||
|
|
||||||
// if first component (ip) is not unspecified, use it as is.
|
|
||||||
if !manet.IsIPUnspecified(split[0]) {
|
|
||||||
outputAddrs = append(outputAddrs, a)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// unspecified? add one address per interface.
|
|
||||||
for _, ia := range ifaceAddrs {
|
|
||||||
split[0] = ia
|
|
||||||
joined := ma.Join(split...)
|
|
||||||
outputAddrs = append(outputAddrs, joined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Event(context.TODO(), "interfaceListenAddresses", func() eventlog.Loggable {
|
|
||||||
var addrs []string
|
|
||||||
for _, addr := range outputAddrs {
|
|
||||||
addrs = append(addrs, addr.String())
|
|
||||||
}
|
|
||||||
return eventlog.Metadata{"addresses": addrs}
|
|
||||||
}())
|
|
||||||
log.Debug("InterfaceListenAddresses:", outputAddrs)
|
|
||||||
return outputAddrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// interfaceAddresses returns a list of addresses associated with local machine
|
|
||||||
func interfaceAddresses() ([]ma.Multiaddr, error) {
|
|
||||||
maddrs, err := manet.InterfaceMultiaddrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var nonLoopback []ma.Multiaddr
|
|
||||||
for _, a := range maddrs {
|
|
||||||
if !manet.IsIPLoopback(a) {
|
|
||||||
nonLoopback = append(nonLoopback, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nonLoopback, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// addrInList returns whether or not an address is part of a list.
|
|
||||||
// this is useful to check if NAT is happening (or other bugs?)
|
|
||||||
func addrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool {
|
|
||||||
for _, addr2 := range list {
|
|
||||||
if addr.Equal(addr2) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNATWarning checks if our observed addresses differ. if so,
|
|
||||||
// informs the user that certain things might not work yet
|
|
||||||
func checkNATWarning(s *Swarm, observed ma.Multiaddr, expected ma.Multiaddr) {
|
|
||||||
if observed.Equal(expected) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
listen, err := InterfaceListenAddresses(s)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error retrieving swarm.InterfaceListenAddresses: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !addrInList(observed, listen) { // probably a nat
|
|
||||||
log.Warningf(natWarning, observed, listen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const natWarning = `Remote peer observed our address to be: %s
|
|
||||||
The local addresses are: %s
|
|
||||||
Thus, connection is going through NAT, and other connections may fail.
|
|
||||||
|
|
||||||
IPFS NAT traversal is still under development. Please bug us on github or irc to fix this.
|
|
||||||
Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif
|
|
||||||
`
|
|
258
p2p/net/swarm/addr/addr.go
Normal file
258
p2p/net/swarm/addr/addr.go
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
package addrutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
|
||||||
|
|
||||||
|
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||||
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||||
|
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = eventlog.Logger("p2p/net/swarm/addr")
|
||||||
|
|
||||||
|
// SupportedTransportStrings is the list of supported transports for the swarm.
|
||||||
|
// These are strings of encapsulated multiaddr protocols. E.g.:
|
||||||
|
// /ip4/tcp
|
||||||
|
var SupportedTransportStrings = []string{
|
||||||
|
"/ip4/tcp",
|
||||||
|
"/ip6/tcp",
|
||||||
|
// "/ip4/udp/utp", disabled because the lib is broken
|
||||||
|
// "/ip6/udp/utp", disabled because the lib is broken
|
||||||
|
// "/ip4/udp/udt", disabled because the lib doesnt work on arm
|
||||||
|
// "/ip6/udp/udt", disabled because the lib doesnt work on arm
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupportedTransportProtocols is the list of supported transports for the swarm.
|
||||||
|
// These are []ma.Protocol lists. Populated at runtime from SupportedTransportStrings
|
||||||
|
var SupportedTransportProtocols = [][]ma.Protocol{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// initialize SupportedTransportProtocols
|
||||||
|
transports := make([][]ma.Protocol, len(SupportedTransportStrings))
|
||||||
|
for _, s := range SupportedTransportStrings {
|
||||||
|
t, err := ma.ProtocolsWithString(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // important to fix this in the codebase
|
||||||
|
}
|
||||||
|
transports = append(transports, t)
|
||||||
|
}
|
||||||
|
SupportedTransportProtocols = transports
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterAddrs is a filter that removes certain addresses
|
||||||
|
// from a list. the addresses removed are those known NOT
|
||||||
|
// to work with our network. Namely, addresses with UTP.
|
||||||
|
func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
|
||||||
|
b := make([]ma.Multiaddr, 0, len(a))
|
||||||
|
for _, addr := range a {
|
||||||
|
if AddrUsable(addr, false) {
|
||||||
|
b = append(b, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link
|
||||||
|
func AddrOverNonLocalIP(a ma.Multiaddr) bool {
|
||||||
|
split := ma.Split(a)
|
||||||
|
if len(split) < 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if manet.IsIP6LinkLocal(split[0]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddrUsable returns whether our network can use this addr.
|
||||||
|
// We only use the transports in SupportedTransportStrings,
|
||||||
|
// and we do not link local addresses. Loopback is ok
|
||||||
|
// as we need to be able to connect to multiple ipfs nodes
|
||||||
|
// in the same machine.
|
||||||
|
func AddrUsable(a ma.Multiaddr, partial bool) bool {
|
||||||
|
|
||||||
|
if !AddrOverNonLocalIP(a) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// test the address protocol list is in SupportedTransportProtocols
|
||||||
|
matches := func(supported, test []ma.Protocol) bool {
|
||||||
|
if len(test) > len(supported) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// when partial, it's ok if test < supported.
|
||||||
|
if !partial && len(supported) != len(test) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range test {
|
||||||
|
if supported[i].Code != test[i].Code {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
transport := a.Protocols()
|
||||||
|
for _, supported := range SupportedTransportProtocols {
|
||||||
|
if matches(supported, transport) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||||
|
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
|
||||||
|
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
|
||||||
|
func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||||
|
// split address into its components
|
||||||
|
split := ma.Split(resolve)
|
||||||
|
|
||||||
|
// if first component (ip) is not unspecified, use it as is.
|
||||||
|
if !manet.IsIPUnspecified(split[0]) {
|
||||||
|
return []ma.Multiaddr{resolve}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
|
||||||
|
for _, ia := range ifaceAddrs {
|
||||||
|
// must match the first protocol to be resolve.
|
||||||
|
if ia.Protocols()[0].Code != resolve.Protocols()[0].Code {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
split[0] = ia
|
||||||
|
joined := ma.Join(split...)
|
||||||
|
out = append(out, joined)
|
||||||
|
log.Debug("adding resolved addr:", resolve, joined, out)
|
||||||
|
}
|
||||||
|
if len(out) < 1 {
|
||||||
|
return nil, fmt.Errorf("failed to resolve: %s", resolve)
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||||
|
// use the known local interfaces.
|
||||||
|
func ResolveUnspecifiedAddresses(unspecAddrs, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||||
|
|
||||||
|
// todo optimize: only fetch these if we have a "any" addr.
|
||||||
|
if len(ifaceAddrs) < 1 {
|
||||||
|
var err error
|
||||||
|
ifaceAddrs, err = InterfaceAddresses()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// log.Debug("InterfaceAddresses:", ifaceAddrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputAddrs []ma.Multiaddr
|
||||||
|
for _, a := range unspecAddrs {
|
||||||
|
// unspecified?
|
||||||
|
resolved, err := ResolveUnspecifiedAddress(a, ifaceAddrs)
|
||||||
|
if err != nil {
|
||||||
|
continue // optimistic. if we cant resolve anything, we'll know at the bottom.
|
||||||
|
}
|
||||||
|
// log.Debug("resolved:", a, resolved)
|
||||||
|
outputAddrs = append(outputAddrs, resolved...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(outputAddrs) < 1 {
|
||||||
|
return nil, fmt.Errorf("failed to specify addrs: %s", unspecAddrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Event(context.TODO(), "interfaceListenAddresses", func() eventlog.Loggable {
|
||||||
|
var addrs []string
|
||||||
|
for _, addr := range outputAddrs {
|
||||||
|
addrs = append(addrs, addr.String())
|
||||||
|
}
|
||||||
|
return eventlog.Metadata{"addresses": addrs}
|
||||||
|
}())
|
||||||
|
|
||||||
|
log.Debug("ResolveUnspecifiedAddresses:", unspecAddrs, ifaceAddrs, outputAddrs)
|
||||||
|
return outputAddrs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceAddresses returns a list of addresses associated with local machine
|
||||||
|
// Note: we do not return link local addresses. IP loopback is ok, because we
|
||||||
|
// may be connecting to other nodes in the same machine.
|
||||||
|
func InterfaceAddresses() ([]ma.Multiaddr, error) {
|
||||||
|
maddrs, err := manet.InterfaceMultiaddrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Debug("InterfaceAddresses: from manet:", maddrs)
|
||||||
|
|
||||||
|
var out []ma.Multiaddr
|
||||||
|
for _, a := range maddrs {
|
||||||
|
if !AddrUsable(a, true) { // partial
|
||||||
|
// log.Debug("InterfaceAddresses: skipping unusable:", a)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("InterfaceAddresses: usable:", out)
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddrInList returns whether or not an address is part of a list.
|
||||||
|
// this is useful to check if NAT is happening (or other bugs?)
|
||||||
|
func AddrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool {
|
||||||
|
for _, addr2 := range list {
|
||||||
|
if addr.Equal(addr2) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddrIsShareableOnWAN returns whether the given address should be shareable on the
|
||||||
|
// wide area network (wide internet).
|
||||||
|
func AddrIsShareableOnWAN(addr ma.Multiaddr) bool {
|
||||||
|
s := ma.Split(addr)
|
||||||
|
if len(s) < 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
a := s[0]
|
||||||
|
if manet.IsIPLoopback(a) || manet.IsIP6LinkLocal(a) || manet.IsIPUnspecified(a) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return manet.IsThinWaist(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WANShareableAddrs filters addresses based on whether they're shareable on WAN
|
||||||
|
func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr {
|
||||||
|
out := make([]ma.Multiaddr, 0, len(inp))
|
||||||
|
for _, a := range inp {
|
||||||
|
if AddrIsShareableOnWAN(a) {
|
||||||
|
out = append(out, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckNATWarning checks if our observed addresses differ. if so,
|
||||||
|
// informs the user that certain things might not work yet
|
||||||
|
func CheckNATWarning(observed, expected ma.Multiaddr, listen []ma.Multiaddr) {
|
||||||
|
if observed.Equal(expected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !AddrInList(observed, listen) { // probably a nat
|
||||||
|
log.Warningf(natWarning, observed, listen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const natWarning = `Remote peer observed our address to be: %s
|
||||||
|
The local addresses are: %s
|
||||||
|
Thus, connection is going through NAT, and other connections may fail.
|
||||||
|
|
||||||
|
IPFS NAT traversal is still under development. Please bug us on github or irc to fix this.
|
||||||
|
Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif
|
||||||
|
`
|
198
p2p/net/swarm/addr/addr_test.go
Normal file
198
p2p/net/swarm/addr/addr_test.go
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
package addrutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||||
|
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newMultiaddr(t *testing.T, s string) ma.Multiaddr {
|
||||||
|
maddr, err := ma.NewMultiaddr(s)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return maddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterAddrs(t *testing.T) {
|
||||||
|
|
||||||
|
bad := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/udp/1234"), // unreliable
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
|
||||||
|
newMultiaddr(t, "/ip6/fe80::1/tcp/1234"), // link local
|
||||||
|
newMultiaddr(t, "/ip6/fe80::100/tcp/1234"), // link local
|
||||||
|
}
|
||||||
|
|
||||||
|
good := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234"),
|
||||||
|
}
|
||||||
|
|
||||||
|
goodAndBad := append(good, bad...)
|
||||||
|
|
||||||
|
// test filters
|
||||||
|
|
||||||
|
for _, a := range bad {
|
||||||
|
if AddrUsable(a, false) {
|
||||||
|
t.Errorf("addr %s should be unusable", a)
|
||||||
|
}
|
||||||
|
if AddrUsable(a, true) {
|
||||||
|
t.Errorf("addr %s should be unusable", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range good {
|
||||||
|
if !AddrUsable(a, false) {
|
||||||
|
t.Errorf("addr %s should be usable", a)
|
||||||
|
}
|
||||||
|
if !AddrUsable(a, true) {
|
||||||
|
t.Errorf("addr %s should be usable", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{})
|
||||||
|
subtestAddrsEqual(t, FilterAddrs(good), good)
|
||||||
|
subtestAddrsEqual(t, FilterAddrs(goodAndBad), good)
|
||||||
|
}
|
||||||
|
|
||||||
|
func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
t.Error(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
in := func(addr ma.Multiaddr, l []ma.Multiaddr) bool {
|
||||||
|
for _, addr2 := range l {
|
||||||
|
if addr.Equal(addr2) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, aa := range a {
|
||||||
|
if !in(aa, b) {
|
||||||
|
t.Errorf("%s not in %s", aa, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInterfaceAddrs(t *testing.T) {
|
||||||
|
addrs, err := InterfaceAddresses()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(addrs) < 1 {
|
||||||
|
t.Error("no addresses")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range addrs {
|
||||||
|
if manet.IsIP6LinkLocal(a) {
|
||||||
|
t.Error("should not return ip link local addresses", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(addrs) < 1 {
|
||||||
|
t.Error("no good interface addrs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolvingAddrs(t *testing.T) {
|
||||||
|
|
||||||
|
unspec := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::100/tcp/1234"),
|
||||||
|
}
|
||||||
|
|
||||||
|
iface := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/127.0.0.1"),
|
||||||
|
newMultiaddr(t, "/ip4/10.20.30.40"),
|
||||||
|
newMultiaddr(t, "/ip6/::1"),
|
||||||
|
newMultiaddr(t, "/ip6/::f"),
|
||||||
|
}
|
||||||
|
|
||||||
|
spec := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/10.20.30.40/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::f/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::100/tcp/1234"),
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := ResolveUnspecifiedAddresses(unspec, iface)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, a := range actual {
|
||||||
|
if !a.Equal(spec[i]) {
|
||||||
|
t.Error(a, " != ", spec[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip4u := []ma.Multiaddr{newMultiaddr(t, "/ip4/0.0.0.0")}
|
||||||
|
ip4i := []ma.Multiaddr{newMultiaddr(t, "/ip4/1.2.3.4")}
|
||||||
|
|
||||||
|
ip6u := []ma.Multiaddr{newMultiaddr(t, "/ip6/::")}
|
||||||
|
ip6i := []ma.Multiaddr{newMultiaddr(t, "/ip6/::1")}
|
||||||
|
|
||||||
|
if _, err := ResolveUnspecifiedAddress(ip4u[0], ip6i); err == nil {
|
||||||
|
t.Fatal("should have failed")
|
||||||
|
}
|
||||||
|
if _, err := ResolveUnspecifiedAddress(ip6u[0], ip4i); err == nil {
|
||||||
|
t.Fatal("should have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ResolveUnspecifiedAddresses(ip6u, ip4i); err == nil {
|
||||||
|
t.Fatal("should have failed")
|
||||||
|
}
|
||||||
|
if _, err := ResolveUnspecifiedAddresses(ip4u, ip6i); err == nil {
|
||||||
|
t.Fatal("should have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWANShareable(t *testing.T) {
|
||||||
|
|
||||||
|
wanok := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/abcd::1/tcp/1234"),
|
||||||
|
}
|
||||||
|
|
||||||
|
wanbad := []ma.Multiaddr{
|
||||||
|
newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/::/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/fe80::1/tcp/1234"),
|
||||||
|
newMultiaddr(t, "/ip6/fe80::/tcp/1234"),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range wanok {
|
||||||
|
if !AddrIsShareableOnWAN(a) {
|
||||||
|
t.Error("should be true", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range wanbad {
|
||||||
|
if AddrIsShareableOnWAN(a) {
|
||||||
|
t.Error("should be false", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wanok2 := WANShareableAddrs(wanok)
|
||||||
|
if len(wanok) != len(wanok2) {
|
||||||
|
t.Error("should be the same")
|
||||||
|
}
|
||||||
|
|
||||||
|
wanbad2 := WANShareableAddrs(wanbad)
|
||||||
|
if len(wanbad2) != 0 {
|
||||||
|
t.Error("should be zero")
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,10 @@
|
|||||||
package swarm
|
package swarm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
inet "github.com/jbenet/go-ipfs/p2p/net"
|
inet "github.com/jbenet/go-ipfs/p2p/net"
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
||||||
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
|
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
|
||||||
|
|
||||||
@ -37,6 +40,14 @@ type Swarm struct {
|
|||||||
func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
|
func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
|
||||||
local peer.ID, peers peer.Peerstore) (*Swarm, error) {
|
local peer.ID, peers peer.Peerstore) (*Swarm, error) {
|
||||||
|
|
||||||
|
if len(listenAddrs) > 0 {
|
||||||
|
filtered := addrutil.FilterAddrs(listenAddrs)
|
||||||
|
if len(filtered) < 1 {
|
||||||
|
return nil, fmt.Errorf("swarm cannot use any addr in: %s", listenAddrs)
|
||||||
|
}
|
||||||
|
listenAddrs = filtered
|
||||||
|
}
|
||||||
|
|
||||||
s := &Swarm{
|
s := &Swarm{
|
||||||
swarm: ps.NewSwarm(PSTransport),
|
swarm: ps.NewSwarm(PSTransport),
|
||||||
local: local,
|
local: local,
|
||||||
|
39
p2p/net/swarm/swarm_addr.go
Normal file
39
p2p/net/swarm/swarm_addr.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
|
|
||||||
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListenAddresses returns a list of addresses at which this swarm listens.
|
||||||
|
func (s *Swarm) ListenAddresses() []ma.Multiaddr {
|
||||||
|
listeners := s.swarm.Listeners()
|
||||||
|
addrs := make([]ma.Multiaddr, 0, len(listeners))
|
||||||
|
for _, l := range listeners {
|
||||||
|
if l2, ok := l.NetListener().(conn.Listener); ok {
|
||||||
|
addrs = append(addrs, l2.Multiaddr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addrs
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceListenAddresses returns a list of addresses at which this swarm
|
||||||
|
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||||
|
// use the known local interfaces.
|
||||||
|
func InterfaceListenAddresses(s *Swarm) ([]ma.Multiaddr, error) {
|
||||||
|
return addrutil.ResolveUnspecifiedAddresses(s.ListenAddresses(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkNATWarning checks if our observed addresses differ. if so,
|
||||||
|
// informs the user that certain things might not work yet
|
||||||
|
func checkNATWarning(s *Swarm, observed ma.Multiaddr, expected ma.Multiaddr) {
|
||||||
|
listen, err := InterfaceListenAddresses(s)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error retrieving swarm.InterfaceListenAddresses: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
addrutil.CheckNATWarning(observed, expected, listen)
|
||||||
|
}
|
@ -3,6 +3,7 @@ package swarm
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
||||||
testutil "github.com/jbenet/go-ipfs/util/testutil"
|
testutil "github.com/jbenet/go-ipfs/util/testutil"
|
||||||
|
|
||||||
@ -25,6 +26,8 @@ func TestFilterAddrs(t *testing.T) {
|
|||||||
m("/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
|
m("/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
|
||||||
m("/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
|
m("/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
|
||||||
m("/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
|
m("/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
|
||||||
|
m("/ip6/fe80::1/tcp/1234"), // link local
|
||||||
|
m("/ip6/fe80::100/tcp/1234"), // link local
|
||||||
}
|
}
|
||||||
|
|
||||||
good := []ma.Multiaddr{
|
good := []ma.Multiaddr{
|
||||||
@ -37,20 +40,20 @@ func TestFilterAddrs(t *testing.T) {
|
|||||||
// test filters
|
// test filters
|
||||||
|
|
||||||
for _, a := range bad {
|
for _, a := range bad {
|
||||||
if AddrUsable(a) {
|
if addrutil.AddrUsable(a, true) {
|
||||||
t.Errorf("addr %s should be unusable", a)
|
t.Errorf("addr %s should be unusable", a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range good {
|
for _, a := range good {
|
||||||
if !AddrUsable(a) {
|
if !addrutil.AddrUsable(a, true) {
|
||||||
t.Errorf("addr %s should be usable", a)
|
t.Errorf("addr %s should be usable", a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{})
|
subtestAddrsEqual(t, addrutil.FilterAddrs(bad), []ma.Multiaddr{})
|
||||||
subtestAddrsEqual(t, FilterAddrs(good), good)
|
subtestAddrsEqual(t, addrutil.FilterAddrs(good), good)
|
||||||
subtestAddrsEqual(t, FilterAddrs(goodAndBad), good)
|
subtestAddrsEqual(t, addrutil.FilterAddrs(goodAndBad), good)
|
||||||
|
|
||||||
// now test it with swarm
|
// now test it with swarm
|
||||||
|
|
||||||
@ -95,3 +98,29 @@ func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDialBadAddrs(t *testing.T) {
|
||||||
|
|
||||||
|
m := func(s string) ma.Multiaddr {
|
||||||
|
maddr, err := ma.NewMultiaddr(s)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return maddr
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
s := makeSwarms(ctx, t, 1)[0]
|
||||||
|
|
||||||
|
test := func(a ma.Multiaddr) {
|
||||||
|
p := testutil.RandPeerIDFatal(t)
|
||||||
|
s.peers.AddAddress(p, a)
|
||||||
|
if _, err := s.Dial(ctx, p); err == nil {
|
||||||
|
t.Error("swarm should not dial: %s", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test(m("/ip6/fe80::1")) // link local
|
||||||
|
test(m("/ip6/fe80::100")) // link local
|
||||||
|
test(m("/ip4/127.0.0.1/udp/1234/utp")) // utp
|
||||||
|
}
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
||||||
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
|
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
|
||||||
|
|
||||||
@ -38,6 +39,8 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remoteAddrs := s.peers.Addresses(p)
|
remoteAddrs := s.peers.Addresses(p)
|
||||||
|
// make sure we can use the addresses.
|
||||||
|
remoteAddrs = addrutil.FilterAddrs(remoteAddrs)
|
||||||
if len(remoteAddrs) == 0 {
|
if len(remoteAddrs) == 0 {
|
||||||
return nil, errors.New("peer has no addresses")
|
return nil, errors.New("peer has no addresses")
|
||||||
}
|
}
|
||||||
@ -67,6 +70,9 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if connC == nil {
|
||||||
|
err = fmt.Errorf("failed to dial %s", p)
|
||||||
|
}
|
||||||
|
|
||||||
// ok try to setup the new connection.
|
// ok try to setup the new connection.
|
||||||
swarmC, err := dialConnSetup(ctx, s, connC)
|
swarmC, err := dialConnSetup(ctx, s, connC)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
|
||||||
|
addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
|
||||||
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
|
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
|
||||||
|
|
||||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||||
@ -16,7 +17,7 @@ import (
|
|||||||
func (s *Swarm) listen(addrs []ma.Multiaddr) error {
|
func (s *Swarm) listen(addrs []ma.Multiaddr) error {
|
||||||
|
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if !AddrUsable(addr) {
|
if !addrutil.AddrUsable(addr, true) {
|
||||||
return fmt.Errorf("cannot use addr: %s", addr)
|
return fmt.Errorf("cannot use addr: %s", addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,10 +60,12 @@ func (s *Swarm) setupListener(maddr ma.Multiaddr) error {
|
|||||||
// may be fine for sk to be nil, just log a warning.
|
// may be fine for sk to be nil, just log a warning.
|
||||||
log.Warning("Listener not given PrivateKey, so WILL NOT SECURE conns.")
|
log.Warning("Listener not given PrivateKey, so WILL NOT SECURE conns.")
|
||||||
}
|
}
|
||||||
|
log.Infof("Swarm Listening at %s", maddr)
|
||||||
list, err := conn.Listen(s.cg.Context(), maddr, s.local, sk)
|
list, err := conn.Listen(s.cg.Context(), maddr, s.local, sk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log.Infof("Swarm Listening at %s", s.ListenAddresses())
|
||||||
|
|
||||||
// AddListener to the peerstream Listener. this will begin accepting connections
|
// AddListener to the peerstream Listener. this will begin accepting connections
|
||||||
// and streams!
|
// and streams!
|
||||||
|
@ -66,8 +66,13 @@ func NewDHT(ctx context.Context, h host.Host, dstore ds.ThreadSafeDatastore) *Ip
|
|||||||
dht.peerstore = h.Peerstore()
|
dht.peerstore = h.Peerstore()
|
||||||
dht.ContextGroup = ctxgroup.WithContext(ctx)
|
dht.ContextGroup = ctxgroup.WithContext(ctx)
|
||||||
dht.host = h
|
dht.host = h
|
||||||
h.SetStreamHandler(ProtocolDHT, dht.handleNewStream)
|
|
||||||
|
|
||||||
|
// sanity check. this should **never** happen
|
||||||
|
if len(dht.peerstore.Addresses(dht.self)) < 1 {
|
||||||
|
panic("attempt to initialize dht without addresses for self")
|
||||||
|
}
|
||||||
|
|
||||||
|
h.SetStreamHandler(ProtocolDHT, dht.handleNewStream)
|
||||||
dht.providers = NewProviderManager(dht.Context(), dht.self)
|
dht.providers = NewProviderManager(dht.Context(), dht.self)
|
||||||
dht.AddChildGroup(dht.providers)
|
dht.AddChildGroup(dht.providers)
|
||||||
|
|
||||||
@ -132,19 +137,23 @@ func (dht *IpfsDHT) putValueToPeer(ctx context.Context, p peer.ID,
|
|||||||
// can provide the value of 'key'
|
// can provide the value of 'key'
|
||||||
func (dht *IpfsDHT) putProvider(ctx context.Context, p peer.ID, key string) error {
|
func (dht *IpfsDHT) putProvider(ctx context.Context, p peer.ID, key string) error {
|
||||||
|
|
||||||
pmes := pb.NewMessage(pb.Message_ADD_PROVIDER, string(key), 0)
|
|
||||||
|
|
||||||
// add self as the provider
|
// add self as the provider
|
||||||
pi := dht.peerstore.PeerInfo(dht.self)
|
pi := dht.peerstore.PeerInfo(dht.self)
|
||||||
pmes.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), []peer.PeerInfo{pi})
|
// // only share WAN-friendly addresses ??
|
||||||
|
// pi.Addrs = addrutil.WANShareableAddrs(pi.Addrs)
|
||||||
|
if len(pi.Addrs) < 1 {
|
||||||
|
log.Errorf("%s putProvider: %s for %s error: no wan-friendly addresses", dht.self, p, u.Key(key), pi.Addrs)
|
||||||
|
return fmt.Errorf("no known addresses for self. cannot put provider.")
|
||||||
|
}
|
||||||
|
|
||||||
|
pmes := pb.NewMessage(pb.Message_ADD_PROVIDER, string(key), 0)
|
||||||
|
pmes.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), []peer.PeerInfo{pi})
|
||||||
err := dht.sendMessage(ctx, p, pmes)
|
err := dht.sendMessage(ctx, p, pmes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("%s putProvider: %s for %s (%s)", dht.self, p, u.Key(key), pi.Addrs)
|
log.Debugf("%s putProvider: %s for %s (%s)", dht.self, p, u.Key(key), pi.Addrs)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user