From 347065ffd7b33950490f0c99841abd52505e0ee6 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 2 May 2016 16:30:02 -0700 Subject: [PATCH 1/5] make multiaddr-net more pluggable --- convert.go | 260 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 173 insertions(+), 87 deletions(-) diff --git a/convert.go b/convert.go index 50c6fff..8e05842 100644 --- a/convert.go +++ b/convert.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "strings" + "sync" ma "github.com/jbenet/go-multiaddr" utp "github.com/jbenet/go-multiaddr-net/utp" @@ -11,105 +12,190 @@ import ( 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. func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { if a == nil { return nil, fmt.Errorf("nil multiaddr") } - - 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.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()) + p, err := getAddrParser(a.Network()) + if err != nil { + return nil, err } + + 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 // Must be ThinWaist. acceptable protocol stacks are: // /ip{4,6}/{tcp, udp} 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) if err != nil { return nil, err From 12630644161fc56371ffea28a12f40b6ba96ee49 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 3 May 2016 13:23:57 -0700 Subject: [PATCH 2/5] clean up parser registry --- convert.go | 246 +++++++++++++++++++--------------------------------- registry.go | 68 +++++++++++++++ 2 files changed, 157 insertions(+), 157 deletions(-) create mode 100644 registry.go diff --git a/convert.go b/convert.go index 8e05842..f8ff71d 100644 --- a/convert.go +++ b/convert.go @@ -4,7 +4,6 @@ import ( "fmt" "net" "strings" - "sync" ma "github.com/jbenet/go-multiaddr" utp "github.com/jbenet/go-multiaddr-net/utp" @@ -12,144 +11,6 @@ import ( 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. func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { if a == nil { @@ -163,17 +24,6 @@ func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { 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 // Must be ThinWaist. acceptable protocol stacks are: // /ip{4,6}/{tcp, udp} @@ -189,13 +39,7 @@ func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { 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) { +func parseBasicNetMaddr(maddr ma.Multiaddr) (net.Addr, error) { network, host, err := DialArgs(maddr) if err != nil { return nil, err @@ -256,3 +100,91 @@ func DialArgs(m ma.Multiaddr) (string, string, error) { } return network, host, nil } + +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) +} diff --git a/registry.go b/registry.go new file mode 100644 index 0000000..d3dde65 --- /dev/null +++ b/registry.go @@ -0,0 +1,68 @@ +package manet + +import ( + "fmt" + "net" + "sync" + + ma "github.com/jbenet/go-multiaddr" +) + +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 RegisterAddressType(netname, maname string, ap AddrParser, mp MaddrParser) { + addrParsersLock.Lock() + defer addrParsersLock.Unlock() + addrParsers[netname] = ap + maddrParsers[maname] = mp +} + +func init() { + addrParsers = make(map[string]AddrParser) + maddrParsers = make(map[string]MaddrParser) + + funcs := map[string]AddrParser{ + "tcp": parseTcpNetAddr, + "udp": parseUdpNetAddr, + "utp": parseUtpNetAddr, + } + + for k, v := range funcs { + RegisterAddressType(k, k, v, parseBasicNetMaddr) + RegisterAddressType(k+"4", k, v, parseBasicNetMaddr) + RegisterAddressType(k+"6", k, v, parseBasicNetMaddr) + } + + for _, i := range []string{"ip", "ip4", "ip6"} { + RegisterAddressType(i, i, parseIpNetAddr, parseBasicNetMaddr) + } + + addrParsers["ip+net"] = parseIpPlusNetAddr +} + +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 +} + +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 +} From 48f060edf78cb4954869d852bbf6e1a7811124f7 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 4 May 2016 14:09:13 -0700 Subject: [PATCH 3/5] refactor to use AddressSpec objects --- convert.go | 35 +++++++++++++++++++++++++++++++++++ registry.go | 47 +++++++++++++++++++++++++++++------------------ 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/convert.go b/convert.go index f8ff71d..a521e97 100644 --- a/convert.go +++ b/convert.go @@ -101,6 +101,13 @@ func DialArgs(m ma.Multiaddr) (string, string, error) { return network, host, nil } +var tcpAddrSpec = &AddressSpec{ + Key: "tcp", + NetNames: []string{"tcp", "tcp4", "tcp6"}, + ParseNetAddr: parseTcpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + func parseTcpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.TCPAddr) if !ok { @@ -123,6 +130,13 @@ func parseTcpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(tcpm), nil } +var udpAddrSpec = &AddressSpec{ + Key: "udp", + NetNames: []string{"udp", "udp4", "udp6"}, + ParseNetAddr: parseUdpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + func parseUdpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.UDPAddr) if !ok { @@ -145,6 +159,13 @@ func parseUdpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(udpm), nil } +var utpAddrSpec = &AddressSpec{ + Key: "utp", + NetNames: []string{"utp", "utp4", "utp6"}, + ParseNetAddr: parseUtpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + func parseUtpNetAddr(a net.Addr) (ma.Multiaddr, error) { acc, ok := a.(*utp.Addr) if !ok { @@ -173,6 +194,20 @@ func parseUtpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(utpm), nil } +var ip4AddrSpec = &AddressSpec{ + Key: "ip4", + NetNames: []string{"ip4"}, + ParseNetAddr: parseIpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + +var ip6AddrSpec = &AddressSpec{ + Key: "ip6", + NetNames: []string{"ip6"}, + ParseNetAddr: parseIpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + func parseIpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.IPAddr) if !ok { diff --git a/registry.go b/registry.go index d3dde65..57e6d98 100644 --- a/registry.go +++ b/registry.go @@ -15,32 +15,43 @@ var maddrParsers map[string]MaddrParser var addrParsers map[string]AddrParser var addrParsersLock sync.Mutex -func RegisterAddressType(netname, maname string, ap AddrParser, mp MaddrParser) { +type AddressSpec struct { + // NetNames is an array of strings that may be returned + // by net.Addr.Network() calls on addresses belonging to this type + NetNames []string + + // Key is the string value for Multiaddr address keys + Key string + + // ParseNetAddr parses a net.Addr belonging to this type into a multiaddr + ParseNetAddr AddrParser + + // ConvertMultiaddr converts a multiaddr of this type back into a net.Addr + ConvertMultiaddr MaddrParser + + // Protocol returns the multiaddr protocol struct for this type + Protocol ma.Protocol +} + +func RegisterAddressType(a *AddressSpec) { addrParsersLock.Lock() defer addrParsersLock.Unlock() - addrParsers[netname] = ap - maddrParsers[maname] = mp + for _, n := range a.NetNames { + addrParsers[n] = a.ParseNetAddr + } + + maddrParsers[a.Key] = a.ConvertMultiaddr } func init() { addrParsers = make(map[string]AddrParser) maddrParsers = make(map[string]MaddrParser) - funcs := map[string]AddrParser{ - "tcp": parseTcpNetAddr, - "udp": parseUdpNetAddr, - "utp": parseUtpNetAddr, - } - - for k, v := range funcs { - RegisterAddressType(k, k, v, parseBasicNetMaddr) - RegisterAddressType(k+"4", k, v, parseBasicNetMaddr) - RegisterAddressType(k+"6", k, v, parseBasicNetMaddr) - } - - for _, i := range []string{"ip", "ip4", "ip6"} { - RegisterAddressType(i, i, parseIpNetAddr, parseBasicNetMaddr) - } + RegisterAddressType(tcpAddrSpec) + RegisterAddressType(udpAddrSpec) + RegisterAddressType(utpAddrSpec) + RegisterAddressType(ip4AddrSpec) + RegisterAddressType(ip6AddrSpec) addrParsers["ip+net"] = parseIpPlusNetAddr } From 79cf06be20493bd5326cfdc4154435c1878a1dae Mon Sep 17 00:00:00 2001 From: Jeromy Date: Fri, 6 May 2016 09:14:27 -0700 Subject: [PATCH 4/5] move addspec definitions and add test for RegisterAddressType --- convert.go | 35 --------------------------------- registry.go | 35 +++++++++++++++++++++++++++++++++ registry_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 35 deletions(-) create mode 100644 registry_test.go diff --git a/convert.go b/convert.go index a521e97..f8ff71d 100644 --- a/convert.go +++ b/convert.go @@ -101,13 +101,6 @@ func DialArgs(m ma.Multiaddr) (string, string, error) { return network, host, nil } -var tcpAddrSpec = &AddressSpec{ - Key: "tcp", - NetNames: []string{"tcp", "tcp4", "tcp6"}, - ParseNetAddr: parseTcpNetAddr, - ConvertMultiaddr: parseBasicNetMaddr, -} - func parseTcpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.TCPAddr) if !ok { @@ -130,13 +123,6 @@ func parseTcpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(tcpm), nil } -var udpAddrSpec = &AddressSpec{ - Key: "udp", - NetNames: []string{"udp", "udp4", "udp6"}, - ParseNetAddr: parseUdpNetAddr, - ConvertMultiaddr: parseBasicNetMaddr, -} - func parseUdpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.UDPAddr) if !ok { @@ -159,13 +145,6 @@ func parseUdpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(udpm), nil } -var utpAddrSpec = &AddressSpec{ - Key: "utp", - NetNames: []string{"utp", "utp4", "utp6"}, - ParseNetAddr: parseUtpNetAddr, - ConvertMultiaddr: parseBasicNetMaddr, -} - func parseUtpNetAddr(a net.Addr) (ma.Multiaddr, error) { acc, ok := a.(*utp.Addr) if !ok { @@ -194,20 +173,6 @@ func parseUtpNetAddr(a net.Addr) (ma.Multiaddr, error) { return ipm.Encapsulate(utpm), nil } -var ip4AddrSpec = &AddressSpec{ - Key: "ip4", - NetNames: []string{"ip4"}, - ParseNetAddr: parseIpNetAddr, - ConvertMultiaddr: parseBasicNetMaddr, -} - -var ip6AddrSpec = &AddressSpec{ - Key: "ip6", - NetNames: []string{"ip6"}, - ParseNetAddr: parseIpNetAddr, - ConvertMultiaddr: parseBasicNetMaddr, -} - func parseIpNetAddr(a net.Addr) (ma.Multiaddr, error) { ac, ok := a.(*net.IPAddr) if !ok { diff --git a/registry.go b/registry.go index 57e6d98..aa8d22f 100644 --- a/registry.go +++ b/registry.go @@ -56,6 +56,41 @@ func init() { addrParsers["ip+net"] = parseIpPlusNetAddr } +var tcpAddrSpec = &AddressSpec{ + Key: "tcp", + NetNames: []string{"tcp", "tcp4", "tcp6"}, + ParseNetAddr: parseTcpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + +var udpAddrSpec = &AddressSpec{ + Key: "udp", + NetNames: []string{"udp", "udp4", "udp6"}, + ParseNetAddr: parseUdpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + +var utpAddrSpec = &AddressSpec{ + Key: "utp", + NetNames: []string{"utp", "utp4", "utp6"}, + ParseNetAddr: parseUtpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + +var ip4AddrSpec = &AddressSpec{ + Key: "ip4", + NetNames: []string{"ip4"}, + ParseNetAddr: parseIpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + +var ip6AddrSpec = &AddressSpec{ + Key: "ip6", + NetNames: []string{"ip6"}, + ParseNetAddr: parseIpNetAddr, + ConvertMultiaddr: parseBasicNetMaddr, +} + func getAddrParser(net string) (AddrParser, error) { addrParsersLock.Lock() defer addrParsersLock.Unlock() diff --git a/registry_test.go b/registry_test.go new file mode 100644 index 0000000..f185596 --- /dev/null +++ b/registry_test.go @@ -0,0 +1,50 @@ +package manet + +import ( + "net" + "testing" + + ma "github.com/jbenet/go-multiaddr" +) + +func TestRegisterSpec(t *testing.T) { + myproto := &AddressSpec{ + Key: "test", + NetNames: []string{"test", "iptest", "blahtest"}, + ConvertMultiaddr: func(a ma.Multiaddr) (net.Addr, error) { return nil, nil }, + ParseNetAddr: func(a net.Addr) (ma.Multiaddr, error) { return nil, nil }, + } + + RegisterAddressType(myproto) + + _, ok := addrParsers["test"] + if !ok { + t.Fatal("myproto not properly registered") + } + + _, ok = addrParsers["iptest"] + if !ok { + t.Fatal("myproto not properly registered") + } + + _, ok = addrParsers["blahtest"] + if !ok { + t.Fatal("myproto not properly registered") + } + + _, ok = maddrParsers["test"] + if !ok { + t.Fatal("myproto not properly registered") + } + + _, ok = maddrParsers["iptest"] + if ok { + t.Fatal("myproto not properly registered") + } + + _, ok = maddrParsers["blahtest"] + if ok { + t.Fatal("myproto not properly registered") + } + +} From b730d261ac533bab9ceafcf01223cb21023616fe Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sat, 14 May 2016 18:02:25 -0700 Subject: [PATCH 5/5] refactor globals --- convert.go | 14 +++++- registry.go | 122 ++++++++++++++++++++++++++--------------------- registry_test.go | 22 ++++----- 3 files changed, 91 insertions(+), 67 deletions(-) diff --git a/convert.go b/convert.go index f8ff71d..0bd59c7 100644 --- a/convert.go +++ b/convert.go @@ -13,10 +13,14 @@ 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) { + return defaultCodecs.FromNetAddr(a) +} + +func (cm *CodecMap) FromNetAddr(a net.Addr) (ma.Multiaddr, error) { if a == nil { return nil, fmt.Errorf("nil multiaddr") } - p, err := getAddrParser(a.Network()) + p, err := cm.getAddrParser(a.Network()) if err != nil { return nil, err } @@ -28,10 +32,14 @@ func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { // Must be ThinWaist. acceptable protocol stacks are: // /ip{4,6}/{tcp, udp} func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { + return defaultCodecs.ToNetAddr(maddr) +} + +func (cm *CodecMap) ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { protos := maddr.Protocols() final := protos[len(protos)-1] - p, err := getMaddrParser(final.Name) + p, err := cm.getMaddrParser(final.Name) if err != nil { return nil, err } @@ -73,6 +81,8 @@ func FromIP(ip net.IP) (ma.Multiaddr, error) { // DialArgs is a convenience function returning arguments for use in net.Dial func DialArgs(m ma.Multiaddr) (string, string, error) { + // TODO: find a 'good' way to eliminate the function. + // My preference is with a multiaddr.Format(...) function if !IsThinWaist(m) { return "", "", fmt.Errorf("%s is not a 'thin waist' address", m) } diff --git a/registry.go b/registry.go index aa8d22f..816e554 100644 --- a/registry.go +++ b/registry.go @@ -8,104 +8,118 @@ import ( ma "github.com/jbenet/go-multiaddr" ) -type AddrParser func(a net.Addr) (ma.Multiaddr, error) -type MaddrParser func(ma ma.Multiaddr) (net.Addr, error) +type FromNetAddrFunc func(a net.Addr) (ma.Multiaddr, error) +type ToNetAddrFunc func(ma ma.Multiaddr) (net.Addr, error) -var maddrParsers map[string]MaddrParser -var addrParsers map[string]AddrParser -var addrParsersLock sync.Mutex +var defaultCodecs *CodecMap -type AddressSpec struct { - // NetNames is an array of strings that may be returned +func init() { + defaultCodecs = NewCodecMap() + defaultCodecs.RegisterNetCodec(tcpAddrSpec) + defaultCodecs.RegisterNetCodec(udpAddrSpec) + defaultCodecs.RegisterNetCodec(utpAddrSpec) + defaultCodecs.RegisterNetCodec(ip4AddrSpec) + defaultCodecs.RegisterNetCodec(ip6AddrSpec) +} + +type CodecMap struct { + codecs map[string]*NetCodec + addrParsers map[string]FromNetAddrFunc + maddrParsers map[string]ToNetAddrFunc + lk sync.Mutex +} + +func NewCodecMap() *CodecMap { + return &CodecMap{ + codecs: make(map[string]*NetCodec), + addrParsers: make(map[string]FromNetAddrFunc), + maddrParsers: make(map[string]ToNetAddrFunc), + } +} + +type NetCodec struct { + // NetAddrNetworks is an array of strings that may be returned // by net.Addr.Network() calls on addresses belonging to this type - NetNames []string + NetAddrNetworks []string - // Key is the string value for Multiaddr address keys - Key string + // ProtocolName is the string value for Multiaddr address keys + ProtocolName string // ParseNetAddr parses a net.Addr belonging to this type into a multiaddr - ParseNetAddr AddrParser + ParseNetAddr FromNetAddrFunc // ConvertMultiaddr converts a multiaddr of this type back into a net.Addr - ConvertMultiaddr MaddrParser + ConvertMultiaddr ToNetAddrFunc // Protocol returns the multiaddr protocol struct for this type Protocol ma.Protocol } -func RegisterAddressType(a *AddressSpec) { - addrParsersLock.Lock() - defer addrParsersLock.Unlock() - for _, n := range a.NetNames { - addrParsers[n] = a.ParseNetAddr +func RegisterNetCodec(a *NetCodec) { + defaultCodecs.RegisterNetCodec(a) +} + +func (cm *CodecMap) RegisterNetCodec(a *NetCodec) { + cm.lk.Lock() + defer cm.lk.Unlock() + cm.codecs[a.ProtocolName] = a + for _, n := range a.NetAddrNetworks { + cm.addrParsers[n] = a.ParseNetAddr } - maddrParsers[a.Key] = a.ConvertMultiaddr + cm.maddrParsers[a.ProtocolName] = a.ConvertMultiaddr } -func init() { - addrParsers = make(map[string]AddrParser) - maddrParsers = make(map[string]MaddrParser) - - RegisterAddressType(tcpAddrSpec) - RegisterAddressType(udpAddrSpec) - RegisterAddressType(utpAddrSpec) - RegisterAddressType(ip4AddrSpec) - RegisterAddressType(ip6AddrSpec) - - addrParsers["ip+net"] = parseIpPlusNetAddr -} - -var tcpAddrSpec = &AddressSpec{ - Key: "tcp", - NetNames: []string{"tcp", "tcp4", "tcp6"}, +var tcpAddrSpec = &NetCodec{ + ProtocolName: "tcp", + NetAddrNetworks: []string{"tcp", "tcp4", "tcp6"}, ParseNetAddr: parseTcpNetAddr, ConvertMultiaddr: parseBasicNetMaddr, } -var udpAddrSpec = &AddressSpec{ - Key: "udp", - NetNames: []string{"udp", "udp4", "udp6"}, +var udpAddrSpec = &NetCodec{ + ProtocolName: "udp", + NetAddrNetworks: []string{"udp", "udp4", "udp6"}, ParseNetAddr: parseUdpNetAddr, ConvertMultiaddr: parseBasicNetMaddr, } -var utpAddrSpec = &AddressSpec{ - Key: "utp", - NetNames: []string{"utp", "utp4", "utp6"}, +var utpAddrSpec = &NetCodec{ + ProtocolName: "utp", + NetAddrNetworks: []string{"utp", "utp4", "utp6"}, ParseNetAddr: parseUtpNetAddr, ConvertMultiaddr: parseBasicNetMaddr, } -var ip4AddrSpec = &AddressSpec{ - Key: "ip4", - NetNames: []string{"ip4"}, +var ip4AddrSpec = &NetCodec{ + ProtocolName: "ip4", + NetAddrNetworks: []string{"ip4"}, ParseNetAddr: parseIpNetAddr, ConvertMultiaddr: parseBasicNetMaddr, } -var ip6AddrSpec = &AddressSpec{ - Key: "ip6", - NetNames: []string{"ip6"}, +var ip6AddrSpec = &NetCodec{ + ProtocolName: "ip6", + NetAddrNetworks: []string{"ip6"}, ParseNetAddr: parseIpNetAddr, ConvertMultiaddr: parseBasicNetMaddr, } -func getAddrParser(net string) (AddrParser, error) { - addrParsersLock.Lock() - defer addrParsersLock.Unlock() +func (cm *CodecMap) getAddrParser(net string) (FromNetAddrFunc, error) { + cm.lk.Lock() + defer cm.lk.Unlock() - parser, ok := addrParsers[net] + parser, ok := cm.addrParsers[net] if !ok { return nil, fmt.Errorf("unknown network %v", net) } return parser, nil } -func getMaddrParser(name string) (MaddrParser, error) { - addrParsersLock.Lock() - defer addrParsersLock.Unlock() - p, ok := maddrParsers[name] +func (cm *CodecMap) getMaddrParser(name string) (ToNetAddrFunc, error) { + cm.lk.Lock() + defer cm.lk.Unlock() + p, ok := cm.maddrParsers[name] if !ok { return nil, fmt.Errorf("network not supported: %s", name) } diff --git a/registry_test.go b/registry_test.go index f185596..6e825e8 100644 --- a/registry_test.go +++ b/registry_test.go @@ -8,43 +8,43 @@ import ( ) func TestRegisterSpec(t *testing.T) { - myproto := &AddressSpec{ - Key: "test", - NetNames: []string{"test", "iptest", "blahtest"}, + cm := NewCodecMap() + myproto := &NetCodec{ + ProtocolName: "test", + NetAddrNetworks: []string{"test", "iptest", "blahtest"}, ConvertMultiaddr: func(a ma.Multiaddr) (net.Addr, error) { return nil, nil }, ParseNetAddr: func(a net.Addr) (ma.Multiaddr, error) { return nil, nil }, } - RegisterAddressType(myproto) + cm.RegisterNetCodec(myproto) - _, ok := addrParsers["test"] + _, ok := cm.addrParsers["test"] if !ok { t.Fatal("myproto not properly registered") } - _, ok = addrParsers["iptest"] + _, ok = cm.addrParsers["iptest"] if !ok { t.Fatal("myproto not properly registered") } - _, ok = addrParsers["blahtest"] + _, ok = cm.addrParsers["blahtest"] if !ok { t.Fatal("myproto not properly registered") } - _, ok = maddrParsers["test"] + _, ok = cm.maddrParsers["test"] if !ok { t.Fatal("myproto not properly registered") } - _, ok = maddrParsers["iptest"] + _, ok = cm.maddrParsers["iptest"] if ok { t.Fatal("myproto not properly registered") } - _, ok = maddrParsers["blahtest"] + _, ok = cm.maddrParsers["blahtest"] if ok { t.Fatal("myproto not properly registered") } - }