提交 0135e3eb 作者: Juan Batiz-Benet

swarm + net: add explicit listen addresses

上级 f0f202ed
...@@ -123,7 +123,12 @@ func NewIpfsNode(cfg *config.Config, online bool) (n *IpfsNode, err error) { ...@@ -123,7 +123,12 @@ func NewIpfsNode(cfg *config.Config, online bool) (n *IpfsNode, err error) {
} }
// setup the network // 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -183,16 +188,6 @@ func initIdentity(cfg *config.Config, peers peer.Peerstore, online bool) (peer.P ...@@ -183,16 +188,6 @@ func initIdentity(cfg *config.Config, peers peer.Peerstore, online bool) (peer.P
return nil, err 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) // when not online, don't need to parse private keys (yet)
if online { if online {
skb, err := base64.StdEncoding.DecodeString(cfg.Identity.PrivKey) skb, err := base64.StdEncoding.DecodeString(cfg.Identity.PrivKey)
...@@ -233,3 +228,18 @@ func initConnections(ctx context.Context, cfg *config.Config, pstore peer.Peerst ...@@ -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
}
...@@ -6,6 +6,8 @@ import ( ...@@ -6,6 +6,8 @@ import (
srv "github.com/jbenet/go-ipfs/net/service" srv "github.com/jbenet/go-ipfs/net/service"
peer "github.com/jbenet/go-ipfs/peer" peer "github.com/jbenet/go-ipfs/peer"
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser" 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. // Network is the interface IPFS uses for connecting to the world.
...@@ -37,6 +39,14 @@ type Network interface { ...@@ -37,6 +39,14 @@ type Network interface {
// SendMessage sends given Message out // SendMessage sends given Message out
SendMessage(msg.NetMessage) error 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. // Sender interface for network services.
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser" ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
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"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
) )
// IpfsNetwork implements the Network interface, // IpfsNetwork implements the Network interface,
...@@ -27,7 +28,7 @@ type IpfsNetwork struct { ...@@ -27,7 +28,7 @@ type IpfsNetwork struct {
} }
// NewIpfsNetwork is the structure that implements the network interface // 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) { peers peer.Peerstore, pmap *mux.ProtocolMap) (*IpfsNetwork, error) {
in := &IpfsNetwork{ in := &IpfsNetwork{
...@@ -37,7 +38,7 @@ func NewIpfsNetwork(ctx context.Context, local peer.Peer, ...@@ -37,7 +38,7 @@ func NewIpfsNetwork(ctx context.Context, local peer.Peer,
} }
var err error var err error
in.swarm, err = swarm.NewSwarm(ctx, local, peers) in.swarm, err = swarm.NewSwarm(ctx, listen, local, peers)
if err != nil { if err != nil {
in.Close() in.Close()
return nil, err return nil, err
...@@ -96,3 +97,15 @@ func (n *IpfsNetwork) GetPeerList() []peer.Peer { ...@@ -96,3 +97,15 @@ func (n *IpfsNetwork) GetPeerList() []peer.Peer {
func (n *IpfsNetwork) GetBandwidthTotals() (in uint64, out uint64) { func (n *IpfsNetwork) GetBandwidthTotals() (in uint64, out uint64) {
return n.muxer.GetBandwidthTotals() 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()
}
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
}
...@@ -12,14 +12,14 @@ import ( ...@@ -12,14 +12,14 @@ import (
) )
// Open listeners for each network the swarm should listen on // 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 hasErr := false
retErr := &ListenErr{ retErr := &ListenErr{
Errors: make([]error, len(s.local.Addresses())), Errors: make([]error, len(addrs)),
} }
// listen on every address // listen on every address
for i, addr := range s.local.Addresses() { for i, addr := range addrs {
err := s.connListen(addr) err := s.connListen(addr)
if err != nil { if err != nil {
hasErr = true hasErr = true
...@@ -37,11 +37,21 @@ func (s *Swarm) listen() error { ...@@ -37,11 +37,21 @@ func (s *Swarm) listen() error {
// Listen for new connections on the given multiaddr // Listen for new connections on the given multiaddr
func (s *Swarm) connListen(maddr ma.Multiaddr) error { 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) list, err := conn.Listen(s.Context(), maddr, s.local, s.peers)
if err != nil { if err != nil {
return err 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... // make sure port can be reused. TOOD this doesn't work...
// if err := setSocketReuse(list); err != nil { // if err := setSocketReuse(list); err != nil {
// return err // return err
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
ctxc "github.com/jbenet/go-ipfs/util/ctxcloser" ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
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"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
) )
var log = u.Logger("swarm") var log = u.Logger("swarm")
...@@ -70,7 +71,7 @@ type Swarm struct { ...@@ -70,7 +71,7 @@ type Swarm struct {
} }
// NewSwarm constructs a Swarm, with a Chan. // 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{ s := &Swarm{
Pipe: msg.NewPipe(10), Pipe: msg.NewPipe(10),
conns: conn.MultiConnMap{}, conns: conn.MultiConnMap{},
...@@ -83,7 +84,7 @@ func NewSwarm(ctx context.Context, local peer.Peer, ps peer.Peerstore) (*Swarm, ...@@ -83,7 +84,7 @@ func NewSwarm(ctx context.Context, local peer.Peer, ps peer.Peerstore) (*Swarm,
s.ContextCloser = ctxc.NewContextCloser(ctx, s.close) s.ContextCloser = ctxc.NewContextCloser(ctx, s.close)
go s.fanOut() go s.fanOut()
return s, s.listen() return s, s.listen(listenAddrs)
} }
// close stops a swarm. It's the underlying function called by ContextCloser // close stops a swarm. It's the underlying function called by ContextCloser
...@@ -210,6 +211,3 @@ func (s *Swarm) GetPeerList() []peer.Peer { ...@@ -210,6 +211,3 @@ func (s *Swarm) GetPeerList() []peer.Peer {
s.connsLock.RUnlock() s.connsLock.RUnlock()
return out 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, [] ...@@ -57,7 +57,7 @@ func makeSwarms(ctx context.Context, t *testing.T, addrs []string) ([]*Swarm, []
for _, addr := range addrs { for _, addr := range addrs {
local := setupPeer(t, addr) local := setupPeer(t, addr)
peerstore := peer.NewPeerstore() peerstore := peer.NewPeerstore()
swarm, err := NewSwarm(ctx, local, peerstore) swarm, err := NewSwarm(ctx, local.Addresses(), local, peerstore)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -24,7 +24,7 @@ func setupDHT(ctx context.Context, t *testing.T, p peer.Peer) *IpfsDHT { ...@@ -24,7 +24,7 @@ func setupDHT(ctx context.Context, t *testing.T, p peer.Peer) *IpfsDHT {
peerstore := peer.NewPeerstore() peerstore := peer.NewPeerstore()
dhts := netservice.NewService(ctx, nil) // nil handler for now, need to patch it 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, mux.ProtocolID_Routing: dhts,
}) })
if err != nil { if err != nil {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论