Commit 3b5d1164 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet
Browse files

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 afaddf4c
package basichost
import (
"sync"
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"
inat "github.com/jbenet/go-ipfs/p2p/nat"
inet "github.com/jbenet/go-ipfs/p2p/net"
peer "github.com/jbenet/go-ipfs/p2p/peer"
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
......@@ -14,20 +19,35 @@ import (
var log = eventlog.Logger("p2p/host/basic")
type Option int
const (
NATPortMap Option = iota
)
type BasicHost struct {
network inet.Network
mux *protocol.Mux
ids *identify.IDService
relay *relay.RelayService
natmu sync.Mutex
nat *inat.NAT
proc goprocess.Process
}
// 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{
network: net,
mux: protocol.NewMux(),
}
h.proc = goprocess.WithTeardown(func() error {
return h.Network().Close()
})
// setup host services
h.ids = identify.NewIDService(h)
h.relay = relay.NewRelayService(h, h.Mux().HandleSync)
......@@ -35,9 +55,48 @@ func New(net inet.Network) *BasicHost {
net.SetConnHandler(h.newConnHandler)
net.SetStreamHandler(h.newStreamHandler)
for _, o := range opts {
switch o {
case NATPortMap:
h.setupNATPortMap()
}
}
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
func (h *BasicHost) newConnHandler(c inet.Conn) {
h.ids.IdentifyConn(c)
......@@ -143,7 +202,23 @@ func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error {
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).
func (h *BasicHost) Close() error {
return h.Network().Close()
return h.proc.Close()
}
......@@ -2,6 +2,7 @@ package host
import (
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"
peer "github.com/jbenet/go-ipfs/p2p/peer"
......@@ -23,6 +24,9 @@ type Host interface {
// Peerstore returns the Host's repository of Peer Addresses and Keys.
Peerstore() peer.Peerstore
// Returns the listen addresses of the Host
Addrs() []ma.Multiaddr
// Networks returns the Network interface of the Host
Network() inet.Network
......
......@@ -29,9 +29,9 @@ var log = eventlog.Logger("nat")
// Port mappings are renewed every (MappingDuration / 3)
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.
func DiscoverGateway() *NAT {
func DiscoverNAT() *NAT {
nat, err := nat.DiscoverGateway()
if err != nil {
log.Debug("DiscoverGateway error:", err)
......@@ -72,6 +72,12 @@ func (nat *NAT) Close() error {
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.
// It is implemented using github.com/jbenet/go-ipfs/thirdparty/notifier
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