basic client

This commit is contained in:
vyzo 2018-05-05 16:45:58 +03:00
parent f0b7fc9cf3
commit 1ad785cc02
2 changed files with 106 additions and 0 deletions

View File

@ -0,0 +1,83 @@
package autonat
import (
"context"
"fmt"
pb "github.com/libp2p/go-libp2p-autonat/pb"
ggio "github.com/gogo/protobuf/io"
host "github.com/libp2p/go-libp2p-host"
inet "github.com/libp2p/go-libp2p-net"
peer "github.com/libp2p/go-libp2p-peer"
pstore "github.com/libp2p/go-libp2p-peerstore"
ma "github.com/multiformats/go-multiaddr"
)
type AutoNATClient interface {
Dial(ctx context.Context) (ma.Multiaddr, error)
}
type AutoNATError struct {
Status pb.Message_ResponseStatus
Text string
}
func NewAutoNATClient(h host.Host, p peer.ID) AutoNATClient {
return &client{h: h, p: p}
}
type client struct {
h host.Host
p peer.ID
}
func (c *client) Dial(ctx context.Context) (ma.Multiaddr, error) {
s, err := c.h.NewStream(ctx, c.p, AutoNATProto)
if err != nil {
return nil, err
}
defer s.Close()
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
w := ggio.NewDelimitedWriter(s)
req := newDialMessage(pstore.PeerInfo{ID: c.h.ID(), Addrs: c.h.Addrs()})
err = w.WriteMsg(req)
if err != nil {
return nil, err
}
var res pb.Message
err = r.ReadMsg(&res)
if err != nil {
return nil, err
}
if res.GetType() != pb.Message_DIAL_RESPONSE {
return nil, fmt.Errorf("Unexpected response: %s", res.GetType().String())
}
status := res.GetDialResponse().GetStatus()
switch status {
case pb.Message_OK:
addr := res.GetDialResponse().GetAddr()
return ma.NewMultiaddrBytes(addr)
default:
return nil, AutoNATError{Status: status, Text: res.GetDialResponse().GetStatusText()}
}
}
func (e AutoNATError) Error() string {
return fmt.Sprintf("AutoNAT error: %s (%s)", e.Text, e.Status.String())
}
func (e AutoNATError) IsDialError() bool {
return e.Status == pb.Message_E_DIAL_ERROR
}
func IsDialError(e error) bool {
ae, ok := e.(AutoNATError)
return ok && ae.IsDialError()
}

23
p2p/host/autonat/proto.go Normal file
View File

@ -0,0 +1,23 @@
package autonat
import (
pb "github.com/libp2p/go-libp2p-autonat/pb"
pstore "github.com/libp2p/go-libp2p-peerstore"
)
const AutoNATProto = "/autonat/1.0.0"
func newDialMessage(pi pstore.PeerInfo) *pb.Message {
msg := new(pb.Message)
msg.Type = pb.Message_DIAL.Enum()
msg.Dial = new(pb.Message_Dial)
msg.Dial.Peer = new(pb.Message_PeerInfo)
msg.Dial.Peer.Id = []byte(pi.ID)
msg.Dial.Peer.Addrs = make([][]byte, len(pi.Addrs))
for i, addr := range pi.Addrs {
msg.Dial.Peer.Addrs[i] = addr.Bytes()
}
return msg
}