node.go 27 KB

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