locator.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package zerotier
  14. // #include "../../native/GoGlue.h"
  15. import "C"
  16. import (
  17. "encoding/json"
  18. "runtime"
  19. "unsafe"
  20. )
  21. type Locator struct {
  22. Timestamp int64 `json:"timestamp"`
  23. Fingerprint *Fingerprint `json:"fingerprint"`
  24. Endpoints []Endpoint `json:"endpoints"`
  25. String string `json:"string"`
  26. cl unsafe.Pointer
  27. }
  28. func NewLocator(ts int64, endpoints []Endpoint, signer *Identity) (*Locator, error) {
  29. if ts <= 0 || len(endpoints) == 0 || signer == nil {
  30. return nil, ErrInvalidParameter
  31. }
  32. eps := make([]C.ZT_Endpoint, 0, len(endpoints))
  33. for _, e := range endpoints {
  34. eps = append(eps, e.cep)
  35. }
  36. signer.initCIdentityPtr()
  37. loc := C.ZT_Locator_create(C.int64_t(ts), &eps[0], C.uint(len(eps)), signer.cid)
  38. if uintptr(loc) == 0 {
  39. return nil, ErrInvalidParameter
  40. }
  41. goloc := new(Locator)
  42. goloc.cl = unsafe.Pointer(loc)
  43. return goloc, goloc.init()
  44. }
  45. func NewLocatorFromBytes(lb []byte) (*Locator, error) {
  46. if len(lb) == 0 {
  47. return nil, ErrInvalidParameter
  48. }
  49. loc := C.ZT_Locator_unmarshal(unsafe.Pointer(&lb[0]), C.uint(len(lb)))
  50. if uintptr(loc) == 0 {
  51. return nil, ErrInvalidParameter
  52. }
  53. goloc := new(Locator)
  54. goloc.cl = unsafe.Pointer(loc)
  55. return goloc, goloc.init()
  56. }
  57. func NewLocatorFromString(s string) (*Locator, error) {
  58. if len(s) == 0 {
  59. return nil, ErrInvalidParameter
  60. }
  61. sb := []byte(s)
  62. sb = append(sb, 0)
  63. loc := C.ZT_Locator_fromString((*C.char)(unsafe.Pointer(&sb[0])))
  64. if loc == nil {
  65. return nil, ErrInvalidParameter
  66. }
  67. goloc := new(Locator)
  68. goloc.cl = unsafe.Pointer(loc)
  69. return goloc, goloc.init()
  70. }
  71. func (loc *Locator) Validate(id *Identity) bool {
  72. if id == nil {
  73. return false
  74. }
  75. id.initCIdentityPtr()
  76. return C.ZT_Locator_verify(loc.cl, id.cid) != 0
  77. }
  78. func (loc *Locator) Bytes() []byte {
  79. var buf [4096]byte
  80. bl := C.ZT_Locator_marshal(loc.cl, unsafe.Pointer(&buf[0]), 4096)
  81. if bl <= 0 {
  82. return nil
  83. }
  84. return buf[0:int(bl)]
  85. }
  86. func (loc *Locator) MarshalJSON() ([]byte, error) {
  87. return json.Marshal(loc)
  88. }
  89. func (loc *Locator) UnmarshalJSON(j []byte) error {
  90. C.ZT_Locator_delete(loc.cl)
  91. loc.cl = unsafe.Pointer(nil)
  92. err := json.Unmarshal(j, loc)
  93. if err != nil {
  94. return err
  95. }
  96. sb := []byte(loc.String)
  97. sb = append(sb, 0)
  98. cl := C.ZT_Locator_fromString((*C.char)(unsafe.Pointer(&sb[0])))
  99. if cl == nil {
  100. return ErrInvalidParameter
  101. }
  102. loc.cl = cl
  103. return loc.init()
  104. }
  105. func locatorFinalizer(obj interface{}) {
  106. if obj != nil {
  107. C.ZT_Locator_delete(obj.(Locator).cl)
  108. }
  109. }
  110. func (loc *Locator) init() error {
  111. loc.Timestamp = int64(C.ZT_Locator_timestamp(loc.cl))
  112. cfp := C.ZT_Locator_fingerprint(loc.cl)
  113. if uintptr(unsafe.Pointer(cfp)) == 0 {
  114. return ErrInternal
  115. }
  116. loc.Fingerprint = newFingerprintFromCFingerprint(cfp)
  117. epc := int(C.ZT_Locator_endpointCount(loc.cl))
  118. loc.Endpoints = make([]Endpoint, epc)
  119. for i := 0; i < epc; i++ {
  120. loc.Endpoints[i].cep = *C.ZT_Locator_endpoint(loc.cl, C.uint(i))
  121. }
  122. var buf [4096]byte
  123. loc.String = C.GoString(C.ZT_Locator_toString(loc.cl, (*C.char)(unsafe.Pointer(&buf[0])), 4096))
  124. runtime.SetFinalizer(loc, locatorFinalizer)
  125. return nil
  126. }