mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-06 00:38:08 +08:00
Merge pull request #271 from jbenet/listen-addrs
Swarm + Handshake Listen Addresses
This commit is contained in:
commit
7cfe2f1a00
6
Godeps/Godeps.json
generated
6
Godeps/Godeps.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"ImportPath": "github.com/jbenet/go-ipfs",
|
||||
"GoVersion": "go1.3.3",
|
||||
"GoVersion": "go1.3",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
@ -102,8 +102,8 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jbenet/go-multiaddr",
|
||||
"Comment": "0.1.2-17-g68a2067",
|
||||
"Rev": "68a20675cb0829da219def0d90afe17a7219e8c7"
|
||||
"Comment": "0.1.2-27-g62a88e0",
|
||||
"Rev": "62a88e015e1bf5d6aaca29aec1aba0722f21c8d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jbenet/go-multihash",
|
||||
|
||||
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md
generated
vendored
10
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md
generated
vendored
@ -34,16 +34,6 @@ addr.Protocols()
|
||||
// }
|
||||
```
|
||||
|
||||
### Other formats
|
||||
|
||||
```go
|
||||
// handles the stupid url version too
|
||||
m = ma.NewUrl("udp4://127.0.0.1:1234")
|
||||
// <Multiaddr /ip4/127.0.0.1/udp/1234>
|
||||
m.Url(buf)
|
||||
// udp4://127.0.0.1:1234
|
||||
```
|
||||
|
||||
### En/decapsulate
|
||||
|
||||
```go
|
||||
|
||||
24
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go
generated
vendored
24
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go
generated
vendored
@ -67,6 +67,30 @@ func bytesToString(b []byte) (ret string, err error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func bytesSplit(b []byte) (ret [][]byte, err error) {
|
||||
// panic handler, in case we try accessing bytes incorrectly.
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ret = [][]byte{}
|
||||
err = e.(error)
|
||||
}
|
||||
}()
|
||||
|
||||
ret = [][]byte{}
|
||||
for len(b) > 0 {
|
||||
p := ProtocolWithCode(int(b[0]))
|
||||
if p == nil {
|
||||
return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0])
|
||||
}
|
||||
|
||||
length := 1 + (p.Size / 8)
|
||||
ret = append(ret, b[:length])
|
||||
b = b[length:]
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func addressStringToBytes(p *Protocol, s string) []byte {
|
||||
switch p.Code {
|
||||
|
||||
|
||||
8
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go
generated
vendored
8
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go
generated
vendored
@ -84,10 +84,10 @@ func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr {
|
||||
mb := m.bytes
|
||||
ob := o.Bytes()
|
||||
|
||||
var b bytes.Buffer
|
||||
b.Write(mb)
|
||||
b.Write(ob)
|
||||
return &multiaddr{bytes: b.Bytes()}
|
||||
b := make([]byte, len(mb)+len(ob))
|
||||
copy(b, mb)
|
||||
copy(b[len(mb):], ob)
|
||||
return &multiaddr{bytes: b}
|
||||
}
|
||||
|
||||
// Decapsulate unwraps Multiaddr up until the given Multiaddr is found.
|
||||
|
||||
BIN
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr
generated
vendored
Normal file
BIN
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr
generated
vendored
Normal file
Binary file not shown.
96
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr.go
generated
vendored
Normal file
96
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// flags
|
||||
var formats = []string{"string", "bytes", "hex", "slice"}
|
||||
var format string
|
||||
var hideLoopback bool
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [<multiaddr>]\n\nFlags:\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
usage := fmt.Sprintf("output format, one of: %v", formats)
|
||||
flag.StringVar(&format, "format", "string", usage)
|
||||
flag.StringVar(&format, "f", "string", usage+" (shorthand)")
|
||||
flag.BoolVar(&hideLoopback, "hide-loopback", false, "do not display loopback addresses")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
args := flag.Args()
|
||||
if len(args) == 0 {
|
||||
output(localAddresses()...)
|
||||
} else {
|
||||
output(address(args[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func localAddresses() []ma.Multiaddr {
|
||||
maddrs, err := manet.InterfaceMultiaddrs()
|
||||
if err != nil {
|
||||
die(err)
|
||||
}
|
||||
|
||||
if !hideLoopback {
|
||||
return maddrs
|
||||
}
|
||||
|
||||
var maddrs2 []ma.Multiaddr
|
||||
for _, a := range maddrs {
|
||||
if !manet.IsIPLoopback(a) {
|
||||
maddrs2 = append(maddrs2, a)
|
||||
}
|
||||
}
|
||||
|
||||
return maddrs2
|
||||
}
|
||||
|
||||
func address(addr string) ma.Multiaddr {
|
||||
m, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
die(err)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func output(ms ...ma.Multiaddr) {
|
||||
for _, m := range ms {
|
||||
fmt.Println(outfmt(m))
|
||||
}
|
||||
}
|
||||
|
||||
func outfmt(m ma.Multiaddr) string {
|
||||
switch format {
|
||||
case "string":
|
||||
return m.String()
|
||||
case "slice":
|
||||
return fmt.Sprintf("%v", m.Bytes())
|
||||
case "bytes":
|
||||
return string(m.Bytes())
|
||||
case "hex":
|
||||
return "0x" + hex.EncodeToString(m.Bytes())
|
||||
}
|
||||
|
||||
die("error: invalid format", format)
|
||||
return ""
|
||||
}
|
||||
|
||||
func die(v ...interface{}) {
|
||||
fmt.Fprint(os.Stderr, v...)
|
||||
fmt.Fprint(os.Stderr, "\n")
|
||||
flag.Usage()
|
||||
os.Exit(-1)
|
||||
}
|
||||
43
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go
generated
vendored
43
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go
generated
vendored
@ -91,6 +91,49 @@ func TestBytesToString(t *testing.T) {
|
||||
testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2")
|
||||
}
|
||||
|
||||
func TestBytesSplitAndJoin(t *testing.T) {
|
||||
|
||||
testString := func(s string, res []string) {
|
||||
m, err := NewMultiaddr(s)
|
||||
if err != nil {
|
||||
t.Error("failed to convert", s)
|
||||
}
|
||||
|
||||
split := Split(m)
|
||||
if len(split) != len(res) {
|
||||
t.Error("not enough split components", split)
|
||||
return
|
||||
}
|
||||
|
||||
for i, a := range split {
|
||||
if a.String() != res[i] {
|
||||
t.Errorf("split component failed: %s != %s", a, res[i])
|
||||
}
|
||||
}
|
||||
|
||||
joined := Join(split...)
|
||||
if !m.Equal(joined) {
|
||||
t.Errorf("joined components failed: %s != %s", m, joined)
|
||||
}
|
||||
|
||||
// modifying underlying bytes is fine.
|
||||
m2 := m.(*multiaddr)
|
||||
for i := range m2.bytes {
|
||||
m2.bytes[i] = 0
|
||||
}
|
||||
|
||||
for i, a := range split {
|
||||
if a.String() != res[i] {
|
||||
t.Errorf("split component failed: %s != %s", a, res[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testString("/ip4/1.2.3.4/udp/1234", []string{"/ip4/1.2.3.4", "/udp/1234"})
|
||||
testString("/ip4/1.2.3.4/tcp/1/ip4/2.3.4.5/udp/2",
|
||||
[]string{"/ip4/1.2.3.4", "/tcp/1", "/ip4/2.3.4.5", "/udp/2"})
|
||||
}
|
||||
|
||||
func TestProtocols(t *testing.T) {
|
||||
m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
if err != nil {
|
||||
|
||||
36
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go
generated
vendored
36
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package net
|
||||
package manet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -62,6 +62,13 @@ func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
}
|
||||
return FromIP(ac.IP)
|
||||
|
||||
case "ip+net":
|
||||
ac, ok := a.(*net.IPNet)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
return FromIP(ac.IP)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown network %v", a.Network())
|
||||
}
|
||||
@ -123,30 +130,3 @@ func DialArgs(m ma.Multiaddr) (string, string, error) {
|
||||
}
|
||||
return network, host, nil
|
||||
}
|
||||
|
||||
// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols.
|
||||
// This means: /{IP4, IP6}[/{TCP, UDP}]
|
||||
func IsThinWaist(m ma.Multiaddr) bool {
|
||||
p := m.Protocols()
|
||||
|
||||
// nothing? not even a waist.
|
||||
if len(p) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 {
|
||||
return false
|
||||
}
|
||||
|
||||
// only IP? still counts.
|
||||
if len(p) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
switch p[1].Code {
|
||||
case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
2
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package net
|
||||
package manet
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
4
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go
generated
vendored
4
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// Package net provides Multiaddr specific versions of common
|
||||
// Package manet provides Multiaddr specific versions of common
|
||||
// functions in stdlib's net package. This means wrappers of
|
||||
// standard net symbols like net.Dial and net.Listen, as well
|
||||
// as conversion to/from net.Addr.
|
||||
package net
|
||||
package manet
|
||||
|
||||
76
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/ip.go
generated
vendored
Normal file
76
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/ip.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
// Loopback Addresses
|
||||
var (
|
||||
// IP4Loopback is the ip4 loopback multiaddr
|
||||
IP4Loopback = ma.StringCast("/ip4/127.0.0.1")
|
||||
|
||||
// IP6Loopback is the ip6 loopback multiaddr
|
||||
IP6Loopback = ma.StringCast("/ip6/::1")
|
||||
|
||||
// IP6LinkLocalLoopback is the ip6 link-local loopback multiaddr
|
||||
IP6LinkLocalLoopback = ma.StringCast("/ip6/fe80::1")
|
||||
)
|
||||
|
||||
// Unspecified Addresses (used for )
|
||||
var (
|
||||
IP4Unspecified = ma.StringCast("/ip4/0.0.0.0")
|
||||
IP6Unspecified = ma.StringCast("/ip6/::")
|
||||
)
|
||||
|
||||
// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols.
|
||||
// This means: /{IP4, IP6}[/{TCP, UDP}]
|
||||
func IsThinWaist(m ma.Multiaddr) bool {
|
||||
p := m.Protocols()
|
||||
|
||||
// nothing? not even a waist.
|
||||
if len(p) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 {
|
||||
return false
|
||||
}
|
||||
|
||||
// only IP? still counts.
|
||||
if len(p) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
switch p[1].Code {
|
||||
case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsIPLoopback returns whether a Multiaddr is a "Loopback" IP address
|
||||
// This means either /ip4/127.0.0.1 or /ip6/::1
|
||||
func IsIPLoopback(m ma.Multiaddr) bool {
|
||||
b := m.Bytes()
|
||||
|
||||
// /ip4/127 prefix (_entire_ /8 is loopback...)
|
||||
if bytes.HasPrefix(b, []byte{4, 127}) {
|
||||
return true
|
||||
}
|
||||
|
||||
// /ip6/::1
|
||||
if IP6Loopback.Equal(m) || IP6LinkLocalLoopback.Equal(m) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address
|
||||
// This means either /ip4/0.0.0.0 or /ip6/::
|
||||
func IsIPUnspecified(m ma.Multiaddr) bool {
|
||||
return IP4Unspecified.Equal(m) || IP6Unspecified.Equal(m)
|
||||
}
|
||||
19
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go
generated
vendored
19
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package net
|
||||
package manet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -216,3 +216,20 @@ func Listen(laddr ma.Multiaddr) (Listener, error) {
|
||||
laddr: laddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs
|
||||
func InterfaceMultiaddrs() ([]ma.Multiaddr, error) {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maddrs := make([]ma.Multiaddr, len(addrs))
|
||||
for i, a := range addrs {
|
||||
maddrs[i], err = FromNetAddr(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return maddrs, nil
|
||||
}
|
||||
|
||||
46
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go
generated
vendored
46
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package net
|
||||
package manet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -198,3 +198,47 @@ func TestListenAndDial(t *testing.T) {
|
||||
cA.Close()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestIPLoopback(t *testing.T) {
|
||||
if IP4Loopback.String() != "/ip4/127.0.0.1" {
|
||||
t.Error("IP4Loopback incorrect:", IP4Loopback)
|
||||
}
|
||||
|
||||
if IP6Loopback.String() != "/ip6/::1" {
|
||||
t.Error("IP6Loopback incorrect:", IP6Loopback)
|
||||
}
|
||||
|
||||
if IP6LinkLocalLoopback.String() != "/ip6/fe80::1" {
|
||||
t.Error("IP6LinkLocalLoopback incorrect:", IP6Loopback)
|
||||
}
|
||||
|
||||
if !IsIPLoopback(IP4Loopback) {
|
||||
t.Error("IsIPLoopback failed (IP4Loopback)")
|
||||
}
|
||||
|
||||
if !IsIPLoopback(IP6Loopback) {
|
||||
t.Error("IsIPLoopback failed (IP6Loopback)")
|
||||
}
|
||||
|
||||
if !IsIPLoopback(IP6LinkLocalLoopback) {
|
||||
t.Error("IsIPLoopback failed (IP6LinkLocalLoopback)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPUnspecified(t *testing.T) {
|
||||
if IP4Unspecified.String() != "/ip4/0.0.0.0" {
|
||||
t.Error("IP4Unspecified incorrect:", IP4Unspecified)
|
||||
}
|
||||
|
||||
if IP6Unspecified.String() != "/ip6/::" {
|
||||
t.Error("IP6Unspecified incorrect:", IP6Unspecified)
|
||||
}
|
||||
|
||||
if !IsIPUnspecified(IP4Unspecified) {
|
||||
t.Error("IsIPUnspecified failed (IP4Unspecified)")
|
||||
}
|
||||
|
||||
if !IsIPUnspecified(IP6Unspecified) {
|
||||
t.Error("IsIPUnspecified failed (IP6Unspecified)")
|
||||
}
|
||||
}
|
||||
|
||||
56
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go
generated
vendored
Normal file
56
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package multiaddr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Split returns the sub-address portions of a multiaddr.
|
||||
func Split(m Multiaddr) []Multiaddr {
|
||||
split, err := bytesSplit(m.Bytes())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid multiaddr %s", m.String()))
|
||||
}
|
||||
|
||||
addrs := make([]Multiaddr, len(split))
|
||||
for i, addr := range split {
|
||||
addrs[i] = &multiaddr{bytes: addr}
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
// Join returns a combination of addresses.
|
||||
func Join(ms ...Multiaddr) Multiaddr {
|
||||
|
||||
length := 0
|
||||
bs := make([][]byte, len(ms))
|
||||
for i, m := range ms {
|
||||
bs[i] = m.Bytes()
|
||||
length += len(bs[i])
|
||||
}
|
||||
|
||||
bidx := 0
|
||||
b := make([]byte, length)
|
||||
for _, mb := range bs {
|
||||
for i := range mb {
|
||||
b[bidx] = mb[i]
|
||||
bidx++
|
||||
}
|
||||
}
|
||||
return &multiaddr{bytes: b}
|
||||
}
|
||||
|
||||
// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse.
|
||||
func Cast(b []byte) Multiaddr {
|
||||
_, err := bytesToString(b)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("multiaddr failed to parse: %s", err))
|
||||
}
|
||||
return &multiaddr{bytes: b}
|
||||
}
|
||||
|
||||
// StringCast like Cast, but parses a string. Will also panic if it fails to parse.
|
||||
func StringCast(s string) Multiaddr {
|
||||
m, err := NewMultiaddr(s)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("multiaddr failed to parse: %s", err))
|
||||
}
|
||||
return m
|
||||
}
|
||||
32
core/core.go
32
core/core.go
@ -123,7 +123,12 @@ func NewIpfsNode(cfg *config.Config, online bool) (n *IpfsNode, err error) {
|
||||
}
|
||||
|
||||
// setup the network
|
||||
n.Network, err = inet.NewIpfsNetwork(ctx, n.Identity, n.Peerstore, muxMap)
|
||||
listenAddrs, err := listenAddresses(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n.Network, err = inet.NewIpfsNetwork(ctx, listenAddrs, n.Identity, n.Peerstore, muxMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -183,16 +188,6 @@ func initIdentity(cfg *config.Config, peers peer.Peerstore, online bool) (peer.P
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// address is optional
|
||||
if len(cfg.Addresses.Swarm) > 0 {
|
||||
maddr, err := ma.NewMultiaddr(cfg.Addresses.Swarm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer.AddAddress(maddr)
|
||||
}
|
||||
|
||||
// when not online, don't need to parse private keys (yet)
|
||||
if online {
|
||||
skb, err := base64.StdEncoding.DecodeString(cfg.Identity.PrivKey)
|
||||
@ -233,3 +228,18 @@ func initConnections(ctx context.Context, cfg *config.Config, pstore peer.Peerst
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
|
||||
var listen []ma.Multiaddr
|
||||
|
||||
if len(cfg.Addresses.Swarm) > 0 {
|
||||
maddr, err := ma.NewMultiaddr(cfg.Addresses.Swarm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failure to parse config.Addresses.Swarm: %s", cfg.Addresses.Swarm)
|
||||
}
|
||||
|
||||
listen = append(listen, maddr)
|
||||
}
|
||||
|
||||
return listen, nil
|
||||
}
|
||||
|
||||
@ -3,15 +3,12 @@ package conn
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
handshake "github.com/jbenet/go-ipfs/net/handshake"
|
||||
hspb "github.com/jbenet/go-ipfs/net/handshake/pb"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
// Handshake1 exchanges local and remote versions and compares them
|
||||
@ -62,87 +59,48 @@ func Handshake1(ctx context.Context, c Conn) error {
|
||||
}
|
||||
|
||||
// Handshake3 exchanges local and remote service information
|
||||
func Handshake3(ctx context.Context, c Conn) error {
|
||||
func Handshake3(ctx context.Context, c Conn) (*handshake.Handshake3Result, error) {
|
||||
rpeer := c.RemotePeer()
|
||||
lpeer := c.LocalPeer()
|
||||
|
||||
// setup + send the message to remote
|
||||
var remoteH, localH *hspb.Handshake3
|
||||
localH = handshake.Handshake3Msg(lpeer)
|
||||
|
||||
rma := c.RemoteMultiaddr()
|
||||
localH.ObservedAddr = proto.String(rma.String())
|
||||
|
||||
localH = handshake.Handshake3Msg(lpeer, c.RemoteMultiaddr())
|
||||
localB, err := proto.Marshal(localH)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.Out() <- localB
|
||||
log.Debugf("Handshake1: sent to %s", rpeer)
|
||||
|
||||
// wait + listen for response
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
return nil, ctx.Err()
|
||||
|
||||
case <-c.Closing():
|
||||
return errors.New("Handshake3: error remote connection closed")
|
||||
return nil, errors.New("Handshake3: error remote connection closed")
|
||||
|
||||
case remoteB, ok := <-c.In():
|
||||
if !ok {
|
||||
return fmt.Errorf("Handshake3 error receiving from conn: %v", rpeer)
|
||||
return nil, fmt.Errorf("Handshake3 error receiving from conn: %v", rpeer)
|
||||
}
|
||||
|
||||
remoteH = new(hspb.Handshake3)
|
||||
err = proto.Unmarshal(remoteB, remoteH)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Handshake3 could not decode remote msg: %q", err)
|
||||
return nil, fmt.Errorf("Handshake3 could not decode remote msg: %q", err)
|
||||
}
|
||||
|
||||
log.Debugf("Handshake3 received from %s", rpeer)
|
||||
}
|
||||
|
||||
if err := handshake.Handshake3UpdatePeer(rpeer, remoteH); err != nil {
|
||||
// actually update our state based on the new knowledge
|
||||
res, err := handshake.Handshake3Update(lpeer, rpeer, remoteH)
|
||||
if err != nil {
|
||||
log.Errorf("Handshake3 failed to update %s", rpeer)
|
||||
return err
|
||||
}
|
||||
|
||||
// If we are behind a NAT, inform the user that certain things might not work yet
|
||||
nat, err := checkNAT(remoteH.GetObservedAddr())
|
||||
if err != nil {
|
||||
log.Errorf("Error in NAT detection: %s", err)
|
||||
}
|
||||
if nat {
|
||||
msg := `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
|
||||
`
|
||||
addrs, _ := u.GetLocalAddresses()
|
||||
log.Warning(fmt.Sprintf(msg, remoteH.GetObservedAddr(), addrs))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkNAT returns whether or not we might be behind a NAT
|
||||
func checkNAT(observedaddr string) (bool, error) {
|
||||
observedma, err := ma.NewMultiaddr(observedaddr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
addrs, err := u.GetLocalAddresses()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
omastr := observedma.String()
|
||||
for _, addr := range addrs {
|
||||
if strings.HasPrefix(omastr, addr.String()) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
res.RemoteObservedAddress = c.RemoteMultiaddr()
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@ -13,18 +13,21 @@ import (
|
||||
var log = u.Logger("handshake")
|
||||
|
||||
// Handshake3Msg constructs a Handshake3 msg.
|
||||
func Handshake3Msg(localPeer peer.Peer) *pb.Handshake3 {
|
||||
func Handshake3Msg(localPeer peer.Peer, remoteAddr ma.Multiaddr) *pb.Handshake3 {
|
||||
var msg pb.Handshake3
|
||||
// don't need publicKey after secure channel.
|
||||
// msg.PublicKey = localPeer.PubKey().Bytes()
|
||||
|
||||
// addresses
|
||||
// local listen addresses
|
||||
addrs := localPeer.Addresses()
|
||||
msg.ListenAddrs = make([][]byte, len(addrs))
|
||||
for i, a := range addrs {
|
||||
msg.ListenAddrs[i] = a.Bytes()
|
||||
}
|
||||
|
||||
// observed remote address
|
||||
msg.ObservedAddr = remoteAddr.Bytes()
|
||||
|
||||
// services
|
||||
// srv := localPeer.Services()
|
||||
// msg.Services = make([]mux.ProtocolID, len(srv))
|
||||
@ -35,20 +38,45 @@ func Handshake3Msg(localPeer peer.Peer) *pb.Handshake3 {
|
||||
return &msg
|
||||
}
|
||||
|
||||
// Handshake3UpdatePeer updates a remote peer with the information in the
|
||||
// handshake3 msg we received from them.
|
||||
func Handshake3UpdatePeer(remotePeer peer.Peer, msg *pb.Handshake3) error {
|
||||
// Handshake3Update updates local knowledge with the information in the
|
||||
// handshake3 msg we received from remote client.
|
||||
func Handshake3Update(lpeer, rpeer peer.Peer, msg *pb.Handshake3) (*Handshake3Result, error) {
|
||||
res := &Handshake3Result{}
|
||||
|
||||
// addresses
|
||||
// our observed address
|
||||
observedAddr, err := ma.NewMultiaddrBytes(msg.GetObservedAddr())
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if lpeer.AddAddress(observedAddr) {
|
||||
log.Infof("(nat) added new local, remote-observed address: %s", observedAddr)
|
||||
}
|
||||
res.LocalObservedAddress = observedAddr
|
||||
|
||||
// remote's reported addresses
|
||||
for _, a := range msg.GetListenAddrs() {
|
||||
addr, err := ma.NewMultiaddrBytes(a)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("remote peer address not a multiaddr: %s", err)
|
||||
log.Errorf("Handshake3: error %s", err)
|
||||
return err
|
||||
log.Errorf("Handshake3 error %s", err)
|
||||
return res, err
|
||||
}
|
||||
remotePeer.AddAddress(addr)
|
||||
rpeer.AddAddress(addr)
|
||||
res.RemoteListenAddresses = append(res.RemoteListenAddresses, addr)
|
||||
}
|
||||
|
||||
return nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Handshake3Result collects the knowledge gained in Handshake3.
|
||||
type Handshake3Result struct {
|
||||
|
||||
// The addresses reported by the remote client
|
||||
RemoteListenAddresses []ma.Multiaddr
|
||||
|
||||
// The address of the remote client we observed in this connection
|
||||
RemoteObservedAddress ma.Multiaddr
|
||||
|
||||
// The address the remote client observed from this connection
|
||||
LocalObservedAddress ma.Multiaddr
|
||||
}
|
||||
|
||||
@ -15,10 +15,12 @@ It has these top-level messages:
|
||||
package handshake_pb
|
||||
|
||||
import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
// Handshake1 is delivered _before_ the secure channel is initialized
|
||||
@ -51,11 +53,13 @@ func (m *Handshake1) GetAgentVersion() string {
|
||||
|
||||
// Handshake3 is delivered _after_ the secure channel is initialized
|
||||
type Handshake3 struct {
|
||||
// listenAddrs are the multiaddrs this node listens for open connections on
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"`
|
||||
// we'll have more fields here later.
|
||||
ObservedAddr *string `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
ObservedAddr []byte `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Handshake3) Reset() { *m = Handshake3{} }
|
||||
@ -69,11 +73,11 @@ func (m *Handshake3) GetListenAddrs() [][]byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Handshake3) GetObservedAddr() string {
|
||||
if m != nil && m.ObservedAddr != nil {
|
||||
return *m.ObservedAddr
|
||||
func (m *Handshake3) GetObservedAddr() []byte {
|
||||
if m != nil {
|
||||
return m.ObservedAddr
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@ -22,7 +22,7 @@ message Handshake3 {
|
||||
// - then again, if we change / disable secure channel, may still want it.
|
||||
// optional bytes publicKey = 1;
|
||||
|
||||
// listenAddrs are the multiaddrs this node listens for open connections on
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
repeated bytes listenAddrs = 2;
|
||||
|
||||
// TODO
|
||||
@ -31,8 +31,8 @@ message Handshake3 {
|
||||
|
||||
// we'll have more fields here later.
|
||||
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the local node perceives
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
optional string observedAddr = 4;
|
||||
optional bytes observedAddr = 4;
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ import (
|
||||
srv "github.com/jbenet/go-ipfs/net/service"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
|
||||
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
// Network is the interface IPFS uses for connecting to the world.
|
||||
@ -37,6 +39,14 @@ type Network interface {
|
||||
|
||||
// SendMessage sends given Message out
|
||||
SendMessage(msg.NetMessage) error
|
||||
|
||||
// ListenAddresses returns a list of addresses at which this network listens.
|
||||
ListenAddresses() []ma.Multiaddr
|
||||
|
||||
// InterfaceListenAddresses returns a list of addresses at which this network
|
||||
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||
// use the known local interfaces.
|
||||
InterfaceListenAddresses() ([]ma.Multiaddr, error)
|
||||
}
|
||||
|
||||
// Sender interface for network services.
|
||||
|
||||
17
net/net.go
17
net/net.go
@ -8,6 +8,7 @@ import (
|
||||
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// IpfsNetwork implements the Network interface,
|
||||
@ -27,7 +28,7 @@ type IpfsNetwork struct {
|
||||
}
|
||||
|
||||
// NewIpfsNetwork is the structure that implements the network interface
|
||||
func NewIpfsNetwork(ctx context.Context, local peer.Peer,
|
||||
func NewIpfsNetwork(ctx context.Context, listen []ma.Multiaddr, local peer.Peer,
|
||||
peers peer.Peerstore, pmap *mux.ProtocolMap) (*IpfsNetwork, error) {
|
||||
|
||||
in := &IpfsNetwork{
|
||||
@ -37,7 +38,7 @@ func NewIpfsNetwork(ctx context.Context, local peer.Peer,
|
||||
}
|
||||
|
||||
var err error
|
||||
in.swarm, err = swarm.NewSwarm(ctx, local, peers)
|
||||
in.swarm, err = swarm.NewSwarm(ctx, listen, local, peers)
|
||||
if err != nil {
|
||||
in.Close()
|
||||
return nil, err
|
||||
@ -96,3 +97,15 @@ func (n *IpfsNetwork) GetPeerList() []peer.Peer {
|
||||
func (n *IpfsNetwork) GetBandwidthTotals() (in uint64, out uint64) {
|
||||
return n.muxer.GetBandwidthTotals()
|
||||
}
|
||||
|
||||
// ListenAddresses returns a list of addresses at which this network listens.
|
||||
func (n *IpfsNetwork) ListenAddresses() []ma.Multiaddr {
|
||||
return n.swarm.ListenAddresses()
|
||||
}
|
||||
|
||||
// InterfaceListenAddresses returns a list of addresses at which this network
|
||||
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||
// use the known local interfaces.
|
||||
func (n *IpfsNetwork) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
|
||||
return n.swarm.InterfaceListenAddresses()
|
||||
}
|
||||
|
||||
107
net/swarm/addrs.go
Normal file
107
net/swarm/addrs.go
Normal file
@ -0,0 +1,107 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net"
|
||||
|
||||
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 {
|
||||
addrs := make([]ma.Multiaddr, len(s.listeners))
|
||||
for i, l := range s.listeners {
|
||||
addrs[i] = l.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 (s *Swarm) InterfaceListenAddresses() ([]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)
|
||||
continue
|
||||
}
|
||||
|
||||
// unspecified? add one address per interface.
|
||||
for _, ia := range ifaceAddrs {
|
||||
split[0] = ia
|
||||
joined := ma.Join(split...)
|
||||
outputAddrs = append(outputAddrs, joined)
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("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 (s *Swarm) checkNATWarning(observed ma.Multiaddr) {
|
||||
listen, err := s.InterfaceListenAddresses()
|
||||
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
|
||||
`
|
||||
@ -12,14 +12,14 @@ import (
|
||||
)
|
||||
|
||||
// Open listeners for each network the swarm should listen on
|
||||
func (s *Swarm) listen() error {
|
||||
func (s *Swarm) listen(addrs []ma.Multiaddr) error {
|
||||
hasErr := false
|
||||
retErr := &ListenErr{
|
||||
Errors: make([]error, len(s.local.Addresses())),
|
||||
Errors: make([]error, len(addrs)),
|
||||
}
|
||||
|
||||
// listen on every address
|
||||
for i, addr := range s.local.Addresses() {
|
||||
for i, addr := range addrs {
|
||||
err := s.connListen(addr)
|
||||
if err != nil {
|
||||
hasErr = true
|
||||
@ -37,11 +37,21 @@ func (s *Swarm) listen() error {
|
||||
// Listen for new connections on the given multiaddr
|
||||
func (s *Swarm) connListen(maddr ma.Multiaddr) error {
|
||||
|
||||
resolved, err := resolveUnspecifiedAddresses([]ma.Multiaddr{maddr})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
list, err := conn.Listen(s.Context(), maddr, s.local, s.peers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add resolved local addresses to peer
|
||||
for _, addr := range resolved {
|
||||
s.local.AddAddress(addr)
|
||||
}
|
||||
|
||||
// make sure port can be reused. TOOD this doesn't work...
|
||||
// if err := setSocketReuse(list); err != nil {
|
||||
// return err
|
||||
@ -102,11 +112,15 @@ func (s *Swarm) connSetup(c conn.Conn) (conn.Conn, error) {
|
||||
|
||||
// handshake3
|
||||
ctxT, _ := context.WithTimeout(c.Context(), conn.HandshakeTimeout)
|
||||
if err := conn.Handshake3(ctxT, c); err != nil {
|
||||
h3result, err := conn.Handshake3(ctxT, c)
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("Handshake3 failed: %s", err)
|
||||
}
|
||||
|
||||
// check for nats. you know, just in case.
|
||||
s.checkNATWarning(h3result.LocalObservedAddress)
|
||||
|
||||
// add to conns
|
||||
s.connsLock.Lock()
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
var log = u.Logger("swarm")
|
||||
@ -70,7 +71,7 @@ type Swarm struct {
|
||||
}
|
||||
|
||||
// NewSwarm constructs a Swarm, with a Chan.
|
||||
func NewSwarm(ctx context.Context, local peer.Peer, ps peer.Peerstore) (*Swarm, error) {
|
||||
func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr, local peer.Peer, ps peer.Peerstore) (*Swarm, error) {
|
||||
s := &Swarm{
|
||||
Pipe: msg.NewPipe(10),
|
||||
conns: conn.MultiConnMap{},
|
||||
@ -83,7 +84,7 @@ func NewSwarm(ctx context.Context, local peer.Peer, ps peer.Peerstore) (*Swarm,
|
||||
s.ContextCloser = ctxc.NewContextCloser(ctx, s.close)
|
||||
|
||||
go s.fanOut()
|
||||
return s, s.listen()
|
||||
return s, s.listen(listenAddrs)
|
||||
}
|
||||
|
||||
// close stops a swarm. It's the underlying function called by ContextCloser
|
||||
@ -210,6 +211,3 @@ func (s *Swarm) GetPeerList() []peer.Peer {
|
||||
s.connsLock.RUnlock()
|
||||
return out
|
||||
}
|
||||
|
||||
// Temporary to ensure that the Swarm always matches the Network interface as we are changing it
|
||||
// var _ Network = &Swarm{}
|
||||
|
||||
@ -57,7 +57,7 @@ func makeSwarms(ctx context.Context, t *testing.T, addrs []string) ([]*Swarm, []
|
||||
for _, addr := range addrs {
|
||||
local := setupPeer(t, addr)
|
||||
peerstore := peer.NewPeerstore()
|
||||
swarm, err := NewSwarm(ctx, local, peerstore)
|
||||
swarm, err := NewSwarm(ctx, local.Addresses(), local, peerstore)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -66,7 +66,8 @@ type Peer interface {
|
||||
Addresses() []ma.Multiaddr
|
||||
|
||||
// AddAddress adds the given Multiaddr address to Peer's addresses.
|
||||
AddAddress(a ma.Multiaddr)
|
||||
// returns whether this was a newly added address.
|
||||
AddAddress(a ma.Multiaddr) bool
|
||||
|
||||
// NetAddress returns the first Multiaddr found for a given network.
|
||||
NetAddress(n string) ma.Multiaddr
|
||||
@ -141,16 +142,18 @@ func (p *peer) Addresses() []ma.Multiaddr {
|
||||
}
|
||||
|
||||
// AddAddress adds the given Multiaddr address to Peer's addresses.
|
||||
func (p *peer) AddAddress(a ma.Multiaddr) {
|
||||
// Returns whether this address was a newly added address
|
||||
func (p *peer) AddAddress(a ma.Multiaddr) bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
|
||||
for _, addr := range p.addresses {
|
||||
if addr.Equal(a) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
}
|
||||
p.addresses = append(p.addresses, a)
|
||||
return true
|
||||
}
|
||||
|
||||
// NetAddress returns the first Multiaddr found for a given network.
|
||||
|
||||
@ -24,7 +24,7 @@ func setupDHT(ctx context.Context, t *testing.T, p peer.Peer) *IpfsDHT {
|
||||
peerstore := peer.NewPeerstore()
|
||||
|
||||
dhts := netservice.NewService(ctx, nil) // nil handler for now, need to patch it
|
||||
net, err := inet.NewIpfsNetwork(ctx, p, peerstore, &mux.ProtocolMap{
|
||||
net, err := inet.NewIpfsNetwork(ctx, p.Addresses(), p, peerstore, &mux.ProtocolMap{
|
||||
mux.ProtocolID_Routing: dhts,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
59
util/util.go
59
util/util.go
@ -4,16 +4,13 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
|
||||
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"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
@ -111,57 +108,3 @@ func GetenvBool(name string) bool {
|
||||
v := strings.ToLower(os.Getenv(name))
|
||||
return v == "true" || v == "t" || v == "1"
|
||||
}
|
||||
|
||||
// IsLoopbackAddr returns whether or not the ip portion of the passed in multiaddr
|
||||
// string is a loopback address
|
||||
func IsLoopbackAddr(addr string) bool {
|
||||
loops := []string{"/ip4/127.0.0.1", "/ip6/::1"}
|
||||
for _, loop := range loops {
|
||||
if strings.HasPrefix(addr, loop) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetLocalAddresses returns a list of ip addresses associated with
|
||||
// the local machine
|
||||
func GetLocalAddresses() ([]ma.Multiaddr, error) {
|
||||
// Enumerate interfaces on this machine
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var maddrs []ma.Multiaddr
|
||||
for _, i := range ifaces {
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
log.Warningf("Skipping addr: %s", err)
|
||||
continue
|
||||
}
|
||||
// Check each address and convert to a multiaddr
|
||||
for _, addr := range addrs {
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
|
||||
// Build multiaddr
|
||||
maddr, err := manet.FromIP(v.IP)
|
||||
if err != nil {
|
||||
log.Errorf("maddr parsing error: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Dont list loopback addresses
|
||||
if IsLoopbackAddr(maddr.String()) {
|
||||
continue
|
||||
}
|
||||
maddrs = append(maddrs, maddr)
|
||||
default:
|
||||
// Not sure if any other types will show up here
|
||||
log.Errorf("Got '%s' type = '%s'", v, reflect.TypeOf(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
return maddrs, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user