2016-05-03 13:23:57 -07:00
|
|
|
package manet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"sync"
|
|
|
|
|
2016-09-19 10:30:07 +08:00
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
2016-05-03 13:23:57 -07:00
|
|
|
)
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
type FromNetAddrFunc func(a net.Addr) (ma.Multiaddr, error)
|
|
|
|
type ToNetAddrFunc func(ma ma.Multiaddr) (net.Addr, error)
|
2016-05-03 13:23:57 -07:00
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
var defaultCodecs *CodecMap
|
2016-05-03 13:23:57 -07:00
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
func init() {
|
|
|
|
defaultCodecs = NewCodecMap()
|
|
|
|
defaultCodecs.RegisterNetCodec(tcpAddrSpec)
|
|
|
|
defaultCodecs.RegisterNetCodec(udpAddrSpec)
|
|
|
|
defaultCodecs.RegisterNetCodec(ip4AddrSpec)
|
|
|
|
defaultCodecs.RegisterNetCodec(ip6AddrSpec)
|
2016-05-16 14:40:20 -07:00
|
|
|
defaultCodecs.RegisterNetCodec(ipnetAddrSpec)
|
2016-05-14 18:02:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2016-05-04 14:09:13 -07:00
|
|
|
// by net.Addr.Network() calls on addresses belonging to this type
|
2016-05-14 18:02:25 -07:00
|
|
|
NetAddrNetworks []string
|
2016-05-04 14:09:13 -07:00
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
// ProtocolName is the string value for Multiaddr address keys
|
|
|
|
ProtocolName string
|
2016-05-04 14:09:13 -07:00
|
|
|
|
|
|
|
// ParseNetAddr parses a net.Addr belonging to this type into a multiaddr
|
2016-05-14 18:02:25 -07:00
|
|
|
ParseNetAddr FromNetAddrFunc
|
2016-05-04 14:09:13 -07:00
|
|
|
|
|
|
|
// ConvertMultiaddr converts a multiaddr of this type back into a net.Addr
|
2016-05-14 18:02:25 -07:00
|
|
|
ConvertMultiaddr ToNetAddrFunc
|
2016-05-04 14:09:13 -07:00
|
|
|
|
|
|
|
// Protocol returns the multiaddr protocol struct for this type
|
|
|
|
Protocol ma.Protocol
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
func RegisterNetCodec(a *NetCodec) {
|
|
|
|
defaultCodecs.RegisterNetCodec(a)
|
2016-05-03 13:23:57 -07:00
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
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
|
|
|
|
}
|
2016-05-03 13:23:57 -07:00
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
cm.maddrParsers[a.ProtocolName] = a.ConvertMultiaddr
|
2016-05-03 13:23:57 -07:00
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
var tcpAddrSpec = &NetCodec{
|
|
|
|
ProtocolName: "tcp",
|
|
|
|
NetAddrNetworks: []string{"tcp", "tcp4", "tcp6"},
|
2016-05-06 09:14:27 -07:00
|
|
|
ParseNetAddr: parseTcpNetAddr,
|
|
|
|
ConvertMultiaddr: parseBasicNetMaddr,
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
var udpAddrSpec = &NetCodec{
|
|
|
|
ProtocolName: "udp",
|
|
|
|
NetAddrNetworks: []string{"udp", "udp4", "udp6"},
|
2016-05-06 09:14:27 -07:00
|
|
|
ParseNetAddr: parseUdpNetAddr,
|
|
|
|
ConvertMultiaddr: parseBasicNetMaddr,
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
var ip4AddrSpec = &NetCodec{
|
|
|
|
ProtocolName: "ip4",
|
|
|
|
NetAddrNetworks: []string{"ip4"},
|
2016-05-06 09:14:27 -07:00
|
|
|
ParseNetAddr: parseIpNetAddr,
|
|
|
|
ConvertMultiaddr: parseBasicNetMaddr,
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
var ip6AddrSpec = &NetCodec{
|
|
|
|
ProtocolName: "ip6",
|
|
|
|
NetAddrNetworks: []string{"ip6"},
|
2016-05-06 09:14:27 -07:00
|
|
|
ParseNetAddr: parseIpNetAddr,
|
|
|
|
ConvertMultiaddr: parseBasicNetMaddr,
|
|
|
|
}
|
|
|
|
|
2016-05-16 14:40:20 -07:00
|
|
|
var ipnetAddrSpec = &NetCodec{
|
|
|
|
ProtocolName: "ip+net",
|
|
|
|
NetAddrNetworks: []string{"ip+net"},
|
|
|
|
ParseNetAddr: parseIpPlusNetAddr,
|
|
|
|
ConvertMultiaddr: func(ma.Multiaddr) (net.Addr, error) {
|
|
|
|
return nil, fmt.Errorf("converting ip+net multiaddr not supported")
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
func (cm *CodecMap) getAddrParser(net string) (FromNetAddrFunc, error) {
|
|
|
|
cm.lk.Lock()
|
|
|
|
defer cm.lk.Unlock()
|
2016-05-03 13:23:57 -07:00
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
parser, ok := cm.addrParsers[net]
|
2016-05-03 13:23:57 -07:00
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("unknown network %v", net)
|
|
|
|
}
|
|
|
|
return parser, nil
|
|
|
|
}
|
|
|
|
|
2016-05-14 18:02:25 -07:00
|
|
|
func (cm *CodecMap) getMaddrParser(name string) (ToNetAddrFunc, error) {
|
|
|
|
cm.lk.Lock()
|
|
|
|
defer cm.lk.Unlock()
|
|
|
|
p, ok := cm.maddrParsers[name]
|
2016-05-03 13:23:57 -07:00
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("network not supported: %s", name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return p, nil
|
|
|
|
}
|