locator.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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: 2025-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 "../../serviceiocore/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. cl unsafe.Pointer
  26. }
  27. func newLocatorFromCLocator(cl unsafe.Pointer, needFinalizer bool) (*Locator, error) {
  28. loc := new(Locator)
  29. loc.cl = cl
  30. err := loc.init(needFinalizer)
  31. if err != nil {
  32. return nil, err
  33. }
  34. return loc, nil
  35. }
  36. func NewLocator(ts int64, endpoints []*Endpoint, signer *Identity) (*Locator, error) {
  37. if ts <= 0 || len(endpoints) == 0 || signer == nil {
  38. return nil, ErrInvalidParameter
  39. }
  40. eps := make([]C.ZT_Endpoint, 0, len(endpoints))
  41. for _, e := range endpoints {
  42. eps = append(eps, e.cep)
  43. }
  44. loc := C.ZT_Locator_create(C.int64_t(ts), &eps[0], nil, C.uint(len(eps)), signer.cIdentity())
  45. if uintptr(loc) == 0 {
  46. return nil, ErrInvalidParameter
  47. }
  48. goloc := new(Locator)
  49. goloc.cl = unsafe.Pointer(loc)
  50. return goloc, goloc.init(true)
  51. }
  52. func NewLocatorFromBytes(lb []byte) (*Locator, error) {
  53. if len(lb) == 0 {
  54. return nil, ErrInvalidParameter
  55. }
  56. loc := C.ZT_Locator_unmarshal(unsafe.Pointer(&lb[0]), C.uint(len(lb)))
  57. if uintptr(loc) == 0 {
  58. return nil, ErrInvalidParameter
  59. }
  60. goloc := new(Locator)
  61. goloc.cl = unsafe.Pointer(loc)
  62. return goloc, goloc.init(true)
  63. }
  64. func NewLocatorFromString(s string) (*Locator, error) {
  65. if len(s) == 0 {
  66. return nil, ErrInvalidParameter
  67. }
  68. sb := []byte(s)
  69. sb = append(sb, 0)
  70. loc := C.ZT_Locator_fromString((*C.char)(unsafe.Pointer(&sb[0])))
  71. if loc == nil {
  72. return nil, ErrInvalidParameter
  73. }
  74. goloc := new(Locator)
  75. goloc.cl = unsafe.Pointer(loc)
  76. return goloc, goloc.init(true)
  77. }
  78. func (loc *Locator) Validate(id *Identity) bool {
  79. if id == nil {
  80. return false
  81. }
  82. return C.ZT_Locator_verify(loc.cl, id.cIdentity()) != 0
  83. }
  84. func (loc *Locator) Bytes() []byte {
  85. if loc.cl == nil {
  86. return nil
  87. }
  88. var buf [16384]byte // larger than ZT_LOCATOR_MARSHAL_SIZE_MAX
  89. bl := C.ZT_Locator_marshal(loc.cl, unsafe.Pointer(&buf[0]), 16384)
  90. if bl <= 0 {
  91. return nil
  92. }
  93. return buf[0:int(bl)]
  94. }
  95. func (loc *Locator) String() string {
  96. if loc.cl == nil {
  97. return ""
  98. }
  99. var buf [16384]C.char // 16384 == ZT_LOCATOR_STRING_SIZE_MAX
  100. return C.GoString(C.ZT_Locator_toString(loc.cl, &buf[0], 16384))
  101. }
  102. func (loc *Locator) MarshalJSON() ([]byte, error) {
  103. return json.Marshal(loc)
  104. }
  105. func (loc *Locator) UnmarshalJSON(j []byte) error {
  106. if loc.cl != nil {
  107. C.ZT_Locator_delete(loc.cl)
  108. loc.cl = unsafe.Pointer(nil)
  109. }
  110. err := json.Unmarshal(j, loc)
  111. if err != nil {
  112. return err
  113. }
  114. return loc.init(true)
  115. }
  116. func locatorFinalizer(obj interface{}) {
  117. if obj != nil {
  118. cl := obj.(*Locator).cl
  119. if cl != nil {
  120. C.ZT_Locator_delete(cl)
  121. }
  122. }
  123. }
  124. func (loc *Locator) init(needFinalizer bool) error {
  125. loc.Timestamp = int64(C.ZT_Locator_timestamp(loc.cl))
  126. cfp := C.ZT_Locator_fingerprint(loc.cl)
  127. if uintptr(unsafe.Pointer(cfp)) == 0 {
  128. return ErrInternal
  129. }
  130. loc.Fingerprint = newFingerprintFromCFingerprint(cfp)
  131. epc := int(C.ZT_Locator_endpointCount(loc.cl))
  132. loc.Endpoints = make([]Endpoint, epc)
  133. for i := 0; i < epc; i++ {
  134. loc.Endpoints[i].cep = *C.ZT_Locator_endpoint(loc.cl, C.uint(i))
  135. }
  136. if needFinalizer {
  137. runtime.SetFinalizer(loc, locatorFinalizer)
  138. }
  139. return nil
  140. }