mirror of
https://github.com/logos-messaging/go-multiaddr.git
synced 2026-05-21 16:59:25 +00:00
separated into subrepo
This commit is contained in:
parent
1e1562564d
commit
99cf3edc71
@ -1,96 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
ma "github.com/jbenet/go-multiaddr"
|
|
||||||
manet "github.com/jbenet/go-multiaddr/net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// flags
|
|
||||||
var formats = []string{"string", "bytes", "hex", "slice"}
|
|
||||||
var format string
|
|
||||||
var hideLoopback bool
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: %s [<multiaddr>]\n\nFlags:\n", os.Args[0])
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
usage := fmt.Sprintf("output format, one of: %v", formats)
|
|
||||||
flag.StringVar(&format, "format", "string", usage)
|
|
||||||
flag.StringVar(&format, "f", "string", usage+" (shorthand)")
|
|
||||||
flag.BoolVar(&hideLoopback, "hide-loopback", false, "do not display loopback addresses")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
args := flag.Args()
|
|
||||||
if len(args) == 0 {
|
|
||||||
output(localAddresses()...)
|
|
||||||
} else {
|
|
||||||
output(address(args[0]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func localAddresses() []ma.Multiaddr {
|
|
||||||
maddrs, err := manet.InterfaceMultiaddrs()
|
|
||||||
if err != nil {
|
|
||||||
die(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hideLoopback {
|
|
||||||
return maddrs
|
|
||||||
}
|
|
||||||
|
|
||||||
var maddrs2 []ma.Multiaddr
|
|
||||||
for _, a := range maddrs {
|
|
||||||
if !manet.IsIPLoopback(a) {
|
|
||||||
maddrs2 = append(maddrs2, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maddrs2
|
|
||||||
}
|
|
||||||
|
|
||||||
func address(addr string) ma.Multiaddr {
|
|
||||||
m, err := ma.NewMultiaddr(addr)
|
|
||||||
if err != nil {
|
|
||||||
die(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func output(ms ...ma.Multiaddr) {
|
|
||||||
for _, m := range ms {
|
|
||||||
fmt.Println(outfmt(m))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func outfmt(m ma.Multiaddr) string {
|
|
||||||
switch format {
|
|
||||||
case "string":
|
|
||||||
return m.String()
|
|
||||||
case "slice":
|
|
||||||
return fmt.Sprintf("%v", m.Bytes())
|
|
||||||
case "bytes":
|
|
||||||
return string(m.Bytes())
|
|
||||||
case "hex":
|
|
||||||
return "0x" + hex.EncodeToString(m.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
die("error: invalid format", format)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func die(v ...interface{}) {
|
|
||||||
fmt.Fprint(os.Stderr, v...)
|
|
||||||
fmt.Fprint(os.Stderr, "\n")
|
|
||||||
flag.Usage()
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
# 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
|
|
||||||
165
net/convert.go
165
net/convert.go
@ -1,165 +0,0 @@
|
|||||||
package manet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
utp "github.com/h2so5/utp"
|
|
||||||
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) (ma.Multiaddr, error) {
|
|
||||||
switch a.Network() {
|
|
||||||
case "tcp", "tcp4", "tcp6":
|
|
||||||
ac, ok := a.(*net.TCPAddr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get IP Addr
|
|
||||||
ipm, err := FromIP(ac.IP)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get TCP Addr
|
|
||||||
tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encapsulate
|
|
||||||
return ipm.Encapsulate(tcpm), nil
|
|
||||||
|
|
||||||
case "udp", "upd4", "udp6":
|
|
||||||
ac, ok := a.(*net.UDPAddr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get IP Addr
|
|
||||||
ipm, err := FromIP(ac.IP)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get UDP Addr
|
|
||||||
udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encapsulate
|
|
||||||
return ipm.Encapsulate(udpm), nil
|
|
||||||
|
|
||||||
case "utp", "utp4", "utp6":
|
|
||||||
acc, ok := a.(*utp.UTPAddr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get UDP Addr
|
|
||||||
ac, ok := acc.Addr.(*net.UDPAddr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get IP Addr
|
|
||||||
ipm, err := FromIP(ac.IP)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get UDP Addr
|
|
||||||
utpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d/utp", ac.Port))
|
|
||||||
if err != nil {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encapsulate
|
|
||||||
return ipm.Encapsulate(utpm), nil
|
|
||||||
|
|
||||||
case "ip", "ip4", "ip6":
|
|
||||||
ac, ok := a.(*net.IPAddr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
return FromIP(ac.IP)
|
|
||||||
|
|
||||||
case "ip+net":
|
|
||||||
ac, ok := a.(*net.IPNet)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
return FromIP(ac.IP)
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown network %v", a.Network())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToNetAddr converts a Multiaddr to a net.Addr
|
|
||||||
// Must be ThinWaist. acceptable protocol stacks are:
|
|
||||||
// /ip{4,6}/{tcp, udp}
|
|
||||||
func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
|
||||||
network, host, err := DialArgs(maddr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch network {
|
|
||||||
case "tcp":
|
|
||||||
return net.ResolveTCPAddr(network, host)
|
|
||||||
case "udp":
|
|
||||||
return net.ResolveUDPAddr(network, host)
|
|
||||||
case "utp":
|
|
||||||
return utp.ResolveUTPAddr(network, host)
|
|
||||||
case "ip":
|
|
||||||
return net.ResolveIPAddr(network, host)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("network not supported: %s", network)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromIP converts a net.IP type to a Multiaddr.
|
|
||||||
func FromIP(ip net.IP) (ma.Multiaddr, error) {
|
|
||||||
switch {
|
|
||||||
case ip.To4() != nil:
|
|
||||||
return ma.NewMultiaddr("/ip4/" + ip.String())
|
|
||||||
case ip.To16() != nil:
|
|
||||||
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 ma.Multiaddr) (string, string, error) {
|
|
||||||
if !IsThinWaist(m) {
|
|
||||||
return "", "", fmt.Errorf("%s is not a 'thin waist' address", m)
|
|
||||||
}
|
|
||||||
|
|
||||||
str := m.String()
|
|
||||||
parts := strings.Split(str, "/")[1:]
|
|
||||||
|
|
||||||
if len(parts) == 2 { // only IP
|
|
||||||
return parts[0], parts[1], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
network := parts[2]
|
|
||||||
if parts[2] == "udp" && len(parts) > 4 && parts[4] == "utp" {
|
|
||||||
network = parts[4]
|
|
||||||
}
|
|
||||||
var host string
|
|
||||||
switch parts[0] {
|
|
||||||
case "ip4":
|
|
||||||
host = strings.Join([]string{parts[1], parts[3]}, ":")
|
|
||||||
case "ip6":
|
|
||||||
host = fmt.Sprintf("[%s]:%s", parts[1], parts[3])
|
|
||||||
}
|
|
||||||
return network, host, nil
|
|
||||||
}
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
package manet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
utp "github.com/h2so5/utp"
|
|
||||||
ma "github.com/jbenet/go-multiaddr"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GenFunc func() (ma.Multiaddr, error)
|
|
||||||
|
|
||||||
func testConvert(t *testing.T, s string, gen GenFunc) {
|
|
||||||
m, err := gen()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to generate.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if s2 := m.String(); err != nil || s2 != s {
|
|
||||||
t.Fatal("failed to convert: " + s + " != " + s2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testToNetAddr(t *testing.T, maddr, ntwk, addr string) {
|
|
||||||
m, err := ma.NewMultiaddr(maddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to generate.")
|
|
||||||
}
|
|
||||||
|
|
||||||
naddr, err := ToNetAddr(m)
|
|
||||||
if addr == "" { // should fail
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("failed to error: %s", m)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// shouldn't fail
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to convert to net addr: %s", m)
|
|
||||||
}
|
|
||||||
|
|
||||||
if naddr.String() != addr {
|
|
||||||
t.Fatalf("naddr.Address() == %s != %s", naddr, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if naddr.Network() != ntwk {
|
|
||||||
t.Fatalf("naddr.Network() == %s != %s", naddr.Network(), ntwk)
|
|
||||||
}
|
|
||||||
|
|
||||||
// should convert properly
|
|
||||||
switch ntwk {
|
|
||||||
case "tcp":
|
|
||||||
_ = naddr.(*net.TCPAddr)
|
|
||||||
case "udp":
|
|
||||||
_ = naddr.(*net.UDPAddr)
|
|
||||||
case "ip":
|
|
||||||
_ = naddr.(*net.IPAddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromIP4(t *testing.T) {
|
|
||||||
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() (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() (ma.Multiaddr, error) {
|
|
||||||
return FromNetAddr(&net.TCPAddr{
|
|
||||||
IP: net.ParseIP("10.20.30.40"),
|
|
||||||
Port: 1234,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromUDP(t *testing.T) {
|
|
||||||
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,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromUTP(t *testing.T) {
|
|
||||||
testConvert(t, "/ip4/10.20.30.40/udp/1234/utp", func() (ma.Multiaddr, error) {
|
|
||||||
return FromNetAddr(&utp.UTPAddr{
|
|
||||||
Addr: &net.UDPAddr{
|
|
||||||
IP: net.ParseIP("10.20.30.40"),
|
|
||||||
Port: 1234,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThinWaist(t *testing.T) {
|
|
||||||
addrs := map[string]bool{
|
|
||||||
"/ip4/127.0.0.1/udp/1234": true,
|
|
||||||
"/ip4/127.0.0.1/tcp/1234": true,
|
|
||||||
"/ip4/127.0.0.1/udp/1234/utp": true,
|
|
||||||
"/ip4/127.0.0.1/udp/1234/tcp/1234": true,
|
|
||||||
"/ip4/127.0.0.1/tcp/12345/ip4/1.2.3.4": true,
|
|
||||||
"/ip6/::1/tcp/80": true,
|
|
||||||
"/ip6/::1/udp/80": true,
|
|
||||||
"/ip6/::1": true,
|
|
||||||
"/ip6/::1/utp": false,
|
|
||||||
"/tcp/1234/ip4/1.2.3.4": false,
|
|
||||||
"/tcp/1234": false,
|
|
||||||
"/tcp/1234/utp": false,
|
|
||||||
"/tcp/1234/udp/1234": false,
|
|
||||||
"/ip4/1.2.3.4/ip4/2.3.4.5": true,
|
|
||||||
"/ip6/::1/ip4/2.3.4.5": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
for a, res := range addrs {
|
|
||||||
m, err := ma.NewMultiaddr(a)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to construct Multiaddr: %s", a)
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsThinWaist(m) != res {
|
|
||||||
t.Fatalf("IsThinWaist(%s) != %v", a, res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDialArgs(t *testing.T) {
|
|
||||||
test := func(e_maddr, e_nw, e_host string) {
|
|
||||||
m, err := ma.NewMultiaddr(e_maddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to construct", "/ip4/127.0.0.1/udp/1234", e_maddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
nw, host, err := DialArgs(m)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to get dial args", e_maddr, m, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if nw != e_nw {
|
|
||||||
t.Error("failed to get udp network Dial Arg", e_nw, nw)
|
|
||||||
}
|
|
||||||
|
|
||||||
if host != e_host {
|
|
||||||
t.Error("failed to get host:port Dial Arg", e_host, host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test("/ip4/127.0.0.1/udp/1234", "udp", "127.0.0.1:1234")
|
|
||||||
test("/ip4/127.0.0.1/tcp/4321", "tcp", "127.0.0.1:4321")
|
|
||||||
test("/ip4/127.0.0.1/udp/1234/utp", "utp", "127.0.0.1:1234")
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
// Package manet 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 manet
|
|
||||||
76
net/ip.go
76
net/ip.go
@ -1,76 +0,0 @@
|
|||||||
package manet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
ma "github.com/jbenet/go-multiaddr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Loopback Addresses
|
|
||||||
var (
|
|
||||||
// IP4Loopback is the ip4 loopback multiaddr
|
|
||||||
IP4Loopback = ma.StringCast("/ip4/127.0.0.1")
|
|
||||||
|
|
||||||
// IP6Loopback is the ip6 loopback multiaddr
|
|
||||||
IP6Loopback = ma.StringCast("/ip6/::1")
|
|
||||||
|
|
||||||
// IP6LinkLocalLoopback is the ip6 link-local loopback multiaddr
|
|
||||||
IP6LinkLocalLoopback = ma.StringCast("/ip6/fe80::1")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unspecified Addresses (used for )
|
|
||||||
var (
|
|
||||||
IP4Unspecified = ma.StringCast("/ip4/0.0.0.0")
|
|
||||||
IP6Unspecified = ma.StringCast("/ip6/::")
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols.
|
|
||||||
// This means: /{IP4, IP6}[/{TCP, UDP}]
|
|
||||||
func IsThinWaist(m ma.Multiaddr) bool {
|
|
||||||
p := m.Protocols()
|
|
||||||
|
|
||||||
// nothing? not even a waist.
|
|
||||||
if len(p) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// only IP? still counts.
|
|
||||||
if len(p) == 1 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p[1].Code {
|
|
||||||
case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsIPLoopback returns whether a Multiaddr is a "Loopback" IP address
|
|
||||||
// This means either /ip4/127.0.0.1 or /ip6/::1
|
|
||||||
func IsIPLoopback(m ma.Multiaddr) bool {
|
|
||||||
b := m.Bytes()
|
|
||||||
|
|
||||||
// /ip4/127 prefix (_entire_ /8 is loopback...)
|
|
||||||
if bytes.HasPrefix(b, []byte{4, 127}) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// /ip6/::1
|
|
||||||
if IP6Loopback.Equal(m) || IP6LinkLocalLoopback.Equal(m) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address
|
|
||||||
// This means either /ip4/0.0.0.0 or /ip6/::
|
|
||||||
func IsIPUnspecified(m ma.Multiaddr) bool {
|
|
||||||
return IP4Unspecified.Equal(m) || IP6Unspecified.Equal(m)
|
|
||||||
}
|
|
||||||
235
net/net.go
235
net/net.go
@ -1,235 +0,0 @@
|
|||||||
package manet
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs
|
|
||||||
func InterfaceMultiaddrs() ([]ma.Multiaddr, error) {
|
|
||||||
addrs, err := net.InterfaceAddrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
maddrs := make([]ma.Multiaddr, len(addrs))
|
|
||||||
for i, a := range addrs {
|
|
||||||
maddrs[i], err = FromNetAddr(a)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maddrs, nil
|
|
||||||
}
|
|
||||||
244
net/net_test.go
244
net/net_test.go
@ -1,244 +0,0 @@
|
|||||||
package manet
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPLoopback(t *testing.T) {
|
|
||||||
if IP4Loopback.String() != "/ip4/127.0.0.1" {
|
|
||||||
t.Error("IP4Loopback incorrect:", IP4Loopback)
|
|
||||||
}
|
|
||||||
|
|
||||||
if IP6Loopback.String() != "/ip6/::1" {
|
|
||||||
t.Error("IP6Loopback incorrect:", IP6Loopback)
|
|
||||||
}
|
|
||||||
|
|
||||||
if IP6LinkLocalLoopback.String() != "/ip6/fe80::1" {
|
|
||||||
t.Error("IP6LinkLocalLoopback incorrect:", IP6Loopback)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsIPLoopback(IP4Loopback) {
|
|
||||||
t.Error("IsIPLoopback failed (IP4Loopback)")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsIPLoopback(IP6Loopback) {
|
|
||||||
t.Error("IsIPLoopback failed (IP6Loopback)")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsIPLoopback(IP6LinkLocalLoopback) {
|
|
||||||
t.Error("IsIPLoopback failed (IP6LinkLocalLoopback)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPUnspecified(t *testing.T) {
|
|
||||||
if IP4Unspecified.String() != "/ip4/0.0.0.0" {
|
|
||||||
t.Error("IP4Unspecified incorrect:", IP4Unspecified)
|
|
||||||
}
|
|
||||||
|
|
||||||
if IP6Unspecified.String() != "/ip6/::" {
|
|
||||||
t.Error("IP6Unspecified incorrect:", IP6Unspecified)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsIPUnspecified(IP4Unspecified) {
|
|
||||||
t.Error("IsIPUnspecified failed (IP4Unspecified)")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsIPUnspecified(IP6Unspecified) {
|
|
||||||
t.Error("IsIPUnspecified failed (IP6Unspecified)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user