Skip to content

Commit

Permalink
Merge pull request #2 from libp2p/feat/extract-svc
Browse files Browse the repository at this point in the history
Extract service implementation
  • Loading branch information
vyzo authored Oct 18, 2018
2 parents 0710dd3 + 00f3153 commit a45f261
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 457 deletions.
70 changes: 0 additions & 70 deletions p2p/host/autonat/addr.go

This file was deleted.

20 changes: 14 additions & 6 deletions p2p/host/autonat/autonat.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type AmbientAutoNAT struct {
ctx context.Context
host host.Host

getAddrs GetAddrs

mx sync.Mutex
peers map[peer.ID]struct{}
status NATStatus
Expand All @@ -61,12 +63,18 @@ type AmbientAutoNAT struct {
}

// NewAutoNAT creates a new ambient NAT autodiscovery instance attached to a host
func NewAutoNAT(ctx context.Context, h host.Host) AutoNAT {
// If getAddrs is nil, h.Addrs will be used
func NewAutoNAT(ctx context.Context, h host.Host, getAddrs GetAddrs) AutoNAT {
if getAddrs == nil {
getAddrs = h.Addrs
}

as := &AmbientAutoNAT{
ctx: ctx,
host: h,
peers: make(map[peer.ID]struct{}),
status: NATStatusUnknown,
ctx: ctx,
host: h,
getAddrs: getAddrs,
peers: make(map[peer.ID]struct{}),
status: NATStatusUnknown,
}

h.Network().Notify(as)
Expand Down Expand Up @@ -123,7 +131,7 @@ func (as *AmbientAutoNAT) autodetect() {
return
}

cli := NewAutoNATClient(as.host)
cli := NewAutoNATClient(as.host, as.getAddrs)
failures := 0

for _, p := range peers {
Expand Down
87 changes: 70 additions & 17 deletions p2p/host/autonat/autonat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ package autonat

import (
"context"
"net"
"testing"
"time"

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

ggio "github.com/gogo/protobuf/io"
bhost "github.com/libp2p/go-libp2p-blankhost"
host "github.com/libp2p/go-libp2p-host"
inet "github.com/libp2p/go-libp2p-net"
pstore "github.com/libp2p/go-libp2p-peerstore"
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
ma "github.com/multiformats/go-multiaddr"
)

func init() {
Expand All @@ -17,24 +23,76 @@ func init() {
AutoNATIdentifyDelay = 100 * time.Millisecond
}

func makeAutoNAT(ctx context.Context, t *testing.T) (host.Host, AutoNAT) {
h, err := libp2p.New(ctx, libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"))
if err != nil {
t.Fatal(err)
// these are mock service implementations for testing
func makeAutoNATServicePrivate(ctx context.Context, t *testing.T) host.Host {
h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
h.SetStreamHandler(AutoNATProto, sayAutoNATPrivate)
return h
}

func makeAutoNATServicePublic(ctx context.Context, t *testing.T) host.Host {
h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
h.SetStreamHandler(AutoNATProto, sayAutoNATPublic)
return h
}

func sayAutoNATPrivate(s inet.Stream) {
defer s.Close()
w := ggio.NewDelimitedWriter(s)
res := pb.Message{
Type: pb.Message_DIAL_RESPONSE.Enum(),
DialResponse: newDialResponseError(pb.Message_E_DIAL_ERROR, "no dialable addresses"),
}
w.WriteMsg(&res)
}

func sayAutoNATPublic(s inet.Stream) {
defer s.Close()
w := ggio.NewDelimitedWriter(s)
res := pb.Message{
Type: pb.Message_DIAL_RESPONSE.Enum(),
DialResponse: newDialResponseOK(s.Conn().RemoteMultiaddr()),
}
w.WriteMsg(&res)
}

a := NewAutoNAT(ctx, h)
func newDialResponseOK(addr ma.Multiaddr) *pb.Message_DialResponse {
dr := new(pb.Message_DialResponse)
dr.Status = pb.Message_OK.Enum()
dr.Addr = addr.Bytes()
return dr
}

func newDialResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DialResponse {
dr := new(pb.Message_DialResponse)
dr.Status = status.Enum()
dr.StatusText = &text
return dr
}

func makeAutoNAT(ctx context.Context, t *testing.T, ash host.Host) (host.Host, AutoNAT) {
h := bhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
a := NewAutoNAT(ctx, h, nil)
a.(*AmbientAutoNAT).peers[ash.ID()] = struct{}{}

return h, a
}

// Note: these tests assume the host has only private inet addresses!
func connect(t *testing.T, a, b host.Host) {
pinfo := pstore.PeerInfo{ID: a.ID(), Addrs: a.Addrs()}
err := b.Connect(context.Background(), pinfo)
if err != nil {
t.Fatal(err)
}
}

// tests
func TestAutoNATPrivate(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

hs, _ := makeAutoNATService(ctx, t)
hc, an := makeAutoNAT(ctx, t)
hs := makeAutoNATServicePrivate(ctx, t)
hc, an := makeAutoNAT(ctx, t, hs)

status := an.Status()
if status != NATStatusUnknown {
Expand All @@ -54,11 +112,8 @@ func TestAutoNATPublic(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

save := private4
private4 = []*net.IPNet{}

hs, _ := makeAutoNATService(ctx, t)
hc, an := makeAutoNAT(ctx, t)
hs := makeAutoNATServicePublic(ctx, t)
hc, an := makeAutoNAT(ctx, t, hs)

status := an.Status()
if status != NATStatusUnknown {
Expand All @@ -72,6 +127,4 @@ func TestAutoNATPublic(t *testing.T) {
if status != NATStatusPublic {
t.Fatalf("unexpected NAT status: %d", status)
}

private4 = save
}
16 changes: 12 additions & 4 deletions p2p/host/autonat/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,21 @@ type AutoNATError struct {
Text string
}

// GetAddrs is a function that returns the addresses to dial back
type GetAddrs func() []ma.Multiaddr

// NewAutoNATClient creates a fresh instance of an AutoNATClient
func NewAutoNATClient(h host.Host) AutoNATClient {
return &client{h: h}
// If getAddrs is nil, h.Addrs will be used
func NewAutoNATClient(h host.Host, getAddrs GetAddrs) AutoNATClient {
if getAddrs == nil {
getAddrs = h.Addrs
}
return &client{h: h, getAddrs: getAddrs}
}

type client struct {
h host.Host
h host.Host
getAddrs GetAddrs
}

func (c *client) DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error) {
Expand All @@ -46,7 +54,7 @@ func (c *client) DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error)
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
w := ggio.NewDelimitedWriter(s)

req := newDialMessage(pstore.PeerInfo{ID: c.h.ID(), Addrs: c.h.Addrs()})
req := newDialMessage(pstore.PeerInfo{ID: c.h.ID(), Addrs: c.getAddrs()})
err = w.WriteMsg(req)
if err != nil {
return nil, err
Expand Down
15 changes: 0 additions & 15 deletions p2p/host/autonat/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

logging "github.com/ipfs/go-log"
pstore "github.com/libp2p/go-libp2p-peerstore"
ma "github.com/multiformats/go-multiaddr"
)

const AutoNATProto = "/libp2p/autonat/1.0.0"
Expand All @@ -25,17 +24,3 @@ func newDialMessage(pi pstore.PeerInfo) *pb.Message {

return msg
}

func newDialResponseOK(addr ma.Multiaddr) *pb.Message_DialResponse {
dr := new(pb.Message_DialResponse)
dr.Status = pb.Message_OK.Enum()
dr.Addr = addr.Bytes()
return dr
}

func newDialResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DialResponse {
dr := new(pb.Message_DialResponse)
dr.Status = status.Enum()
dr.StatusText = &text
return dr
}
Loading

0 comments on commit a45f261

Please sign in to comment.