endpoint.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package zerotier
  2. // #include "../../serviceiocore/GoGlue.h"
  3. // static inline const ZT_Fingerprint *_getFP(const ZT_Endpoint *ep) { return &(ep->value.fp); }
  4. // static inline uint64_t _getAddress(const ZT_Endpoint *ep) { return ep->value.fp.address; }
  5. // static inline uint64_t _getMAC(const ZT_Endpoint *ep) { return ep->value.mac; }
  6. // static inline const struct sockaddr_storage *_getSS(const ZT_Endpoint *ep) { return &(ep->value.ss); }
  7. // static inline void _setSS(ZT_Endpoint *ep,const void *ss) { memcpy(&(ep->value.ss),ss,sizeof(struct sockaddr_storage)); }
  8. import "C"
  9. import (
  10. "encoding/json"
  11. "unsafe"
  12. )
  13. const (
  14. EndpointTypeNil = C.ZT_ENDPOINT_TYPE_NIL
  15. EndpointTypeZeroTier = C.ZT_ENDPOINT_TYPE_ZEROTIER
  16. EndpointTypeEthernet = C.ZT_ENDPOINT_TYPE_ETHERNET
  17. EndpointTypeWifiDirect = C.ZT_ENDPOINT_TYPE_WIFI_DIRECT
  18. EndpointTypeBluetooth = C.ZT_ENDPOINT_TYPE_BLUETOOTH
  19. EndpointTypeIp = C.ZT_ENDPOINT_TYPE_IP
  20. EndpointTypeIpUdp = C.ZT_ENDPOINT_TYPE_IP_UDP
  21. EndpointTypeIpTcp = C.ZT_ENDPOINT_TYPE_IP_TCP
  22. EndpointTypeIpHttp = C.ZT_ENDPOINT_TYPE_IP_HTTP
  23. )
  24. type Endpoint struct {
  25. cep C.ZT_Endpoint
  26. }
  27. // NewEndpointFromString constructs a new endpoint from an InetAddress or Endpoint string.
  28. // This will auto detect whether this is a plain InetAddress or an Endpoint in string
  29. // format. If the former it's created as a ZT_ENDPOINT_TYPE_IP_UDP endpoint.
  30. func NewEndpointFromString(s string) (*Endpoint, error) {
  31. if len(s) == 0 {
  32. var ep Endpoint
  33. ep.cep._type = C.ZT_ENDPOINT_TYPE_NIL
  34. return &ep, nil
  35. }
  36. var ep Endpoint
  37. cs := C.CString(s)
  38. defer C.free(unsafe.Pointer(cs))
  39. if C.ZT_Endpoint_fromString(&ep.cep, cs) != 0 {
  40. return nil, ErrInvalidParameter
  41. }
  42. return &ep, nil
  43. }
  44. func NewEndpointFromInetAddress(addr *InetAddress) (*Endpoint, error) {
  45. var ep Endpoint
  46. var ss C.struct_sockaddr_storage
  47. if !makeSockaddrStorage(addr.IP, addr.Port, &ss) {
  48. return nil, ErrInvalidParameter
  49. }
  50. ep.cep._type = C.ZT_ENDPOINT_TYPE_IP_UDP
  51. C._setSS(&ep.cep, unsafe.Pointer(&ss))
  52. return &ep, nil
  53. }
  54. // Type returns this endpoint's type.
  55. func (ep *Endpoint) Type() int {
  56. return int(ep.cep._type)
  57. }
  58. // InetAddress gets this Endpoint as an InetAddress or nil if its type is not addressed by one.
  59. func (ep *Endpoint) InetAddress() *InetAddress {
  60. switch ep.cep._type {
  61. case EndpointTypeIp, EndpointTypeIpUdp, EndpointTypeIpTcp, EndpointTypeIpHttp:
  62. ua := sockaddrStorageToUDPAddr(C._getSS(&ep.cep))
  63. return &InetAddress{IP: ua.IP, Port: ua.Port}
  64. }
  65. return nil
  66. }
  67. // Address returns a ZeroTier address if this is a ZeroTier endpoint or a zero address otherwise.
  68. func (ep *Endpoint) Address() Address {
  69. switch ep.cep._type {
  70. case EndpointTypeZeroTier:
  71. return Address(C._getAddress(&ep.cep))
  72. }
  73. return Address(0)
  74. }
  75. // Fingerprint returns a fingerprint if this is a ZeroTier endpoint or nil otherwise.
  76. func (ep *Endpoint) Fingerprint() *Fingerprint {
  77. switch ep.cep._type {
  78. case EndpointTypeZeroTier:
  79. cfp := C._getFP(&ep.cep)
  80. fp := Fingerprint{Address: Address(cfp.address), Hash: C.GoBytes(unsafe.Pointer(&cfp.hash[0]), 48)}
  81. if allZero(fp.Hash) {
  82. fp.Hash = nil
  83. }
  84. return &fp
  85. }
  86. return nil
  87. }
  88. // MAC returns a MAC address if this is an Ethernet type endpoint or a zero address otherwise.
  89. func (ep *Endpoint) MAC() MAC {
  90. switch ep.cep._type {
  91. case EndpointTypeEthernet, EndpointTypeWifiDirect, EndpointTypeBluetooth:
  92. return MAC(C._getMAC(&ep.cep))
  93. }
  94. return MAC(0)
  95. }
  96. func (ep *Endpoint) String() string {
  97. var buf [4096]byte
  98. cs := C.ZT_Endpoint_toString(&ep.cep, (*C.char)(unsafe.Pointer(&buf[0])), 4096)
  99. if cs == nil {
  100. return "0"
  101. }
  102. return C.GoString(cs)
  103. }
  104. func (ep *Endpoint) MarshalJSON() ([]byte, error) {
  105. s := ep.String()
  106. return json.Marshal(&s)
  107. }
  108. func (ep *Endpoint) UnmarshalJSON(j []byte) error {
  109. var s string
  110. err := json.Unmarshal(j, &s)
  111. if err != nil {
  112. return err
  113. }
  114. ep2, err := NewEndpointFromString(s)
  115. if err != nil {
  116. return err
  117. }
  118. *ep = *ep2
  119. return nil
  120. }
  121. func (ep *Endpoint) setFromCEndpoint(cp *C.ZT_Endpoint) {
  122. ep.cep = *cp
  123. }