mirror of
https://github.com/waku-org/go-multiaddr.git
synced 2025-02-23 19:48:18 +00:00
make multiaddr-net more pluggable
This commit is contained in:
parent
f1f304d1e0
commit
347065ffd7
260
convert.go
260
convert.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
ma "github.com/jbenet/go-multiaddr"
|
ma "github.com/jbenet/go-multiaddr"
|
||||||
utp "github.com/jbenet/go-multiaddr-net/utp"
|
utp "github.com/jbenet/go-multiaddr-net/utp"
|
||||||
@ -11,105 +12,190 @@ import (
|
|||||||
|
|
||||||
var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
|
var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
|
||||||
|
|
||||||
|
type AddrParser func(a net.Addr) (ma.Multiaddr, error)
|
||||||
|
type MaddrParser func(ma ma.Multiaddr) (net.Addr, error)
|
||||||
|
|
||||||
|
var maddrParsers map[string]MaddrParser
|
||||||
|
var addrParsers map[string]AddrParser
|
||||||
|
var addrParsersLock sync.Mutex
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
addrParsers = make(map[string]AddrParser)
|
||||||
|
maddrParsers = make(map[string]MaddrParser)
|
||||||
|
|
||||||
|
registerDefaultAddrParsers()
|
||||||
|
registerDefaultMaddrParsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerDefaultAddrParsers() {
|
||||||
|
funcs := map[string]AddrParser{
|
||||||
|
"tcp": ParseTcpNetAddr,
|
||||||
|
"udp": ParseUdpNetAddr,
|
||||||
|
"utp": ParseUtpNetAddr,
|
||||||
|
"ip": ParseIpNetAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range funcs {
|
||||||
|
addrParsers[k] = v
|
||||||
|
addrParsers[k+"4"] = v
|
||||||
|
addrParsers[k+"6"] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
addrParsers["ip+net"] = ParseIpPlusNetAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterAddressType(netname, maname string, ap AddrParser, mp MaddrParser) {
|
||||||
|
addrParsersLock.Lock()
|
||||||
|
defer addrParsersLock.Unlock()
|
||||||
|
addrParsers[netname] = ap
|
||||||
|
maddrParsers[maname] = mp
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseTcpNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseUdpNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseUtpNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
|
acc, ok := a.(*utp.Addr)
|
||||||
|
if !ok {
|
||||||
|
return nil, errIncorrectNetAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get UDP Addr
|
||||||
|
ac, ok := acc.Child().(*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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseIpNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
|
ac, ok := a.(*net.IPAddr)
|
||||||
|
if !ok {
|
||||||
|
return nil, errIncorrectNetAddr
|
||||||
|
}
|
||||||
|
return FromIP(ac.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseIpPlusNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
|
ac, ok := a.(*net.IPNet)
|
||||||
|
if !ok {
|
||||||
|
return nil, errIncorrectNetAddr
|
||||||
|
}
|
||||||
|
return FromIP(ac.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAddrParser(net string) (AddrParser, error) {
|
||||||
|
addrParsersLock.Lock()
|
||||||
|
defer addrParsersLock.Unlock()
|
||||||
|
|
||||||
|
parser, ok := addrParsers[net]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown network %v", net)
|
||||||
|
}
|
||||||
|
return parser, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FromNetAddr converts a net.Addr type to a Multiaddr.
|
// FromNetAddr converts a net.Addr type to a Multiaddr.
|
||||||
func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return nil, fmt.Errorf("nil multiaddr")
|
return nil, fmt.Errorf("nil multiaddr")
|
||||||
}
|
}
|
||||||
|
p, err := getAddrParser(a.Network())
|
||||||
switch a.Network() {
|
if err != nil {
|
||||||
case "tcp", "tcp4", "tcp6":
|
return nil, err
|
||||||
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.Addr)
|
|
||||||
if !ok {
|
|
||||||
return nil, errIncorrectNetAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get UDP Addr
|
|
||||||
ac, ok := acc.Child().(*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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaddrParser(name string) (MaddrParser, error) {
|
||||||
|
addrParsersLock.Lock()
|
||||||
|
defer addrParsersLock.Unlock()
|
||||||
|
p, ok := maddrParsers[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("network not supported: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToNetAddr converts a Multiaddr to a net.Addr
|
// ToNetAddr converts a Multiaddr to a net.Addr
|
||||||
// Must be ThinWaist. acceptable protocol stacks are:
|
// Must be ThinWaist. acceptable protocol stacks are:
|
||||||
// /ip{4,6}/{tcp, udp}
|
// /ip{4,6}/{tcp, udp}
|
||||||
func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||||
|
protos := maddr.Protocols()
|
||||||
|
final := protos[len(protos)-1]
|
||||||
|
|
||||||
|
p, err := getMaddrParser(final.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p(maddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerDefaultMaddrParsers() {
|
||||||
|
for _, net := range []string{"tcp", "udp", "utp", "ip", "ip4", "ip6"} {
|
||||||
|
maddrParsers[net] = parseBasicNetAddr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBasicNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||||
network, host, err := DialArgs(maddr)
|
network, host, err := DialArgs(maddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user