mirror of
https://github.com/waku-org/go-multiaddr.git
synced 2025-02-23 19:48:18 +00:00
basic net package (no tests yet)
Implements: - Conn - Dial, Dialer - Listen, Listener
This commit is contained in:
parent
7d1a12d59b
commit
83543fff5d
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
|
||||||
|
}
|
1
net/net_test.go
Normal file
1
net/net_test.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package net
|
Loading…
x
Reference in New Issue
Block a user