mirror of
https://github.com/waku-org/go-multiaddr.git
synced 2025-02-22 19:18:14 +00:00
commit
68a20675cb
10
.travis.yml
Normal file
10
.travis.yml
Normal file
@ -0,0 +1,10 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- release
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
11
net/README.md
Normal file
11
net/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# multiaddr/net - Multiaddr friendly net
|
||||
|
||||
Package multiaddr/net provides Multiaddr specific versions of common
|
||||
functions in stdlib's net package. This means wrappers of
|
||||
standard net symbols like net.Dial and net.Listen, as well
|
||||
as conversion to/from net.Addr.
|
||||
|
||||
Docs:
|
||||
|
||||
- `multiaddr/net`: https://godoc.org/github.com/jbenet/go-multiaddr/net
|
||||
- `multiaddr`: https://godoc.org/github.com/jbenet/go-multiaddr
|
@ -1,15 +1,17 @@
|
||||
package multiaddr
|
||||
package net
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
ma "github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
|
||||
|
||||
// FromNetAddr converts a net.Addr type to a Multiaddr.
|
||||
func FromNetAddr(a net.Addr) (Multiaddr, error) {
|
||||
func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
switch a.Network() {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
ac, ok := a.(*net.TCPAddr)
|
||||
@ -24,7 +26,7 @@ func FromNetAddr(a net.Addr) (Multiaddr, error) {
|
||||
}
|
||||
|
||||
// Get TCP Addr
|
||||
tcpm, err := NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
|
||||
tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
@ -45,7 +47,7 @@ func FromNetAddr(a net.Addr) (Multiaddr, error) {
|
||||
}
|
||||
|
||||
// Get UDP Addr
|
||||
udpm, err := NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
|
||||
udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
@ -68,8 +70,8 @@ func FromNetAddr(a net.Addr) (Multiaddr, error) {
|
||||
// ToNetAddr converts a Multiaddr to a net.Addr
|
||||
// Must be ThinWaist. acceptable protocol stacks are:
|
||||
// /ip{4,6}/{tcp, udp}
|
||||
func ToNetAddr(ma Multiaddr) (net.Addr, error) {
|
||||
network, host, err := DialArgs(ma)
|
||||
func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||
network, host, err := DialArgs(maddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -87,19 +89,19 @@ func ToNetAddr(ma Multiaddr) (net.Addr, error) {
|
||||
}
|
||||
|
||||
// FromIP converts a net.IP type to a Multiaddr.
|
||||
func FromIP(ip net.IP) (Multiaddr, error) {
|
||||
func FromIP(ip net.IP) (ma.Multiaddr, error) {
|
||||
switch {
|
||||
case ip.To4() != nil:
|
||||
return NewMultiaddr("/ip4/" + ip.String())
|
||||
return ma.NewMultiaddr("/ip4/" + ip.String())
|
||||
case ip.To16() != nil:
|
||||
return NewMultiaddr("/ip6/" + ip.String())
|
||||
return ma.NewMultiaddr("/ip6/" + ip.String())
|
||||
default:
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
}
|
||||
|
||||
// DialArgs is a convenience function returning arguments for use in net.Dial
|
||||
func DialArgs(m Multiaddr) (string, string, error) {
|
||||
func DialArgs(m ma.Multiaddr) (string, string, error) {
|
||||
if !IsThinWaist(m) {
|
||||
return "", "", fmt.Errorf("%s is not a 'thin waist' address", m)
|
||||
}
|
||||
@ -124,7 +126,7 @@ func DialArgs(m Multiaddr) (string, string, error) {
|
||||
|
||||
// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols.
|
||||
// This means: /{IP4, IP6}[/{TCP, UDP}]
|
||||
func IsThinWaist(m Multiaddr) bool {
|
||||
func IsThinWaist(m ma.Multiaddr) bool {
|
||||
p := m.Protocols()
|
||||
|
||||
// nothing? not even a waist.
|
||||
@ -132,7 +134,7 @@ func IsThinWaist(m Multiaddr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if p[0].Code != P_IP4 && p[0].Code != P_IP6 {
|
||||
if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -142,7 +144,7 @@ func IsThinWaist(m Multiaddr) bool {
|
||||
}
|
||||
|
||||
switch p[1].Code {
|
||||
case P_TCP, P_UDP, P_IP4, P_IP6:
|
||||
case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6:
|
||||
return true
|
||||
default:
|
||||
return false
|
@ -1,11 +1,13 @@
|
||||
package multiaddr
|
||||
package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
ma "github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
type GenFunc func() (Multiaddr, error)
|
||||
type GenFunc func() (ma.Multiaddr, error)
|
||||
|
||||
func testConvert(t *testing.T, s string, gen GenFunc) {
|
||||
m, err := gen()
|
||||
@ -19,7 +21,7 @@ func testConvert(t *testing.T, s string, gen GenFunc) {
|
||||
}
|
||||
|
||||
func testToNetAddr(t *testing.T, maddr, ntwk, addr string) {
|
||||
m, err := NewMultiaddr(maddr)
|
||||
m, err := ma.NewMultiaddr(maddr)
|
||||
if err != nil {
|
||||
t.Fatal("failed to generate.")
|
||||
}
|
||||
@ -57,19 +59,19 @@ func testToNetAddr(t *testing.T, maddr, ntwk, addr string) {
|
||||
}
|
||||
|
||||
func TestFromIP4(t *testing.T) {
|
||||
testConvert(t, "/ip4/10.20.30.40", func() (Multiaddr, error) {
|
||||
testConvert(t, "/ip4/10.20.30.40", func() (ma.Multiaddr, error) {
|
||||
return FromIP(net.ParseIP("10.20.30.40"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFromIP6(t *testing.T) {
|
||||
testConvert(t, "/ip6/2001:4860:0:2001::68", func() (Multiaddr, error) {
|
||||
testConvert(t, "/ip6/2001:4860:0:2001::68", func() (ma.Multiaddr, error) {
|
||||
return FromIP(net.ParseIP("2001:4860:0:2001::68"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFromTCP(t *testing.T) {
|
||||
testConvert(t, "/ip4/10.20.30.40/tcp/1234", func() (Multiaddr, error) {
|
||||
testConvert(t, "/ip4/10.20.30.40/tcp/1234", func() (ma.Multiaddr, error) {
|
||||
return FromNetAddr(&net.TCPAddr{
|
||||
IP: net.ParseIP("10.20.30.40"),
|
||||
Port: 1234,
|
||||
@ -78,7 +80,7 @@ func TestFromTCP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFromUDP(t *testing.T) {
|
||||
testConvert(t, "/ip4/10.20.30.40/udp/1234", func() (Multiaddr, error) {
|
||||
testConvert(t, "/ip4/10.20.30.40/udp/1234", func() (ma.Multiaddr, error) {
|
||||
return FromNetAddr(&net.UDPAddr{
|
||||
IP: net.ParseIP("10.20.30.40"),
|
||||
Port: 1234,
|
||||
@ -103,19 +105,19 @@ func TestThinWaist(t *testing.T) {
|
||||
}
|
||||
|
||||
for a, res := range addrs {
|
||||
ma, err := NewMultiaddr(a)
|
||||
m, err := ma.NewMultiaddr(a)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct Multiaddr: %s", a)
|
||||
}
|
||||
|
||||
if IsThinWaist(ma) != res {
|
||||
if IsThinWaist(m) != res {
|
||||
t.Fatalf("IsThinWaist(%s) != %v", a, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDialArgs(t *testing.T) {
|
||||
m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
m, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
if err != nil {
|
||||
t.Fatal("failed to construct", "/ip4/127.0.0.1/udp/1234")
|
||||
}
|
5
net/doc.go
Normal file
5
net/doc.go
Normal file
@ -0,0 +1,5 @@
|
||||
// Package net provides Multiaddr specific versions of common
|
||||
// functions in stdlib's net package. This means wrappers of
|
||||
// standard net symbols like net.Dial and net.Listen, as well
|
||||
// as conversion to/from net.Addr.
|
||||
package net
|
218
net/net.go
Normal file
218
net/net.go
Normal file
@ -0,0 +1,218 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
ma "github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
// Conn is the equivalent of a net.Conn object. It is the
|
||||
// result of calling the Dial or Listen functions in this
|
||||
// package, with associated local and remote Multiaddrs.
|
||||
type Conn interface {
|
||||
net.Conn
|
||||
|
||||
// LocalMultiaddr returns the local Multiaddr associated
|
||||
// with this connection
|
||||
LocalMultiaddr() ma.Multiaddr
|
||||
|
||||
// RemoteMultiaddr returns the remote Multiaddr associated
|
||||
// with this connection
|
||||
RemoteMultiaddr() ma.Multiaddr
|
||||
}
|
||||
|
||||
// WrapNetConn wraps a net.Conn object with a Multiaddr
|
||||
// friendly Conn.
|
||||
func WrapNetConn(nconn net.Conn) (Conn, error) {
|
||||
|
||||
laddr, err := FromNetAddr(nconn.LocalAddr())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err)
|
||||
}
|
||||
|
||||
raddr, err := FromNetAddr(nconn.RemoteAddr())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err)
|
||||
}
|
||||
|
||||
return &maConn{
|
||||
Conn: nconn,
|
||||
laddr: laddr,
|
||||
raddr: raddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// maConn implements the Conn interface. It's a thin wrapper
|
||||
// around a net.Conn
|
||||
type maConn struct {
|
||||
net.Conn
|
||||
laddr ma.Multiaddr
|
||||
raddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// LocalMultiaddr returns the local address associated with
|
||||
// this connection
|
||||
func (c *maConn) LocalMultiaddr() ma.Multiaddr {
|
||||
return c.laddr
|
||||
}
|
||||
|
||||
// RemoteMultiaddr returns the remote address associated with
|
||||
// this connection
|
||||
func (c *maConn) RemoteMultiaddr() ma.Multiaddr {
|
||||
return c.raddr
|
||||
}
|
||||
|
||||
// Dialer contains options for connecting to an address. It
|
||||
// is effectively the same as net.Dialer, but its LocalAddr
|
||||
// and RemoteAddr options are Multiaddrs, instead of net.Addrs.
|
||||
type Dialer struct {
|
||||
|
||||
// Dialer is just an embed net.Dialer, with all its options.
|
||||
net.Dialer
|
||||
|
||||
// LocalAddr is the local address to use when dialing an
|
||||
// address. The address must be of a compatible type for the
|
||||
// network being dialed.
|
||||
// If nil, a local address is automatically chosen.
|
||||
LocalAddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// Dial connects to a remote address, using the options of the
|
||||
// Dialer. Dialer uses an underlying net.Dialer to Dial a
|
||||
// net.Conn, then wraps that in a Conn object (with local and
|
||||
// remote Multiaddrs).
|
||||
func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {
|
||||
|
||||
// if a LocalAddr is specified, use it on the embedded dialer.
|
||||
if d.LocalAddr != nil {
|
||||
// convert our multiaddr to net.Addr friendly
|
||||
naddr, err := ToNetAddr(d.LocalAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set the dialer's LocalAddr as naddr
|
||||
d.Dialer.LocalAddr = naddr
|
||||
}
|
||||
|
||||
// get the net.Dial friendly arguments from the remote addr
|
||||
rnet, rnaddr, err := DialArgs(remote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ok, Dial!
|
||||
nconn, err := d.Dialer.Dial(rnet, rnaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get local address (pre-specified or assigned within net.Conn)
|
||||
local := d.LocalAddr
|
||||
if local == nil {
|
||||
local, err = FromNetAddr(nconn.LocalAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &maConn{
|
||||
Conn: nconn,
|
||||
laddr: local,
|
||||
raddr: remote,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Dial connects to a remote address. It uses an underlying net.Conn,
|
||||
// then wraps it in a Conn object (with local and remote Multiaddrs).
|
||||
func Dial(remote ma.Multiaddr) (Conn, error) {
|
||||
return (&Dialer{}).Dial(remote)
|
||||
}
|
||||
|
||||
// A Listener is a generic network listener for stream-oriented protocols.
|
||||
// it uses an embedded net.Listener, overriding net.Listener.Accept to
|
||||
// return a Conn and providing Multiaddr.
|
||||
type Listener interface {
|
||||
|
||||
// NetListener returns the embedded net.Listener. Use with caution.
|
||||
NetListener() net.Listener
|
||||
|
||||
// Accept waits for and returns the next connection to the listener.
|
||||
// Returns a Multiaddr friendly Conn
|
||||
Accept() (Conn, error)
|
||||
|
||||
// Close closes the listener.
|
||||
// Any blocked Accept operations will be unblocked and return errors.
|
||||
Close() error
|
||||
|
||||
// Multiaddr returns the listener's (local) Multiaddr.
|
||||
Multiaddr() ma.Multiaddr
|
||||
|
||||
// Addr returns the net.Listener's network address.
|
||||
Addr() net.Addr
|
||||
}
|
||||
|
||||
// maListener implements Listener
|
||||
type maListener struct {
|
||||
net.Listener
|
||||
laddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// NetListener returns the embedded net.Listener. Use with caution.
|
||||
func (l *maListener) NetListener() net.Listener {
|
||||
return l.Listener
|
||||
}
|
||||
|
||||
// Accept waits for and returns the next connection to the listener.
|
||||
// Returns a Multiaddr friendly Conn
|
||||
func (l *maListener) Accept() (Conn, error) {
|
||||
nconn, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
raddr, err := FromNetAddr(nconn.RemoteAddr())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert connn.RemoteAddr: %s", err)
|
||||
}
|
||||
|
||||
return &maConn{
|
||||
Conn: nconn,
|
||||
laddr: l.laddr,
|
||||
raddr: raddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Multiaddr returns the listener's (local) Multiaddr.
|
||||
func (l *maListener) Multiaddr() ma.Multiaddr {
|
||||
return l.laddr
|
||||
}
|
||||
|
||||
// Addr returns the listener's network address.
|
||||
func (l *maListener) Addr() net.Addr {
|
||||
return l.Listener.Addr()
|
||||
}
|
||||
|
||||
// Listen announces on the local network address laddr.
|
||||
// The Multiaddr must be a "ThinWaist" stream-oriented network:
|
||||
// ip4/tcp, ip6/tcp, (TODO: unix, unixpacket)
|
||||
// See Dial for the syntax of laddr.
|
||||
func Listen(laddr ma.Multiaddr) (Listener, error) {
|
||||
|
||||
// get the net.Listen friendly arguments from the remote addr
|
||||
lnet, lnaddr, err := DialArgs(laddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nl, err := net.Listen(lnet, lnaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &maListener{
|
||||
Listener: nl,
|
||||
laddr: laddr,
|
||||
}, nil
|
||||
}
|
200
net/net_test.go
Normal file
200
net/net_test.go
Normal file
@ -0,0 +1,200 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
ma "github.com/jbenet/go-multiaddr"
|
||||
)
|
||||
|
||||
func newMultiaddr(t *testing.T, m string) ma.Multiaddr {
|
||||
maddr, err := ma.NewMultiaddr(m)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct multiaddr: %s", m)
|
||||
}
|
||||
return maddr
|
||||
}
|
||||
|
||||
func TestDial(t *testing.T) {
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:4321")
|
||||
if err != nil {
|
||||
t.Fatal("failed to listen")
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
||||
cB, err := listener.Accept()
|
||||
if err != nil {
|
||||
t.Fatal("failed to accept")
|
||||
}
|
||||
|
||||
// echo out
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
_, err := cB.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
cB.Write(buf)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4321")
|
||||
cA, err := Dial(maddr)
|
||||
if err != nil {
|
||||
t.Fatal("failed to dial")
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
if _, err := cA.Write([]byte("beep boop")); err != nil {
|
||||
t.Fatal("failed to write:", err)
|
||||
}
|
||||
|
||||
if _, err := cA.Read(buf); err != nil {
|
||||
t.Fatal("failed to read:", buf, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(buf[:9], []byte("beep boop")) {
|
||||
t.Fatal("failed to echo:", buf)
|
||||
}
|
||||
|
||||
maddr2 := cA.RemoteMultiaddr()
|
||||
if !maddr2.Equal(maddr) {
|
||||
t.Fatal("remote multiaddr not equal:", maddr, maddr2)
|
||||
}
|
||||
|
||||
cA.Close()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestListen(t *testing.T) {
|
||||
|
||||
maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4322")
|
||||
listener, err := Listen(maddr)
|
||||
if err != nil {
|
||||
t.Fatal("failed to listen")
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
||||
cB, err := listener.Accept()
|
||||
if err != nil {
|
||||
t.Fatal("failed to accept")
|
||||
}
|
||||
|
||||
if !cB.LocalMultiaddr().Equal(maddr) {
|
||||
t.Fatal("local multiaddr not equal:", maddr, cB.LocalMultiaddr())
|
||||
}
|
||||
|
||||
// echo out
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
_, err := cB.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
cB.Write(buf)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
cA, err := net.Dial("tcp", "127.0.0.1:4322")
|
||||
if err != nil {
|
||||
t.Fatal("failed to dial")
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
if _, err := cA.Write([]byte("beep boop")); err != nil {
|
||||
t.Fatal("failed to write:", err)
|
||||
}
|
||||
|
||||
if _, err := cA.Read(buf); err != nil {
|
||||
t.Fatal("failed to read:", buf, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(buf[:9], []byte("beep boop")) {
|
||||
t.Fatal("failed to echo:", buf)
|
||||
}
|
||||
|
||||
maddr2, err := FromNetAddr(cA.RemoteAddr())
|
||||
if err != nil {
|
||||
t.Fatal("failed to convert", err)
|
||||
}
|
||||
if !maddr2.Equal(maddr) {
|
||||
t.Fatal("remote multiaddr not equal:", maddr, maddr2)
|
||||
}
|
||||
|
||||
cA.Close()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestListenAndDial(t *testing.T) {
|
||||
|
||||
maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4323")
|
||||
listener, err := Listen(maddr)
|
||||
if err != nil {
|
||||
t.Fatal("failed to listen")
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
||||
cB, err := listener.Accept()
|
||||
if err != nil {
|
||||
t.Fatal("failed to accept")
|
||||
}
|
||||
|
||||
if !cB.LocalMultiaddr().Equal(maddr) {
|
||||
t.Fatal("local multiaddr not equal:", maddr, cB.LocalMultiaddr())
|
||||
}
|
||||
|
||||
// echo out
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
_, err := cB.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
cB.Write(buf)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
cA, err := Dial(newMultiaddr(t, "/ip4/127.0.0.1/tcp/4323"))
|
||||
if err != nil {
|
||||
t.Fatal("failed to dial")
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
if _, err := cA.Write([]byte("beep boop")); err != nil {
|
||||
t.Fatal("failed to write:", err)
|
||||
}
|
||||
|
||||
if _, err := cA.Read(buf); err != nil {
|
||||
t.Fatal("failed to read:", buf, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(buf[:9], []byte("beep boop")) {
|
||||
t.Fatal("failed to echo:", buf)
|
||||
}
|
||||
|
||||
maddr2 := cA.RemoteMultiaddr()
|
||||
if !maddr2.Equal(maddr) {
|
||||
t.Fatal("remote multiaddr not equal:", maddr, maddr2)
|
||||
}
|
||||
|
||||
cA.Close()
|
||||
wg.Wait()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user