mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 08:27:39 +02:00
145 lines
3.4 KiB
Go
145 lines
3.4 KiB
Go
package attic
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
// Endpoint types are the same as the enum values in Endpoint.hpp in the core.
|
|
const (
|
|
EndpointTypeNil = 0
|
|
EndpointTypeInetAddr = 1
|
|
EndpointTypeDnsName = 2
|
|
EndpointTypeZeroTier = 3
|
|
EndpointTypeUrl = 4
|
|
EndpointTypeEthernet = 5
|
|
EndpointTypeUnrecognized = 255
|
|
)
|
|
|
|
// Endpoint wraps a variety of different ways of describing a node's physical network location.
|
|
type Endpoint struct {
|
|
// Type is this endpoint's type
|
|
Type int
|
|
|
|
// Location is the X, Y, Z coordinate of this endpoint or 0,0,0 if unspecified.
|
|
Location [3]int
|
|
|
|
value, value2 interface{}
|
|
}
|
|
|
|
var (
|
|
ErrInvalidEndpoint = errors.New("invalid marshaled endpoint object")
|
|
)
|
|
|
|
func (ep *Endpoint) unmarshalZT(b []byte) (int, error) {
|
|
if len(b) < 7 {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
ep.Type = int(b[0])
|
|
ep.Location[0] = int(binary.BigEndian.Uint16(b[1:3]))
|
|
ep.Location[1] = int(binary.BigEndian.Uint16(b[3:5]))
|
|
ep.Location[2] = int(binary.BigEndian.Uint16(b[5:7]))
|
|
ep.value = nil
|
|
ep.value2 = nil
|
|
switch ep.Type {
|
|
case EndpointTypeNil:
|
|
return 7, nil
|
|
case EndpointTypeInetAddr:
|
|
ina := new(InetAddress)
|
|
inlen, err := ina.unmarshalZT(b[7:])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
ep.value = ina
|
|
return 7 + inlen, nil
|
|
case EndpointTypeDnsName:
|
|
stringEnd := 0
|
|
for i := 7; i < len(b); i++ {
|
|
if b[i] == 0 {
|
|
stringEnd = i + 1
|
|
break
|
|
}
|
|
}
|
|
if stringEnd == 0 || (stringEnd+2) > len(b) {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
ep.value = string(b[7:stringEnd])
|
|
port := binary.BigEndian.Uint16(b[stringEnd : stringEnd+2])
|
|
ep.value2 = &port
|
|
return stringEnd + 2, nil
|
|
case EndpointTypeZeroTier:
|
|
if len(b) < 60 {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
a, err := NewAddressFromBytes(b[7:12])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
ep.value = a
|
|
ep.value2 = append(make([]byte, 0, 48), b[12:60]...)
|
|
return 60, nil
|
|
case EndpointTypeUrl:
|
|
stringEnd := 0
|
|
for i := 7; i < len(b); i++ {
|
|
if b[i] == 0 {
|
|
stringEnd = i + 1
|
|
break
|
|
}
|
|
}
|
|
if stringEnd == 0 {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
ep.value = string(b[7:stringEnd])
|
|
return stringEnd, nil
|
|
case EndpointTypeEthernet:
|
|
if len(b) < 13 {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
m, err := NewMACFromBytes(b[7:13])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
ep.value = m
|
|
return 13, nil
|
|
default:
|
|
if len(b) < 8 {
|
|
return 0, ErrInvalidEndpoint
|
|
}
|
|
ep.Type = EndpointTypeUnrecognized
|
|
return 8 + int(b[1]), nil
|
|
}
|
|
}
|
|
|
|
// InetAddress gets the address associated with this endpoint or nil if it is not of this type.
|
|
func (ep *Endpoint) InetAddress() *InetAddress {
|
|
v, _ := ep.value.(*InetAddress)
|
|
return v
|
|
}
|
|
|
|
// Address gets the address associated with this endpoint or nil if it is not of this type.
|
|
func (ep *Endpoint) Address() *Address {
|
|
v, _ := ep.value.(*Address)
|
|
return v
|
|
}
|
|
|
|
// DNSName gets the DNS name and port associated with this endpoint or an empty string and -1 if it is not of this type.
|
|
func (ep *Endpoint) DNSName() (string, int) {
|
|
if ep.Type == EndpointTypeDnsName {
|
|
return ep.value.(string), int(*(ep.value2.(*uint16)))
|
|
}
|
|
return "", -1
|
|
}
|
|
|
|
// InetAddress gets the URL assocaited with this endpoint or an empty string if it is not of this type.
|
|
func (ep *Endpoint) URL() string {
|
|
if ep.Type == EndpointTypeUrl {
|
|
return ep.value.(string)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Ethernet gets the address associated with this endpoint or nil if it is not of this type.
|
|
func (ep *Endpoint) Ethernet() *MAC {
|
|
v, _ := ep.value.(*MAC)
|
|
return v
|
|
}
|