Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Commit

Permalink
change 'mode' to be implicit
Browse files Browse the repository at this point in the history
  • Loading branch information
willscott committed Mar 16, 2020
1 parent f5497e5 commit f1cd6ba
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 76 deletions.
4 changes: 2 additions & 2 deletions autonat.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func New(ctx context.Context, h host.Host, options ...Option) (AutoNAT, error) {
h.Network().Notify(as)
go as.background()

if conf.mode != ModeClient {
if conf.dialer != nil {
var err error
as.service, err = newAutoNATService(ctx, conf)
if err != nil {
Expand Down Expand Up @@ -225,7 +225,7 @@ func (as *AmbientAutoNAT) recordObservation(observation autoNATResult) {
if currentStatus.Reachability != network.ReachabilityPublic {
// we are flipping our NATStatus, so confidence drops to 0
as.confidence = 0
if as.mode == ModeAuto && as.service != nil {
if as.service != nil && !as.config.forceServer {
ctx, cancel := context.WithCancel(as.ctx)
go as.service.Enable(ctx)
as.serviceCancel = cancel
Expand Down
2 changes: 1 addition & 1 deletion autonat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func makeAutoNAT(ctx context.Context, t *testing.T, ash host.Host) (host.Host, A
h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
h.Peerstore().AddAddrs(ash.ID(), ash.Addrs(), time.Minute)
h.Peerstore().AddProtocols(ash.ID(), AutoNATProto)
a, _ := New(ctx, h, WithSchedule(100*time.Millisecond, time.Second), WithoutStartupDelay(), WithMode(ModeClient))
a, _ := New(ctx, h, WithSchedule(100*time.Millisecond, time.Second), WithoutStartupDelay())
return h, a
}

Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ require (
github.com/libp2p/go-libp2p v0.6.0
github.com/libp2p/go-libp2p-blankhost v0.1.4
github.com/libp2p/go-libp2p-core v0.5.0
github.com/libp2p/go-libp2p-peerstore v0.2.0
github.com/libp2p/go-libp2p-swarm v0.2.2
github.com/libp2p/go-tcp-transport v0.1.1
github.com/multiformats/go-multiaddr v0.2.1
github.com/multiformats/go-multiaddr-net v0.1.3
)
Expand Down
45 changes: 10 additions & 35 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
type config struct {
host host.Host

mode Mode
addressGuesserFunc AddrFunc
dialer network.Dialer
dialer network.Network
forceServer bool

// client
bootDelay time.Duration
Expand All @@ -32,7 +32,6 @@ type config struct {
}

var defaults = func(c *config) error {
c.mode = ModeAuto
c.bootDelay = 15 * time.Second
c.retryInterval = 90 * time.Second
c.refreshInterval = 15 * time.Minute
Expand All @@ -47,43 +46,19 @@ var defaults = func(c *config) error {
return nil
}

// Mode defines how the autonat system behaves.
type Mode byte

const (
// ModeAuto indicates that when this system detects it is not behind a NAT,
// it will help peers determine their own NAT statuses.
ModeAuto Mode = iota
// ModeClient indicates that the system should detect its own NAT status,
// but should not help peers.
ModeClient
// ModeServer indicates that this system should always help peers determine
// their NAT status regardless of its own connectivity.
ModeServer
)

// WithMode specifies the mode of AutoNAT operation.
func WithMode(mode Mode) Option {
return func(c *config) error {
c.mode = mode
return nil
}
}

// WithDialer specifies a network Dialer to use when attempting to dial to potentially
// NATed peers. Note: This dialer should not be the default network/dialer of the
// host, as the NAT system will need to make parallel connections, and as such will
// modify both the associated peerstore and terminate connections. The dialer provided
// should be compatible (TCP/UDP) with the transports in this libp2p network.
// When not specified, a dialer will be created either using the same transports present
// if a `Swarm` network is used, or falling back to the default TCP networking transport
// otherwise.
func WithDialer(dialer network.Dialer) Option {
// EnableService specifies that AutoNAT should be allowed to run a NAT service to help
// other peers determine their own NAT status. The provided Network should not be the
// default network/dialer of the host passed to `New`, as the NAT system will need to
// make parallel connections, and as such will modify both the associated peerstore
// and terminate connections of this dialer. The dialer provided
// should be compatible (TCP/UDP) however with the transports of the libp2p network.
func EnableService(dialer network.Network, forceServer bool) Option {
return func(c *config) error {
if dialer == c.host.Network() || dialer.Peerstore() == c.host.Peerstore() {
return errors.New("dialer should not be that of the host")
}
c.dialer = dialer
c.forceServer = forceServer
return nil
}
}
Expand Down
36 changes: 3 additions & 33 deletions svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ package autonat

import (
"context"
"errors"
"math/rand"
"net"
"sync"
"time"

"github.com/libp2p/go-libp2p-core/helpers"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-peerstore/pstoremem"
swarm "github.com/libp2p/go-libp2p-swarm"
"github.com/libp2p/go-tcp-transport"

pb "github.com/libp2p/go-libp2p-autonat/pb"

Expand All @@ -40,7 +37,7 @@ type autoNATService struct {
// NewAutoNATService creates a new AutoNATService instance attached to a host
func newAutoNATService(ctx context.Context, c *config) (*autoNATService, error) {
if c.dialer == nil {
c.dialer = newDialerFromHost(ctx, c.host)
return nil, errors.New("Cannot create NAT service without a network")
}

as := &autoNATService{
Expand All @@ -49,40 +46,13 @@ func newAutoNATService(ctx context.Context, c *config) (*autoNATService, error)
reqs: make(map[peer.ID]int),
}

if c.mode == ModeServer {
if c.forceServer {
go as.Enable(ctx)
}

return as, nil
}

func newDialerFromHost(ctx context.Context, h host.Host) network.Dialer {
store := pstoremem.NewPeerstore()
id := h.ID()
store.AddPrivKey(id, h.Peerstore().PrivKey(id))
store.AddPubKey(id, h.Peerstore().PubKey(id))
network := swarm.NewSwarm(ctx, id, store, nil)

currentNetwork, ok := h.Network().(*swarm.Swarm)
if !ok {
// fall back to the libp2p default.
network.AddTransport(tcp.NewTCPTransport(nil))
return network
}

for _, p := range ma.Protocols {
addrOfProto, err := ma.NewComponent(p.Name, "0")
if err != nil {
continue
}
if t := currentNetwork.TransportForDialing(addrOfProto); t != nil {
_ = network.AddTransport(t)
}
}

return network
}

func (as *autoNATService) handleStream(s network.Stream) {
defer helpers.FullClose(s)

Expand Down
8 changes: 5 additions & 3 deletions svc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import (

func makeAutoNATConfig(ctx context.Context, t *testing.T) *config {
h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
c := config{host: h}
dh := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
c := config{host: h, dialer: dh.Network()}
_ = defaults(&c)
c.mode = ModeServer
c.forceServer = true
return &c
}

Expand Down Expand Up @@ -193,7 +194,8 @@ func TestAutoNATServiceStartup(t *testing.T) {
manet.Private4 = []*net.IPNet{}

h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
an, err := New(ctx, h)
dh := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
an, err := New(ctx, h, EnableService(dh.Network(), false))
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit f1cd6ba

Please sign in to comment.