node-callbacks.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c)2019 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: 2023-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. //#cgo CFLAGS: -O3
  15. //#define ZT_CGO 1
  16. //#include <stdint.h>
  17. //#include <stdlib.h>
  18. //#include <string.h>
  19. //#include "../../native/GoGlue.h"
  20. import "C"
  21. import (
  22. "net"
  23. "sync"
  24. "sync/atomic"
  25. "unsafe"
  26. )
  27. const (
  28. afInet = C.AF_INET
  29. afInet6 = C.AF_INET6
  30. networkStatusRequestingConfiguration = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
  31. networkStatusOK = C.ZT_NETWORK_STATUS_OK
  32. networkStatusAccessDenied = C.ZT_NETWORK_STATUS_ACCESS_DENIED
  33. networkStatusNotFound = C.ZT_NETWORK_STATUS_NOT_FOUND
  34. networkStatusPortError = C.ZT_NETWORK_STATUS_PORT_ERROR
  35. networkStatusClientTooOld = C.ZT_NETWORK_STATUS_CLIENT_TOO_OLD
  36. )
  37. var (
  38. nodesByUserPtr map[uintptr]*Node
  39. nodesByUserPtrLock sync.RWMutex
  40. )
  41. //export goPathCheckFunc
  42. func goPathCheckFunc(gn unsafe.Pointer, ztAddress C.uint64_t, af C.int, ip unsafe.Pointer, port C.int) C.int {
  43. nodesByUserPtrLock.RLock()
  44. node := nodesByUserPtr[uintptr(gn)]
  45. nodesByUserPtrLock.RUnlock()
  46. if node != nil && node.pathCheck(uint64(ztAddress), int(af), nil, int(port)) {
  47. return 1
  48. }
  49. return 0
  50. }
  51. //export goPathLookupFunc
  52. func goPathLookupFunc(gn unsafe.Pointer, ztAddress C.uint64_t, desiredAddressFamily int, familyP, ipP, portP unsafe.Pointer) C.int {
  53. nodesByUserPtrLock.RLock()
  54. node := nodesByUserPtr[uintptr(gn)]
  55. nodesByUserPtrLock.RUnlock()
  56. if node == nil {
  57. return 0
  58. }
  59. ip, port := node.pathLookup(uint64(ztAddress))
  60. ip4 := ip.To4()
  61. if len(ip4) == 4 {
  62. *((*C.int)(familyP)) = afInet
  63. copy((*[4]byte)(ipP)[:], ip4)
  64. *((*C.int)(portP)) = C.int(port)
  65. } else if len(ip) == 16 {
  66. *((*C.int)(familyP)) = afInet6
  67. copy((*[16]byte)(ipP)[:], ip)
  68. *((*C.int)(portP)) = C.int(port)
  69. }
  70. return 0
  71. }
  72. //export goStateObjectPutFunc
  73. func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, len C.int) {
  74. nodesByUserPtrLock.RLock()
  75. node := nodesByUserPtr[uintptr(gn)]
  76. nodesByUserPtrLock.RUnlock()
  77. if node == nil {
  78. return
  79. }
  80. if len < 0 {
  81. node.stateObjectDelete(int(objType), *((*[2]uint64)(id)))
  82. } else {
  83. node.stateObjectPut(int(objType), *((*[2]uint64)(id)), C.GoBytes(data, len))
  84. }
  85. }
  86. //export goStateObjectGetFunc
  87. func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, bufSize C.uint) C.int {
  88. nodesByUserPtrLock.RLock()
  89. node := nodesByUserPtr[uintptr(gn)]
  90. nodesByUserPtrLock.RUnlock()
  91. if node == nil {
  92. return -1
  93. }
  94. tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
  95. if found && len(tmp) < int(bufSize) {
  96. if len(tmp) > 0 {
  97. C.memcpy(data, unsafe.Pointer(&(tmp[0])), C.ulong(len(tmp)))
  98. }
  99. return C.int(len(tmp))
  100. }
  101. return -1
  102. }
  103. //export goDNSResolverFunc
  104. func goDNSResolverFunc(gn unsafe.Pointer, dnsRecordTypes unsafe.Pointer, numDNSRecordTypes C.int, name unsafe.Pointer, requestID C.uintptr_t) {
  105. nodesByUserPtrLock.RLock()
  106. node := nodesByUserPtr[uintptr(gn)]
  107. nodesByUserPtrLock.RUnlock()
  108. if node == nil {
  109. return
  110. }
  111. recordTypes := C.GoBytes(dnsRecordTypes, numDNSRecordTypes)
  112. recordName := C.GoString((*C.char)(name))
  113. go func() {
  114. recordNameCStrCopy := C.CString(recordName)
  115. for _, rt := range recordTypes {
  116. switch rt {
  117. case C.ZT_DNS_RECORD_TXT:
  118. recs, _ := net.LookupTXT(recordName)
  119. for _, rec := range recs {
  120. if len(rec) > 0 {
  121. rnCS := C.CString(rec)
  122. C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD_TXT, unsafe.Pointer(rnCS), C.uint(len(rec)), 0)
  123. C.free(unsafe.Pointer(rnCS))
  124. }
  125. }
  126. }
  127. }
  128. C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD__END_OF_RESULTS, nil, 0, 0)
  129. C.free(unsafe.Pointer(recordNameCStrCopy))
  130. }()
  131. }
  132. //export goVirtualNetworkConfigFunc
  133. func goVirtualNetworkConfigFunc(gn, tapP unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) C.int {
  134. nodesByUserPtrLock.RLock()
  135. node := nodesByUserPtr[uintptr(gn)]
  136. nodesByUserPtrLock.RUnlock()
  137. if node == nil {
  138. return 255
  139. }
  140. return C.int(node.handleNetworkConfigUpdate(int(op), (*C.ZT_VirtualNetworkConfig)(conf)))
  141. }
  142. //export goZtEvent
  143. func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
  144. nodesByUserPtrLock.RLock()
  145. node := nodesByUserPtr[uintptr(gn)]
  146. nodesByUserPtrLock.RUnlock()
  147. if node == nil {
  148. return
  149. }
  150. switch eventType {
  151. case C.ZT_EVENT_OFFLINE:
  152. atomic.StoreUint32(&node.online, 0)
  153. case C.ZT_EVENT_ONLINE:
  154. atomic.StoreUint32(&node.online, 1)
  155. case C.ZT_EVENT_TRACE:
  156. node.handleTrace(C.GoString((*C.char)(data)))
  157. case C.ZT_EVENT_USER_MESSAGE:
  158. um := (*C.ZT_UserMessage)(data)
  159. node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
  160. case C.ZT_EVENT_REMOTE_TRACE:
  161. rt := (*C.ZT_RemoteTrace)(data)
  162. node.handleRemoteTrace(uint64(rt.origin), C.GoBytes(unsafe.Pointer(rt.data), C.int(rt.len)))
  163. }
  164. }