package network import ( "errors" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" ) const ( // maxProtocolsAmount is maximal amount of protocols // in multiaddress after parsing with network.AddressFromString. maxProtocolsAmount = 3 // minProtocolsAmount is minimal amount of protocols // in multiaddress after parsing with network.AddressFromString: // host(ip) and port. minProtocolsAmount = 2 // network protocols. dns, ip4, ip6 = "dns4", "ip4", "ip6" // transport protocols. tcp = "tcp" ) var ( errIncorrectProtocolAmount = errors.New("numbers of protocols in multiaddress incorrect") errUnsupportedNetworkProtocol = errors.New("unsupported network protocol in multiaddress") errUnsupportedTransportProtocol = errors.New("unsupported transport protocol in multiaddress") errUnsupportedPresentationProtocol = errors.New("unsupported presentation protocol in multiaddress") ) // NodeEndpointsIterator is a wrapper over netmap.NodeInfo which implements // MultiAddressIterator. type NodeEndpointsIterator netmap.NodeInfo func (x NodeEndpointsIterator) IterateAddresses(f func(string) bool) { (netmap.NodeInfo)(x).IterateNetworkEndpoints(f) } func (x NodeEndpointsIterator) NumberOfAddresses() int { return (netmap.NodeInfo)(x).NumberOfNetworkEndpoints() } // VerifyMultiAddress validates multiaddress of n. // // If n's address contains more than 3 protocols // or less than 2 protocols an error returns. // // If n's address's protocol order is incorrect // an error returns. // // Correct composition(and order from low to high level) // of protocols: // 1. dns4/ip4/ip6 // 2. tcp // 3. tls(optional, may be absent) func VerifyMultiAddress(ni netmap.NodeInfo) error { return iterateParsedAddresses(NodeEndpointsIterator(ni), checkProtocols) } func checkProtocols(a Address) error { pp := a.ma.Protocols() parsedProtocolsAmount := len(pp) if parsedProtocolsAmount > maxProtocolsAmount || parsedProtocolsAmount < minProtocolsAmount { return errIncorrectProtocolAmount } switch pp[0].Name { case dns, ip4, ip6: default: return errUnsupportedNetworkProtocol } if pp[1].Name != tcp { return errUnsupportedTransportProtocol } if parsedProtocolsAmount != minProtocolsAmount { if pp[2].Name != tlsProtocolName { return errUnsupportedPresentationProtocol } } return nil }