node.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  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. //#cgo darwin LDFLAGS: ${SRCDIR}/../../../build/go/native/libzt_go_native.a ${SRCDIR}/../../../build/node/libzt_core.a ${SRCDIR}/../../../build/osdep/libzt_osdep.a -lc++ -lpthread
  16. //#cgo linux android LDFLAGS: ${SRCDIR}/../../../build/go/native/libzt_go_native.a ${SRCDIR}/../../../build/node/libzt_core.a ${SRCDIR}/../../../build/osdep/libzt_osdep.a -lstdc++ -lpthread -lm
  17. //#include "../../native/GoGlue.h"
  18. import "C"
  19. import (
  20. "bytes"
  21. "errors"
  22. "fmt"
  23. "io/ioutil"
  24. "log"
  25. "math/rand"
  26. "net"
  27. "net/http"
  28. "os"
  29. "path"
  30. "reflect"
  31. "sort"
  32. "strings"
  33. "sync"
  34. "sync/atomic"
  35. "syscall"
  36. "time"
  37. "unsafe"
  38. "github.com/hectane/go-acl"
  39. )
  40. var nullLogger = log.New(ioutil.Discard, "", 0)
  41. // Network status states
  42. const (
  43. NetworkStatusRequestConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
  44. NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
  45. NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED
  46. NetworkStatusNotFound int = C.ZT_NETWORK_STATUS_NOT_FOUND
  47. NetworkTypePrivate int = C.ZT_NETWORK_TYPE_PRIVATE
  48. NetworkTypePublic int = C.ZT_NETWORK_TYPE_PUBLIC
  49. // CoreVersionMajor is the major version of the ZeroTier core
  50. CoreVersionMajor int = C.ZEROTIER_ONE_VERSION_MAJOR
  51. // CoreVersionMinor is the minor version of the ZeroTier core
  52. CoreVersionMinor int = C.ZEROTIER_ONE_VERSION_MINOR
  53. // CoreVersionRevision is the revision of the ZeroTier core
  54. CoreVersionRevision int = C.ZEROTIER_ONE_VERSION_REVISION
  55. // CoreVersionBuild is the build version of the ZeroTier core
  56. CoreVersionBuild int = C.ZEROTIER_ONE_VERSION_BUILD
  57. networkConfigOpUp int = C.ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP
  58. networkConfigOpUpdate int = C.ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE
  59. defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU
  60. )
  61. var (
  62. // PlatformDefaultHomePath is the default location of ZeroTier's working path on this system
  63. PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
  64. // This map is used to get the Go Node object from a pointer passed back in via C callbacks
  65. nodesByUserPtr = make(map[uintptr]*Node)
  66. nodesByUserPtrLock sync.RWMutex
  67. )
  68. // Node is an instance of the ZeroTier core node and related C++ I/O code
  69. type Node struct {
  70. networks map[NetworkID]*Network
  71. networksByMAC map[MAC]*Network // locked by networksLock
  72. interfaceAddresses map[string]net.IP // physical external IPs on the machine
  73. basePath string
  74. peersPath string
  75. networksPath string
  76. localConfigPath string
  77. localConfig LocalConfig
  78. localConfigLock sync.RWMutex
  79. networksLock sync.RWMutex
  80. interfaceAddressesLock sync.Mutex
  81. logW *sizeLimitWriter
  82. log *log.Logger
  83. gn *C.ZT_GoNode
  84. zn *C.ZT_Node
  85. id *Identity
  86. apiServer *http.Server
  87. tcpApiServer *http.Server
  88. online uint32
  89. running uint32
  90. runLock sync.Mutex
  91. }
  92. // NewNode creates and initializes a new instance of the ZeroTier node service
  93. func NewNode(basePath string) (n *Node, err error) {
  94. n = new(Node)
  95. n.networks = make(map[NetworkID]*Network)
  96. n.networksByMAC = make(map[MAC]*Network)
  97. n.interfaceAddresses = make(map[string]net.IP)
  98. _ = os.MkdirAll(basePath, 0755)
  99. if _, err = os.Stat(basePath); err != nil {
  100. return
  101. }
  102. n.basePath = basePath
  103. n.peersPath = path.Join(basePath, "peers.d")
  104. _ = os.MkdirAll(n.peersPath, 0700)
  105. _ = acl.Chmod(n.peersPath, 0700)
  106. if _, err = os.Stat(n.peersPath); err != nil {
  107. return
  108. }
  109. n.networksPath = path.Join(basePath, "networks.d")
  110. _ = os.MkdirAll(n.networksPath, 0755)
  111. if _, err = os.Stat(n.networksPath); err != nil {
  112. return
  113. }
  114. n.localConfigPath = path.Join(basePath, "local.conf")
  115. _, identitySecretNotFoundErr := os.Stat(path.Join(basePath,"identity.secret"))
  116. err = n.localConfig.Read(n.localConfigPath, true, identitySecretNotFoundErr != nil)
  117. if err != nil {
  118. return
  119. }
  120. if n.localConfig.Settings.LogSizeMax >= 0 {
  121. n.logW, err = sizeLimitWriterOpen(path.Join(basePath, "node.log"))
  122. if err != nil {
  123. return
  124. }
  125. n.log = log.New(n.logW, "", log.LstdFlags)
  126. } else {
  127. n.log = nullLogger
  128. }
  129. if n.localConfig.Settings.PortSearch {
  130. portsChanged := false
  131. portCheckCount := 0
  132. origPort := n.localConfig.Settings.PrimaryPort
  133. for portCheckCount < 256 {
  134. portCheckCount++
  135. if checkPort(n.localConfig.Settings.PrimaryPort) {
  136. if n.localConfig.Settings.PrimaryPort != origPort {
  137. n.log.Printf("primary port %d unavailable, found port %d (port search enabled)", origPort, n.localConfig.Settings.PrimaryPort)
  138. }
  139. break
  140. }
  141. n.localConfig.Settings.PrimaryPort = int(4096 + (randomUInt() % 16384))
  142. portsChanged = true
  143. }
  144. if portCheckCount == 256 {
  145. return nil, errors.New("unable to bind to primary port, tried 2048 later ports")
  146. }
  147. if n.localConfig.Settings.SecondaryPort > 0 {
  148. portCheckCount = 0
  149. origPort = n.localConfig.Settings.SecondaryPort
  150. for portCheckCount < 256 {
  151. portCheckCount++
  152. if checkPort(n.localConfig.Settings.SecondaryPort) {
  153. if n.localConfig.Settings.SecondaryPort != origPort {
  154. n.log.Printf("secondary port %d unavailable, found port %d (port search enabled)", origPort, n.localConfig.Settings.SecondaryPort)
  155. }
  156. break
  157. }
  158. n.log.Printf("secondary port %d unavailable, trying a random port (port search enabled)", n.localConfig.Settings.SecondaryPort)
  159. if portCheckCount <= 64 {
  160. n.localConfig.Settings.SecondaryPort = unassignedPrivilegedPorts[randomUInt() % uint(len(unassignedPrivilegedPorts))]
  161. } else {
  162. n.localConfig.Settings.SecondaryPort = int(16384 + (randomUInt() % 16384))
  163. }
  164. portsChanged = true
  165. }
  166. if portCheckCount == 256 {
  167. n.localConfig.Settings.SecondaryPort = 0
  168. }
  169. }
  170. if portsChanged {
  171. _ = n.localConfig.Write(n.localConfigPath)
  172. }
  173. } else if !checkPort(n.localConfig.Settings.PrimaryPort) {
  174. return nil, errors.New("unable to bind to primary port")
  175. }
  176. nodesByUserPtrLock.Lock()
  177. nodesByUserPtr[uintptr(unsafe.Pointer(n))] = n
  178. nodesByUserPtrLock.Unlock()
  179. cPath := C.CString(basePath)
  180. n.gn = C.ZT_GoNode_new(cPath, C.uintptr_t(uintptr(unsafe.Pointer(n))))
  181. C.free(unsafe.Pointer(cPath))
  182. if n.gn == nil {
  183. n.log.Println("FATAL: node initialization failed")
  184. nodesByUserPtrLock.Lock()
  185. delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
  186. nodesByUserPtrLock.Unlock()
  187. return nil, ErrNodeInitFailed
  188. }
  189. n.zn = (*C.ZT_Node)(C.ZT_GoNode_getNode(n.gn))
  190. var ns C.ZT_NodeStatus
  191. C.ZT_Node_status(unsafe.Pointer(n.zn), &ns)
  192. idString := C.GoString(ns.secretIdentity)
  193. n.id, err = NewIdentityFromString(idString)
  194. if err != nil {
  195. n.log.Printf("FATAL: node's identity does not seem valid (%s)", string(idString))
  196. nodesByUserPtrLock.Lock()
  197. delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
  198. nodesByUserPtrLock.Unlock()
  199. C.ZT_GoNode_delete(n.gn)
  200. return nil, err
  201. }
  202. n.apiServer, n.tcpApiServer, err = createAPIServer(basePath, n)
  203. if err != nil {
  204. n.log.Printf("FATAL: unable to start API server: %s", err.Error())
  205. nodesByUserPtrLock.Lock()
  206. delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
  207. nodesByUserPtrLock.Unlock()
  208. C.ZT_GoNode_delete(n.gn)
  209. return nil, err
  210. }
  211. n.online = 0
  212. n.running = 1
  213. n.runLock.Lock() // used to block Close() until below gorountine exits
  214. go func() {
  215. lastMaintenanceRun := int64(0)
  216. var previousExplicitExternalAddresses []ExternalAddress
  217. var portsA [3]int
  218. for atomic.LoadUint32(&n.running) != 0 {
  219. time.Sleep(1 * time.Second)
  220. now := TimeMs()
  221. if (now - lastMaintenanceRun) >= 30000 {
  222. lastMaintenanceRun = now
  223. n.localConfigLock.RLock()
  224. // Get local physical interface addresses, excluding blacklisted and ZeroTier-created interfaces
  225. interfaceAddresses := make(map[string]net.IP)
  226. ifs, _ := net.Interfaces()
  227. if len(ifs) > 0 {
  228. n.networksLock.RLock()
  229. scanInterfaces:
  230. for _, i := range ifs {
  231. for _, bl := range n.localConfig.Settings.InterfacePrefixBlacklist {
  232. if strings.HasPrefix(strings.ToLower(i.Name), strings.ToLower(bl)) {
  233. continue scanInterfaces
  234. }
  235. }
  236. m, _ := NewMACFromBytes(i.HardwareAddr)
  237. if _, isZeroTier := n.networksByMAC[m]; !isZeroTier {
  238. addrs, _ := i.Addrs()
  239. for _, a := range addrs {
  240. ipn, _ := a.(*net.IPNet)
  241. if ipn != nil && len(ipn.IP) > 0 && !ipn.IP.IsLinkLocalUnicast() && !ipn.IP.IsMulticast() {
  242. interfaceAddresses[ipn.IP.String()] = ipn.IP
  243. }
  244. }
  245. }
  246. }
  247. n.networksLock.RUnlock()
  248. }
  249. interfaceAddressesChanged := false
  250. ports := portsA[:0]
  251. if n.localConfig.Settings.PrimaryPort > 0 && n.localConfig.Settings.PrimaryPort < 65536 {
  252. ports = append(ports, n.localConfig.Settings.PrimaryPort)
  253. }
  254. if n.localConfig.Settings.SecondaryPort > 0 && n.localConfig.Settings.SecondaryPort < 65536 {
  255. ports = append(ports, n.localConfig.Settings.SecondaryPort)
  256. }
  257. // Open or close locally bound UDP ports for each local interface address.
  258. // This opens ports if they are not already open and then closes ports if
  259. // they are open but no longer seem to exist.
  260. n.interfaceAddressesLock.Lock()
  261. for astr, ipn := range interfaceAddresses {
  262. if _, alreadyKnown := n.interfaceAddresses[astr]; !alreadyKnown {
  263. interfaceAddressesChanged = true
  264. ipCstr := C.CString(ipn.String())
  265. for _, p := range ports {
  266. n.log.Printf("UDP binding to port %d on interface %s", p, astr)
  267. C.ZT_GoNode_phyStartListen(n.gn, nil, ipCstr, C.int(p))
  268. }
  269. C.free(unsafe.Pointer(ipCstr))
  270. }
  271. }
  272. for astr, ipn := range n.interfaceAddresses {
  273. if _, stillPresent := interfaceAddresses[astr]; !stillPresent {
  274. interfaceAddressesChanged = true
  275. ipCstr := C.CString(ipn.String())
  276. for _, p := range ports {
  277. n.log.Printf("UDP closing socket bound to port %d on interface %s", p, astr)
  278. C.ZT_GoNode_phyStopListen(n.gn, nil, ipCstr, C.int(p))
  279. }
  280. C.free(unsafe.Pointer(ipCstr))
  281. }
  282. }
  283. n.interfaceAddresses = interfaceAddresses
  284. n.interfaceAddressesLock.Unlock()
  285. // Update node's understanding of our interface addressaes if they've changed
  286. if interfaceAddressesChanged || reflect.DeepEqual(n.localConfig.Settings.ExplicitAddresses, previousExplicitExternalAddresses) {
  287. externalAddresses := make(map[[3]uint64]*ExternalAddress)
  288. for _, ip := range interfaceAddresses {
  289. for _, p := range ports {
  290. a := &ExternalAddress{
  291. InetAddress: InetAddress{
  292. IP: ip,
  293. Port: p,
  294. },
  295. Permanent: false,
  296. }
  297. externalAddresses[a.key()] = a
  298. }
  299. }
  300. for _, a := range n.localConfig.Settings.ExplicitAddresses {
  301. externalAddresses[a.key()] = &a
  302. }
  303. if len(externalAddresses) > 0 {
  304. cAddrs := make([]C.ZT_InterfaceAddress, len(externalAddresses))
  305. cAddrCount := 0
  306. for _, a := range externalAddresses {
  307. makeSockaddrStorage(a.IP, a.Port, &(cAddrs[cAddrCount].address))
  308. cAddrs[cAddrCount].permanent = 0
  309. if a.Permanent {
  310. cAddrs[cAddrCount].permanent = 1
  311. }
  312. cAddrCount++
  313. }
  314. C.ZT_Node_setInterfaceAddresses(unsafe.Pointer(n.zn), &cAddrs[0], C.uint(cAddrCount))
  315. } else {
  316. C.ZT_Node_setInterfaceAddresses(unsafe.Pointer(n.zn), nil, 0)
  317. }
  318. }
  319. // Trim log if it's gone over its size limit
  320. if n.localConfig.Settings.LogSizeMax > 0 && n.logW != nil {
  321. _ = n.logW.trim(n.localConfig.Settings.LogSizeMax*1024, 0.5, true)
  322. }
  323. n.localConfigLock.RUnlock()
  324. }
  325. }
  326. n.runLock.Unlock() // signal Close() that maintenance goroutine is done
  327. }()
  328. return n, nil
  329. }
  330. // Close closes this Node and frees its underlying C++ Node structures
  331. func (n *Node) Close() {
  332. if atomic.SwapUint32(&n.running, 0) != 0 {
  333. if n.apiServer != nil {
  334. _ = n.apiServer.Close()
  335. }
  336. if n.tcpApiServer != nil {
  337. _ = n.tcpApiServer.Close()
  338. }
  339. C.ZT_GoNode_delete(n.gn)
  340. n.runLock.Lock() // wait for maintenance gorountine to die
  341. n.runLock.Unlock()
  342. nodesByUserPtrLock.Lock()
  343. delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
  344. nodesByUserPtrLock.Unlock()
  345. }
  346. }
  347. // Address returns this node's address
  348. func (n *Node) Address() Address { return n.id.address }
  349. // Identity returns this node's identity (including secret portion)
  350. func (n *Node) Identity() *Identity { return n.id }
  351. // Online returns true if this node can reach something
  352. func (n *Node) Online() bool { return atomic.LoadUint32(&n.online) != 0 }
  353. // InterfaceAddresses are external IPs belonging to physical interfaces on this machine
  354. func (n *Node) InterfaceAddresses() []net.IP {
  355. var ea []net.IP
  356. n.interfaceAddressesLock.Lock()
  357. for _, a := range n.interfaceAddresses {
  358. ea = append(ea, a)
  359. }
  360. n.interfaceAddressesLock.Unlock()
  361. sort.Slice(ea, func(a, b int) bool { return bytes.Compare(ea[a], ea[b]) < 0 })
  362. return ea
  363. }
  364. // LocalConfig gets this node's local configuration
  365. func (n *Node) LocalConfig() LocalConfig {
  366. n.localConfigLock.RLock()
  367. defer n.localConfigLock.RUnlock()
  368. return n.localConfig
  369. }
  370. // SetLocalConfig updates this node's local configuration
  371. func (n *Node) SetLocalConfig(lc *LocalConfig) (restartRequired bool, err error) {
  372. n.networksLock.RLock()
  373. n.localConfigLock.Lock()
  374. defer n.localConfigLock.Unlock()
  375. defer n.networksLock.RUnlock()
  376. for nid, nc := range lc.Network {
  377. nw := n.networks[nid]
  378. if nw != nil {
  379. nw.SetLocalSettings(&nc)
  380. }
  381. }
  382. if n.localConfig.Settings.PrimaryPort != lc.Settings.PrimaryPort || n.localConfig.Settings.SecondaryPort != lc.Settings.SecondaryPort {
  383. restartRequired = true
  384. }
  385. if lc.Settings.LogSizeMax < 0 {
  386. n.log = nullLogger
  387. _ = n.logW.Close()
  388. n.logW = nil
  389. } else if n.logW != nil {
  390. n.logW, err = sizeLimitWriterOpen(path.Join(n.basePath, "service.log"))
  391. if err == nil {
  392. n.log = log.New(n.logW, "", log.LstdFlags)
  393. } else {
  394. n.log = nullLogger
  395. n.logW = nil
  396. }
  397. }
  398. n.localConfig = *lc
  399. return
  400. }
  401. // Join joins a network
  402. // If tap is nil, the default system tap for this OS/platform is used (if available).
  403. func (n *Node) Join(nwid NetworkID, settings *NetworkLocalSettings, tap Tap) (*Network, error) {
  404. n.networksLock.RLock()
  405. if nw, have := n.networks[nwid]; have {
  406. n.log.Printf("join network %.16x ignored: already a member", nwid)
  407. if settings != nil {
  408. nw.SetLocalSettings(settings)
  409. }
  410. return nw, nil
  411. }
  412. n.networksLock.RUnlock()
  413. if tap != nil {
  414. panic("non-native taps not yet implemented")
  415. }
  416. ntap := C.ZT_GoNode_join(n.gn, C.uint64_t(nwid))
  417. if ntap == nil {
  418. n.log.Printf("join network %.16x failed: tap device failed to initialize (check drivers / kernel modules)", uint64(nwid))
  419. return nil, ErrTapInitFailed
  420. }
  421. nw, err := newNetwork(n, nwid, &nativeTap{tap: unsafe.Pointer(ntap), enabled: 1})
  422. if err != nil {
  423. n.log.Printf("join network %.16x failed: network failed to initialize: %s", nwid, err.Error())
  424. C.ZT_GoNode_leave(n.gn, C.uint64_t(nwid))
  425. return nil, err
  426. }
  427. n.networksLock.Lock()
  428. n.networks[nwid] = nw
  429. n.networksLock.Unlock()
  430. if settings != nil {
  431. nw.SetLocalSettings(settings)
  432. }
  433. return nw, nil
  434. }
  435. // Leave leaves a network
  436. func (n *Node) Leave(nwid NetworkID) error {
  437. n.log.Printf("leaving network %.16x", nwid)
  438. n.networksLock.Lock()
  439. nw := n.networks[nwid]
  440. delete(n.networks, nwid)
  441. n.networksLock.Unlock()
  442. if nw != nil {
  443. nw.leaving()
  444. }
  445. C.ZT_GoNode_leave(n.gn, C.uint64_t(nwid))
  446. return nil
  447. }
  448. // GetNetwork looks up a network by ID or returns nil if not joined
  449. func (n *Node) GetNetwork(nwid NetworkID) *Network {
  450. n.networksLock.RLock()
  451. nw := n.networks[nwid]
  452. n.networksLock.RUnlock()
  453. return nw
  454. }
  455. // Networks returns a list of networks that this node has joined
  456. func (n *Node) Networks() []*Network {
  457. var nws []*Network
  458. n.networksLock.RLock()
  459. for _, nw := range n.networks {
  460. nws = append(nws, nw)
  461. }
  462. n.networksLock.RUnlock()
  463. return nws
  464. }
  465. // Peers retrieves a list of current peers
  466. func (n *Node) Peers() []*Peer {
  467. var peers []*Peer
  468. pl := C.ZT_Node_peers(unsafe.Pointer(n.zn))
  469. if pl != nil {
  470. for i := uintptr(0); i < uintptr(pl.peerCount); i++ {
  471. p := (*C.ZT_Peer)(unsafe.Pointer(uintptr(unsafe.Pointer(pl.peers)) + (i * C.sizeof_ZT_Peer)))
  472. p2 := new(Peer)
  473. p2.Address = Address(p.address)
  474. p2.Version = [3]int{int(p.versionMajor), int(p.versionMinor), int(p.versionRev)}
  475. p2.Latency = int(p.latency)
  476. p2.Role = int(p.role)
  477. p2.Paths = make([]Path, 0, int(p.pathCount))
  478. for j := uintptr(0); j < uintptr(p.pathCount); j++ {
  479. pt := &p.paths[j]
  480. if pt.alive != 0 {
  481. a := sockaddrStorageToUDPAddr(&pt.address)
  482. if a != nil {
  483. p2.Paths = append(p2.Paths, Path{
  484. IP: a.IP,
  485. Port: a.Port,
  486. LastSend: int64(pt.lastSend),
  487. LastReceive: int64(pt.lastReceive),
  488. TrustedPathID: uint64(pt.trustedPathId),
  489. })
  490. }
  491. }
  492. }
  493. p2.Clock = TimeMs()
  494. peers = append(peers, p2)
  495. }
  496. C.ZT_Node_freeQueryResult(unsafe.Pointer(n.zn), unsafe.Pointer(pl))
  497. }
  498. sort.Slice(peers, func(a, b int) bool {
  499. return peers[a].Address < peers[b].Address
  500. })
  501. return peers
  502. }
  503. //////////////////////////////////////////////////////////////////////////////
  504. func (n *Node) multicastSubscribe(nwid uint64, mg *MulticastGroup) {
  505. C.ZT_Node_multicastSubscribe(unsafe.Pointer(n.zn), nil, C.uint64_t(nwid), C.uint64_t(mg.MAC), C.ulong(mg.ADI))
  506. }
  507. func (n *Node) multicastUnsubscribe(nwid uint64, mg *MulticastGroup) {
  508. C.ZT_Node_multicastUnsubscribe(unsafe.Pointer(n.zn), C.uint64_t(nwid), C.uint64_t(mg.MAC), C.ulong(mg.ADI))
  509. }
  510. func (n *Node) pathCheck(ztAddress Address, af int, ip net.IP, port int) bool {
  511. n.localConfigLock.RLock()
  512. defer n.localConfigLock.RUnlock()
  513. for cidr, phy := range n.localConfig.Physical {
  514. if phy.Blacklist {
  515. _, ipn, _ := net.ParseCIDR(cidr)
  516. if ipn != nil && ipn.Contains(ip) {
  517. return false
  518. }
  519. }
  520. }
  521. return true
  522. }
  523. func (n *Node) pathLookup(id *Identity) (net.IP, int) {
  524. n.localConfigLock.RLock()
  525. defer n.localConfigLock.RUnlock()
  526. virt := n.localConfig.Virtual[id.address]
  527. if len(virt.Try) > 0 {
  528. idx := rand.Int() % len(virt.Try)
  529. return virt.Try[idx].IP, virt.Try[idx].Port
  530. }
  531. return nil, 0
  532. }
  533. func (n *Node) makeStateObjectPath(objType int, id [2]uint64) (string, bool) {
  534. var fp string
  535. secret := false
  536. switch objType {
  537. case C.ZT_STATE_OBJECT_IDENTITY_PUBLIC:
  538. fp = path.Join(n.basePath, "identity.public")
  539. case C.ZT_STATE_OBJECT_IDENTITY_SECRET:
  540. fp = path.Join(n.basePath, "identity.secret")
  541. secret = true
  542. case C.ZT_STATE_OBJECT_PEER:
  543. fp = path.Join(n.basePath, "peers.d")
  544. _ = os.Mkdir(fp, 0700)
  545. fp = path.Join(fp, fmt.Sprintf("%.10x.peer", id[0]))
  546. secret = true
  547. case C.ZT_STATE_OBJECT_NETWORK_CONFIG:
  548. fp = path.Join(n.basePath, "networks.d")
  549. _ = os.Mkdir(fp, 0755)
  550. fp = path.Join(fp, fmt.Sprintf("%.16x.conf", id[0]))
  551. case C.ZT_STATE_OBJECT_ROOTS:
  552. fp = path.Join(n.basePath, "roots")
  553. }
  554. return fp, secret
  555. }
  556. func (n *Node) stateObjectPut(objType int, id [2]uint64, data []byte) {
  557. fp, secret := n.makeStateObjectPath(objType, id)
  558. if len(fp) > 0 {
  559. fileMode := os.FileMode(0644)
  560. if secret {
  561. fileMode = os.FileMode(0600)
  562. }
  563. _ = ioutil.WriteFile(fp, data, fileMode)
  564. if secret {
  565. _ = acl.Chmod(fp, 0600) // this emulates Unix chmod on Windows and uses os.Chmod on Unix-type systems
  566. }
  567. }
  568. }
  569. func (n *Node) stateObjectDelete(objType int, id [2]uint64) {
  570. fp, _ := n.makeStateObjectPath(objType, id)
  571. if len(fp) > 0 {
  572. _ = os.Remove(fp)
  573. }
  574. }
  575. func (n *Node) stateObjectGet(objType int, id [2]uint64) ([]byte, bool) {
  576. fp, _ := n.makeStateObjectPath(objType, id)
  577. if len(fp) > 0 {
  578. fd, err := ioutil.ReadFile(fp)
  579. if err != nil {
  580. return nil, false
  581. }
  582. return fd, true
  583. }
  584. return nil, false
  585. }
  586. func (n *Node) handleTrace(traceMessage string) {
  587. if len(traceMessage) > 0 {
  588. n.log.Print("TRACE: " + traceMessage)
  589. }
  590. }
  591. func (n *Node) handleUserMessage(originAddress, messageTypeID uint64, data []byte) {
  592. }
  593. //////////////////////////////////////////////////////////////////////////////
  594. // These are callbacks called by the core and GoGlue stuff to talk to the
  595. // service. These launch gorountines to do their work where possible to
  596. // avoid blocking anything in the core.
  597. //export goPathCheckFunc
  598. func goPathCheckFunc(gn unsafe.Pointer, ztAddress C.uint64_t, af C.int, ip unsafe.Pointer, port C.int) C.int {
  599. nodesByUserPtrLock.RLock()
  600. node := nodesByUserPtr[uintptr(gn)]
  601. nodesByUserPtrLock.RUnlock()
  602. var nip net.IP
  603. if af == syscall.AF_INET {
  604. nip = ((*[4]byte)(ip))[:]
  605. } else if af == syscall.AF_INET6 {
  606. nip = ((*[16]byte)(ip))[:]
  607. } else {
  608. return 0
  609. }
  610. if node != nil && len(nip) > 0 && node.pathCheck(Address(ztAddress), int(af), nip, int(port)) {
  611. return 1
  612. }
  613. return 0
  614. }
  615. //export goPathLookupFunc
  616. func goPathLookupFunc(gn unsafe.Pointer, ztAddress C.uint64_t, desiredFamily int, identity, familyP, ipP, portP unsafe.Pointer) C.int {
  617. nodesByUserPtrLock.RLock()
  618. node := nodesByUserPtr[uintptr(gn)]
  619. nodesByUserPtrLock.RUnlock()
  620. if node == nil {
  621. return 0
  622. }
  623. id, err := newIdentityFromCIdentity(identity)
  624. if err != nil {
  625. return 0
  626. }
  627. ip, port := node.pathLookup(id)
  628. if len(ip) > 0 && port > 0 && port <= 65535 {
  629. ip4 := ip.To4()
  630. if len(ip4) == 4 {
  631. *((*C.int)(familyP)) = C.int(syscall.AF_INET)
  632. copy((*[4]byte)(ipP)[:], ip4)
  633. *((*C.int)(portP)) = C.int(port)
  634. return 1
  635. } else if len(ip) == 16 {
  636. *((*C.int)(familyP)) = C.int(syscall.AF_INET6)
  637. copy((*[16]byte)(ipP)[:], ip)
  638. *((*C.int)(portP)) = C.int(port)
  639. return 1
  640. }
  641. }
  642. return 0
  643. }
  644. //export goStateObjectPutFunc
  645. func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, len C.int) {
  646. go func() {
  647. nodesByUserPtrLock.RLock()
  648. node := nodesByUserPtr[uintptr(gn)]
  649. nodesByUserPtrLock.RUnlock()
  650. if node == nil {
  651. return
  652. }
  653. if len < 0 {
  654. node.stateObjectDelete(int(objType), *((*[2]uint64)(id)))
  655. } else {
  656. node.stateObjectPut(int(objType), *((*[2]uint64)(id)), C.GoBytes(data, len))
  657. }
  658. }()
  659. }
  660. //export goStateObjectGetFunc
  661. func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, bufSize C.uint) C.int {
  662. nodesByUserPtrLock.RLock()
  663. node := nodesByUserPtr[uintptr(gn)]
  664. nodesByUserPtrLock.RUnlock()
  665. if node == nil {
  666. return -1
  667. }
  668. tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
  669. if found && len(tmp) < int(bufSize) {
  670. if len(tmp) > 0 {
  671. C.memcpy(data, unsafe.Pointer(&(tmp[0])), C.ulong(len(tmp)))
  672. }
  673. return C.int(len(tmp))
  674. }
  675. return -1
  676. }
  677. //export goVirtualNetworkConfigFunc
  678. func goVirtualNetworkConfigFunc(gn, _ unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) {
  679. go func() {
  680. nodesByUserPtrLock.RLock()
  681. node := nodesByUserPtr[uintptr(gn)]
  682. nodesByUserPtrLock.RUnlock()
  683. if node == nil {
  684. return
  685. }
  686. node.networksLock.RLock()
  687. network := node.networks[NetworkID(nwid)]
  688. node.networksLock.RUnlock()
  689. if network != nil {
  690. switch int(op) {
  691. case networkConfigOpUp, networkConfigOpUpdate:
  692. ncc := (*C.ZT_VirtualNetworkConfig)(conf)
  693. if network.networkConfigRevision() > uint64(ncc.netconfRevision) {
  694. return
  695. }
  696. var nc NetworkConfig
  697. nc.ID = NetworkID(ncc.nwid)
  698. nc.MAC = MAC(ncc.mac)
  699. nc.Name = C.GoString(&ncc.name[0])
  700. nc.Status = int(ncc.status)
  701. nc.Type = int(ncc._type)
  702. nc.MTU = int(ncc.mtu)
  703. nc.Bridge = ncc.bridge != 0
  704. nc.BroadcastEnabled = ncc.broadcastEnabled != 0
  705. nc.NetconfRevision = uint64(ncc.netconfRevision)
  706. for i := 0; i < int(ncc.assignedAddressCount); i++ {
  707. a := sockaddrStorageToIPNet(&ncc.assignedAddresses[i])
  708. if a != nil {
  709. nc.AssignedAddresses = append(nc.AssignedAddresses, *a)
  710. }
  711. }
  712. for i := 0; i < int(ncc.routeCount); i++ {
  713. tgt := sockaddrStorageToIPNet(&ncc.routes[i].target)
  714. viaN := sockaddrStorageToIPNet(&ncc.routes[i].via)
  715. var via *net.IP
  716. if viaN != nil && len(viaN.IP) > 0 {
  717. via = &viaN.IP
  718. }
  719. if tgt != nil {
  720. nc.Routes = append(nc.Routes, Route{
  721. Target: *tgt,
  722. Via: via,
  723. Flags: uint16(ncc.routes[i].flags),
  724. Metric: uint16(ncc.routes[i].metric),
  725. })
  726. }
  727. }
  728. network.updateConfig(&nc, nil)
  729. }
  730. }
  731. }()
  732. }
  733. //export goZtEvent
  734. func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
  735. go func() {
  736. nodesByUserPtrLock.RLock()
  737. node := nodesByUserPtr[uintptr(gn)]
  738. nodesByUserPtrLock.RUnlock()
  739. if node == nil {
  740. return
  741. }
  742. switch eventType {
  743. case C.ZT_EVENT_OFFLINE:
  744. atomic.StoreUint32(&node.online, 0)
  745. case C.ZT_EVENT_ONLINE:
  746. atomic.StoreUint32(&node.online, 1)
  747. case C.ZT_EVENT_TRACE:
  748. node.handleTrace(C.GoString((*C.char)(data)))
  749. case C.ZT_EVENT_USER_MESSAGE:
  750. um := (*C.ZT_UserMessage)(data)
  751. node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
  752. }
  753. }()
  754. }