123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- 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
- }
|