endpoint.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package attic
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. )
  6. // Endpoint types are the same as the enum values in Endpoint.hpp in the core.
  7. const (
  8. EndpointTypeNil = 0
  9. EndpointTypeInetAddr = 1
  10. EndpointTypeDnsName = 2
  11. EndpointTypeZeroTier = 3
  12. EndpointTypeUrl = 4
  13. EndpointTypeEthernet = 5
  14. EndpointTypeUnrecognized = 255
  15. )
  16. // Endpoint wraps a variety of different ways of describing a node's physical network location.
  17. type Endpoint struct {
  18. // Type is this endpoint's type
  19. Type int
  20. // Location is the X, Y, Z coordinate of this endpoint or 0,0,0 if unspecified.
  21. Location [3]int
  22. value, value2 interface{}
  23. }
  24. var (
  25. ErrInvalidEndpoint = errors.New("invalid marshaled endpoint object")
  26. )
  27. func (ep *Endpoint) unmarshalZT(b []byte) (int, error) {
  28. if len(b) < 7 {
  29. return 0, ErrInvalidEndpoint
  30. }
  31. ep.Type = int(b[0])
  32. ep.Location[0] = int(binary.BigEndian.Uint16(b[1:3]))
  33. ep.Location[1] = int(binary.BigEndian.Uint16(b[3:5]))
  34. ep.Location[2] = int(binary.BigEndian.Uint16(b[5:7]))
  35. ep.value = nil
  36. ep.value2 = nil
  37. switch ep.Type {
  38. case EndpointTypeNil:
  39. return 7, nil
  40. case EndpointTypeInetAddr:
  41. ina := new(InetAddress)
  42. inlen, err := ina.unmarshalZT(b[7:])
  43. if err != nil {
  44. return 0, err
  45. }
  46. ep.value = ina
  47. return 7 + inlen, nil
  48. case EndpointTypeDnsName:
  49. stringEnd := 0
  50. for i := 7; i < len(b); i++ {
  51. if b[i] == 0 {
  52. stringEnd = i + 1
  53. break
  54. }
  55. }
  56. if stringEnd == 0 || (stringEnd+2) > len(b) {
  57. return 0, ErrInvalidEndpoint
  58. }
  59. ep.value = string(b[7:stringEnd])
  60. port := binary.BigEndian.Uint16(b[stringEnd : stringEnd+2])
  61. ep.value2 = &port
  62. return stringEnd + 2, nil
  63. case EndpointTypeZeroTier:
  64. if len(b) < 60 {
  65. return 0, ErrInvalidEndpoint
  66. }
  67. a, err := NewAddressFromBytes(b[7:12])
  68. if err != nil {
  69. return 0, err
  70. }
  71. ep.value = a
  72. ep.value2 = append(make([]byte, 0, 48), b[12:60]...)
  73. return 60, nil
  74. case EndpointTypeUrl:
  75. stringEnd := 0
  76. for i := 7; i < len(b); i++ {
  77. if b[i] == 0 {
  78. stringEnd = i + 1
  79. break
  80. }
  81. }
  82. if stringEnd == 0 {
  83. return 0, ErrInvalidEndpoint
  84. }
  85. ep.value = string(b[7:stringEnd])
  86. return stringEnd, nil
  87. case EndpointTypeEthernet:
  88. if len(b) < 13 {
  89. return 0, ErrInvalidEndpoint
  90. }
  91. m, err := NewMACFromBytes(b[7:13])
  92. if err != nil {
  93. return 0, err
  94. }
  95. ep.value = m
  96. return 13, nil
  97. default:
  98. if len(b) < 8 {
  99. return 0, ErrInvalidEndpoint
  100. }
  101. ep.Type = EndpointTypeUnrecognized
  102. return 8 + int(b[1]), nil
  103. }
  104. }
  105. // InetAddress gets the address associated with this endpoint or nil if it is not of this type.
  106. func (ep *Endpoint) InetAddress() *InetAddress {
  107. v, _ := ep.value.(*InetAddress)
  108. return v
  109. }
  110. // Address gets the address associated with this endpoint or nil if it is not of this type.
  111. func (ep *Endpoint) Address() *Address {
  112. v, _ := ep.value.(*Address)
  113. return v
  114. }
  115. // DNSName gets the DNS name and port associated with this endpoint or an empty string and -1 if it is not of this type.
  116. func (ep *Endpoint) DNSName() (string, int) {
  117. if ep.Type == EndpointTypeDnsName {
  118. return ep.value.(string), int(*(ep.value2.(*uint16)))
  119. }
  120. return "", -1
  121. }
  122. // InetAddress gets the URL assocaited with this endpoint or an empty string if it is not of this type.
  123. func (ep *Endpoint) URL() string {
  124. if ep.Type == EndpointTypeUrl {
  125. return ep.value.(string)
  126. }
  127. return ""
  128. }
  129. // Ethernet gets the address associated with this endpoint or nil if it is not of this type.
  130. func (ep *Endpoint) Ethernet() *MAC {
  131. v, _ := ep.value.(*MAC)
  132. return v
  133. }