node.go 27 KB

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