Commit ca757c66 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

p2p/nat: managed by host now.

Exposing the NAT to the core is unnecessary. The Host can take
care of it. If a need emerges, we can address it then.
parent 332d3501
...@@ -18,7 +18,6 @@ import ( ...@@ -18,7 +18,6 @@ import (
ic "github.com/jbenet/go-ipfs/p2p/crypto" ic "github.com/jbenet/go-ipfs/p2p/crypto"
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"
inat "github.com/jbenet/go-ipfs/p2p/nat"
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" 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"
...@@ -422,7 +421,7 @@ func constructPeerHost(ctx context.Context, cfg *config.Config, id peer.ID, ps p ...@@ -422,7 +421,7 @@ func constructPeerHost(ctx context.Context, cfg *config.Config, id peer.ID, ps p
return nil, debugerror.Wrap(err) return nil, debugerror.Wrap(err)
} }
peerhost := p2pbhost.New(network) peerhost := p2pbhost.New(network, p2pbhost.NATPortMap)
// explicitly set these as our listen addrs. // explicitly set these as our listen addrs.
// (why not do it inside inet.NewNetwork? because this way we can // (why not do it inside inet.NewNetwork? because this way we can
// listen on addresses without necessarily advertising those publicly.) // listen on addresses without necessarily advertising those publicly.)
...@@ -432,16 +431,6 @@ func constructPeerHost(ctx context.Context, cfg *config.Config, id peer.ID, ps p ...@@ -432,16 +431,6 @@ func constructPeerHost(ctx context.Context, cfg *config.Config, id peer.ID, ps p
} }
log.Infof("Swarm listening at: %s", addrs) log.Infof("Swarm listening at: %s", addrs)
nat := inat.DiscoverGateway()
if nat != nil {
nat.PortMapAddrs(filteredAddrs)
mapAddrs := nat.ExternalAddrs()
if len(mapAddrs) > 0 {
log.Infof("NAT mapping addrs: %s", mapAddrs)
addrs = append(addrs, mapAddrs...)
}
}
ps.AddAddresses(id, addrs) ps.AddAddresses(id, addrs)
return peerhost, nil return peerhost, nil
} }
......
package basichost package basichost
import ( import (
"sync"
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"
goprocess "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog" eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
inat "github.com/jbenet/go-ipfs/p2p/nat"
inet "github.com/jbenet/go-ipfs/p2p/net" inet "github.com/jbenet/go-ipfs/p2p/net"
peer "github.com/jbenet/go-ipfs/p2p/peer" peer "github.com/jbenet/go-ipfs/p2p/peer"
protocol "github.com/jbenet/go-ipfs/p2p/protocol" protocol "github.com/jbenet/go-ipfs/p2p/protocol"
...@@ -14,20 +19,35 @@ import ( ...@@ -14,20 +19,35 @@ import (
var log = eventlog.Logger("p2p/host/basic") var log = eventlog.Logger("p2p/host/basic")
type Option int
const (
NATPortMap Option = iota
)
type BasicHost struct { type BasicHost struct {
network inet.Network network inet.Network
mux *protocol.Mux mux *protocol.Mux
ids *identify.IDService ids *identify.IDService
relay *relay.RelayService relay *relay.RelayService
natmu sync.Mutex
nat *inat.NAT
proc goprocess.Process
} }
// New constructs and sets up a new *BasicHost with given Network // New constructs and sets up a new *BasicHost with given Network
func New(net inet.Network) *BasicHost { func New(net inet.Network, opts ...Option) *BasicHost {
h := &BasicHost{ h := &BasicHost{
network: net, network: net,
mux: protocol.NewMux(), mux: protocol.NewMux(),
} }
h.proc = goprocess.WithTeardown(func() error {
return h.Network().Close()
})
// setup host services // setup host services
h.ids = identify.NewIDService(h) h.ids = identify.NewIDService(h)
h.relay = relay.NewRelayService(h, h.Mux().HandleSync) h.relay = relay.NewRelayService(h, h.Mux().HandleSync)
...@@ -35,9 +55,48 @@ func New(net inet.Network) *BasicHost { ...@@ -35,9 +55,48 @@ func New(net inet.Network) *BasicHost {
net.SetConnHandler(h.newConnHandler) net.SetConnHandler(h.newConnHandler)
net.SetStreamHandler(h.newStreamHandler) net.SetStreamHandler(h.newStreamHandler)
for _, o := range opts {
switch o {
case NATPortMap:
h.setupNATPortMap()
}
}
return h return h
} }
func (h *BasicHost) setupNATPortMap() {
// do this asynchronously to avoid blocking daemon startup
h.proc.Go(func(worker goprocess.Process) {
nat := inat.DiscoverNAT()
if nat == nil { // no nat, or failed to get it.
return
}
select {
case <-worker.Closing():
nat.Close()
return
default:
}
// wire up the nat to close when proc closes.
h.proc.AddChild(nat.Process())
h.natmu.Lock()
h.nat = nat
h.natmu.Unlock()
addrs := h.Network().ListenAddresses()
nat.PortMapAddrs(addrs)
mapAddrs := nat.ExternalAddrs()
if len(mapAddrs) > 0 {
log.Infof("NAT mapping addrs: %s", mapAddrs)
}
})
}
// newConnHandler is the remote-opened conn handler for inet.Network // newConnHandler is the remote-opened conn handler for inet.Network
func (h *BasicHost) newConnHandler(c inet.Conn) { func (h *BasicHost) newConnHandler(c inet.Conn) {
h.ids.IdentifyConn(c) h.ids.IdentifyConn(c)
...@@ -143,7 +202,23 @@ func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error { ...@@ -143,7 +202,23 @@ func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error {
return nil return nil
} }
func (h *BasicHost) Addrs() []ma.Multiaddr {
addrs, err := h.Network().InterfaceListenAddresses()
if err != nil {
log.Debug("error retrieving network interface addrs")
}
h.natmu.Lock()
nat := h.nat
h.natmu.Unlock()
if nat != nil {
addrs = append(addrs, nat.ExternalAddrs()...)
}
return addrs
}
// Close shuts down the Host's services (network, etc). // Close shuts down the Host's services (network, etc).
func (h *BasicHost) Close() error { func (h *BasicHost) Close() error {
return h.Network().Close() return h.proc.Close()
} }
...@@ -2,6 +2,7 @@ package host ...@@ -2,6 +2,7 @@ package host
import ( import (
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"
inet "github.com/jbenet/go-ipfs/p2p/net" inet "github.com/jbenet/go-ipfs/p2p/net"
peer "github.com/jbenet/go-ipfs/p2p/peer" peer "github.com/jbenet/go-ipfs/p2p/peer"
...@@ -23,6 +24,9 @@ type Host interface { ...@@ -23,6 +24,9 @@ type Host interface {
// Peerstore returns the Host's repository of Peer Addresses and Keys. // Peerstore returns the Host's repository of Peer Addresses and Keys.
Peerstore() peer.Peerstore Peerstore() peer.Peerstore
// Returns the listen addresses of the Host
Addrs() []ma.Multiaddr
// Networks returns the Network interface of the Host // Networks returns the Network interface of the Host
Network() inet.Network Network() inet.Network
......
...@@ -29,9 +29,9 @@ var log = eventlog.Logger("nat") ...@@ -29,9 +29,9 @@ var log = eventlog.Logger("nat")
// Port mappings are renewed every (MappingDuration / 3) // Port mappings are renewed every (MappingDuration / 3)
const MappingDuration = time.Second * 60 const MappingDuration = time.Second * 60
// DiscoverGateway looks for a NAT device in the network and // DiscoverNAT looks for a NAT device in the network and
// returns an object that can manage port mappings. // returns an object that can manage port mappings.
func DiscoverGateway() *NAT { func DiscoverNAT() *NAT {
nat, err := nat.DiscoverGateway() nat, err := nat.DiscoverGateway()
if err != nil { if err != nil {
log.Debug("DiscoverGateway error:", err) log.Debug("DiscoverGateway error:", err)
...@@ -72,6 +72,12 @@ func (nat *NAT) Close() error { ...@@ -72,6 +72,12 @@ func (nat *NAT) Close() error {
return nat.proc.Close() return nat.proc.Close()
} }
// Process returns the nat's life-cycle manager, for making it listen
// to close signals.
func (nat *NAT) Process() goprocess.Process {
return nat.proc
}
// Notifier is an object that assists NAT in notifying listeners. // Notifier is an object that assists NAT in notifying listeners.
// It is implemented using github.com/jbenet/go-ipfs/thirdparty/notifier // It is implemented using github.com/jbenet/go-ipfs/thirdparty/notifier
type Notifier struct { type Notifier struct {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment