node.go 25 KB

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