mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
A bunch more go plumbing.
This commit is contained in:
parent
1b2a4f00f2
commit
9babfcb9b6
7 changed files with 128 additions and 56 deletions
|
@ -193,13 +193,13 @@ func readLocator(s string) *zerotier.Locator {
|
||||||
func networkStatusStr(status int) string {
|
func networkStatusStr(status int) string {
|
||||||
switch status {
|
switch status {
|
||||||
case zerotier.NetworkStatusNotFound:
|
case zerotier.NetworkStatusNotFound:
|
||||||
return "NOTFOUND"
|
return "not-found"
|
||||||
case zerotier.NetworkStatusAccessDenied:
|
case zerotier.NetworkStatusAccessDenied:
|
||||||
return "ACCESSDENIED"
|
return "access-denied"
|
||||||
case zerotier.NetworkStatusRequestConfiguration:
|
case zerotier.NetworkStatusRequestingConfiguration:
|
||||||
return "UPDATING"
|
return "updating"
|
||||||
case zerotier.NetworkStatusOK:
|
case zerotier.NetworkStatusOK:
|
||||||
return "OK"
|
return "ok"
|
||||||
}
|
}
|
||||||
return "???"
|
return "???"
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ func NewAddressFromBytes(b []byte) (Address, error) {
|
||||||
return Address((uint64(b[0]) << 32) | (uint64(b[1]) << 24) | (uint64(b[2]) << 16) | (uint64(b[3]) << 8) | uint64(b[4])), nil
|
return Address((uint64(b[0]) << 32) | (uint64(b[1]) << 24) | (uint64(b[2]) << 16) | (uint64(b[3]) << 8) | uint64(b[4])), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy this address to a byte array, which must be 5 bytes in length or this will panic.
|
// CopyTo writes this address to five bytes.
|
||||||
|
// If b cannot store five bytes this will panic.
|
||||||
func (a Address) CopyTo(b []byte) {
|
func (a Address) CopyTo(b []byte) {
|
||||||
_ = b[4]
|
_ = b[4]
|
||||||
b[0] = byte(a >> 32)
|
b[0] = byte(a >> 32)
|
||||||
|
@ -52,7 +53,7 @@ func (a Address) CopyTo(b []byte) {
|
||||||
// IsReserved returns true if this address is reserved and therefore is not valid for a real node.
|
// IsReserved returns true if this address is reserved and therefore is not valid for a real node.
|
||||||
func (a Address) IsReserved() bool { return a == 0 || (a>>32) == 0xff }
|
func (a Address) IsReserved() bool { return a == 0 || (a>>32) == 0xff }
|
||||||
|
|
||||||
// String returns this address's 10-digit hex identifier
|
// String returns this address's 10-digit hex identifier.
|
||||||
func (a Address) String() string {
|
func (a Address) String() string {
|
||||||
return fmt.Sprintf("%.10x", uint64(a))
|
return fmt.Sprintf("%.10x", uint64(a))
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ func createAPIServer(basePath string, node *Node) (*http.Server, *http.Server, e
|
||||||
}
|
}
|
||||||
var nw APINetwork
|
var nw APINetwork
|
||||||
if apiReadObj(out, req, &nw) == nil {
|
if apiReadObj(out, req, &nw) == nil {
|
||||||
n := node.GetNetwork(nw.ID)
|
n := node.Network(nw.ID)
|
||||||
if n == nil {
|
if n == nil {
|
||||||
if nw.ControllerFingerprint != nil && nw.ControllerFingerprint.Address != nw.ID.Controller() {
|
if nw.ControllerFingerprint != nil && nw.ControllerFingerprint.Address != nw.ID.Controller() {
|
||||||
_ = apiSendObj(out, req, http.StatusBadRequest, &APIErr{"fingerprint's address does not match what should be the controller's address"})
|
_ = apiSendObj(out, req, http.StatusBadRequest, &APIErr{"fingerprint's address does not match what should be the controller's address"})
|
||||||
|
|
|
@ -24,11 +24,20 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FingerprintHashSize is the length of a fingerprint hash in bytes.
|
||||||
|
const FingerprintHashSize = 48
|
||||||
|
|
||||||
|
// Fingerprint bundles an address with an optional SHA384 full hash of the identity's key(s).
|
||||||
type Fingerprint struct {
|
type Fingerprint struct {
|
||||||
Address Address
|
Address Address
|
||||||
Hash []byte
|
Hash []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFingerprintFromString decodes a string-format fingerprint.
|
||||||
|
// A fingerprint has the format address-hash, where address is a 10-digit
|
||||||
|
// ZeroTier address and a hash is a base32-encoded SHA384 hash. Fingerprints
|
||||||
|
// can be missing the hash in which case they are represented the same as
|
||||||
|
// an Address and the hash field will be nil.
|
||||||
func NewFingerprintFromString(fps string) (*Fingerprint, error) {
|
func NewFingerprintFromString(fps string) (*Fingerprint, error) {
|
||||||
if len(fps) < AddressStringLength {
|
if len(fps) < AddressStringLength {
|
||||||
return nil, ErrInvalidZeroTierAddress
|
return nil, ErrInvalidZeroTierAddress
|
||||||
|
@ -66,22 +75,28 @@ func newFingerprintFromCFingerprint(cfp *C.ZT_Fingerprint) *Fingerprint {
|
||||||
return &fp
|
return &fp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns an address or a full address-hash depenting on whether a hash is present.
|
||||||
func (fp *Fingerprint) String() string {
|
func (fp *Fingerprint) String() string {
|
||||||
if len(fp.Hash) == 48 {
|
if len(fp.Hash) == FingerprintHashSize {
|
||||||
return fmt.Sprintf("%.10x-%s", uint64(fp.Address), Base32StdLowerCase.EncodeToString(fp.Hash))
|
return fmt.Sprintf("%.10x-%s", uint64(fp.Address), Base32StdLowerCase.EncodeToString(fp.Hash))
|
||||||
}
|
}
|
||||||
return fp.Address.String()
|
return fp.Address.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equals test for full equality with another fingerprint (including hash).
|
||||||
func (fp *Fingerprint) Equals(fp2 *Fingerprint) bool {
|
func (fp *Fingerprint) Equals(fp2 *Fingerprint) bool {
|
||||||
return fp.Address == fp2.Address && bytes.Equal(fp.Hash[:], fp2.Hash[:])
|
return fp.Address == fp2.Address && bytes.Equal(fp.Hash[:], fp2.Hash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fp *Fingerprint) cFingerprint() *C.ZT_Fingerprint {
|
// BestSpecificityEquals compares either just the addresses or also the hashes if both are present.
|
||||||
var apifp C.ZT_Fingerprint
|
func (fp *Fingerprint) BestSpecificityEquals(fp2 *Fingerprint) bool {
|
||||||
apifp.address = C.uint64_t(fp.Address)
|
if fp2 == nil || fp.Address != fp2.Address {
|
||||||
copy((*[48]byte)(unsafe.Pointer(&apifp.hash[0]))[:], fp.Hash[:])
|
return false
|
||||||
return &apifp
|
}
|
||||||
|
if len(fp.Hash) == FingerprintHashSize && len(fp2.Hash) == FingerprintHashSize {
|
||||||
|
return bytes.Equal(fp.Hash, fp2.Hash)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fp *Fingerprint) MarshalJSON() ([]byte, error) {
|
func (fp *Fingerprint) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -99,3 +114,10 @@ func (fp *Fingerprint) UnmarshalJSON(j []byte) error {
|
||||||
fp.Hash = fp2.Hash
|
fp.Hash = fp2.Hash
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fp *Fingerprint) cFingerprint() *C.ZT_Fingerprint {
|
||||||
|
var apifp C.ZT_Fingerprint
|
||||||
|
apifp.address = C.uint64_t(fp.Address)
|
||||||
|
copy((*[48]byte)(unsafe.Pointer(&apifp.hash[0]))[:], fp.Hash[:])
|
||||||
|
return &apifp
|
||||||
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ func (id *Identity) initCIdentityPtr() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIdentity generates a new identity of the selected type
|
// NewIdentity generates a new identity of the selected type.
|
||||||
func NewIdentity(identityType int) (*Identity, error) {
|
func NewIdentity(identityType int) (*Identity, error) {
|
||||||
switch identityType {
|
switch identityType {
|
||||||
case C.ZT_IDENTITY_TYPE_C25519:
|
case C.ZT_IDENTITY_TYPE_C25519:
|
||||||
|
@ -160,7 +160,7 @@ func NewIdentityFromString(s string) (*Identity, error) {
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns this identity's address
|
// Address returns this identity's address.
|
||||||
func (id *Identity) Address() Address { return id.address }
|
func (id *Identity) Address() Address { return id.address }
|
||||||
|
|
||||||
// HasPrivate returns true if this identity has its own private portion.
|
// HasPrivate returns true if this identity has its own private portion.
|
||||||
|
@ -172,7 +172,8 @@ func (id *Identity) Fingerprint() *Fingerprint {
|
||||||
return newFingerprintFromCFingerprint(C.ZT_Identity_fingerprint(id.cid))
|
return newFingerprintFromCFingerprint(C.ZT_Identity_fingerprint(id.cid))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrivateKeyString returns the full identity.secret if the private key is set, or an empty string if no private key is set.
|
// PrivateKeyString returns the full identity.secret if the private key is set,
|
||||||
|
// or an empty string if no private key is set.
|
||||||
func (id *Identity) PrivateKeyString() string {
|
func (id *Identity) PrivateKeyString() string {
|
||||||
switch id.idtype {
|
switch id.idtype {
|
||||||
case IdentityTypeC25519:
|
case IdentityTypeC25519:
|
||||||
|
@ -253,12 +254,10 @@ func (id *Identity) Equals(id2 *Identity) bool {
|
||||||
return id.address == id2.address && id.idtype == id2.idtype && bytes.Equal(id.publicKey, id2.publicKey) && bytes.Equal(id.privateKey, id2.privateKey)
|
return id.address == id2.address && id.idtype == id2.idtype && bytes.Equal(id.publicKey, id2.publicKey) && bytes.Equal(id.privateKey, id2.privateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON marshals this Identity in its string format (private key is never included)
|
|
||||||
func (id *Identity) MarshalJSON() ([]byte, error) {
|
func (id *Identity) MarshalJSON() ([]byte, error) {
|
||||||
return []byte("\"" + id.String() + "\""), nil
|
return []byte("\"" + id.String() + "\""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON unmarshals this Identity from a string
|
|
||||||
func (id *Identity) UnmarshalJSON(j []byte) error {
|
func (id *Identity) UnmarshalJSON(j []byte) error {
|
||||||
var s string
|
var s string
|
||||||
err := json.Unmarshal(j, &s)
|
err := json.Unmarshal(j, &s)
|
||||||
|
|
|
@ -155,7 +155,7 @@ func newNetwork(node *Node, id NetworkID, t Tap) (*Network, error) {
|
||||||
config: NetworkConfig{
|
config: NetworkConfig{
|
||||||
ID: id,
|
ID: id,
|
||||||
MAC: m,
|
MAC: m,
|
||||||
Status: NetworkStatusRequestConfiguration,
|
Status: NetworkStatusRequestingConfiguration,
|
||||||
Type: NetworkTypePrivate,
|
Type: NetworkTypePrivate,
|
||||||
MTU: int(defaultVirtualNetworkMTU),
|
MTU: int(defaultVirtualNetworkMTU),
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,9 +47,11 @@ var nullLogger = log.New(ioutil.Discard, "", 0)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NetworkIDStringLength = 16
|
NetworkIDStringLength = 16
|
||||||
|
NEtworkIDLength = 8
|
||||||
AddressStringLength = 10
|
AddressStringLength = 10
|
||||||
|
AddressLength = 5
|
||||||
|
|
||||||
NetworkStatusRequestConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
|
NetworkStatusRequestingConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
|
||||||
NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
|
NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
|
||||||
NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED
|
NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED
|
||||||
NetworkStatusNotFound int = C.ZT_NETWORK_STATUS_NOT_FOUND
|
NetworkStatusNotFound int = C.ZT_NETWORK_STATUS_NOT_FOUND
|
||||||
|
@ -62,7 +64,8 @@ const (
|
||||||
|
|
||||||
defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU
|
defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU
|
||||||
|
|
||||||
// maxCNodeRefs is the maximum number of Node instances that can be created in this process (increasing is fine)
|
// maxCNodeRefs is the maximum number of Node instances that can be created in this process.
|
||||||
|
// This is perfectly fine to increase.
|
||||||
maxCNodeRefs = 8
|
maxCNodeRefs = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,7 +76,10 @@ var (
|
||||||
CoreVersionRevision int
|
CoreVersionRevision int
|
||||||
CoreVersionBuild int
|
CoreVersionBuild int
|
||||||
|
|
||||||
|
// cNodeRefs maps an index to a *Node
|
||||||
cNodeRefs [maxCNodeRefs]*Node
|
cNodeRefs [maxCNodeRefs]*Node
|
||||||
|
|
||||||
|
// cNodeRefsUsed maps an index to whether or not the corresponding cNodeRefs[] entry is used.
|
||||||
cNodeRefUsed [maxCNodeRefs]uint32
|
cNodeRefUsed [maxCNodeRefs]uint32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +98,9 @@ type Node struct {
|
||||||
// Time this node was created
|
// Time this node was created
|
||||||
startupTime int64
|
startupTime int64
|
||||||
|
|
||||||
// an arbitrary uintptr given to the core as its pointer back to Go's Node instance
|
// an arbitrary uintptr given to the core as its pointer back to Go's Node instance.
|
||||||
|
// This is an index in the cNodeRefs array, which is synchronized by way of a set of
|
||||||
|
// used/free booleans accessed atomically.
|
||||||
cPtr uintptr
|
cPtr uintptr
|
||||||
|
|
||||||
// networks contains networks we have joined, and networksByMAC by their local MAC address
|
// networks contains networks we have joined, and networksByMAC by their local MAC address
|
||||||
|
@ -100,13 +108,14 @@ type Node struct {
|
||||||
networksByMAC map[MAC]*Network // locked by networksLock
|
networksByMAC map[MAC]*Network // locked by networksLock
|
||||||
networksLock sync.RWMutex
|
networksLock sync.RWMutex
|
||||||
|
|
||||||
// interfaceAddresses are physical IPs assigned to the local machine (detected, not configured)
|
// interfaceAddresses are physical IPs assigned to the local machine.
|
||||||
|
// These are the detected IPs, not those configured explicitly. They include
|
||||||
|
// both private and global IPs.
|
||||||
interfaceAddresses map[string]net.IP
|
interfaceAddresses map[string]net.IP
|
||||||
interfaceAddressesLock sync.Mutex
|
interfaceAddressesLock sync.Mutex
|
||||||
|
|
||||||
// online and running are atomic flags set to control and monitor background tasks
|
|
||||||
online uint32
|
|
||||||
running uint32
|
running uint32
|
||||||
|
online uint32
|
||||||
|
|
||||||
basePath string
|
basePath string
|
||||||
peersPath string
|
peersPath string
|
||||||
|
@ -115,20 +124,20 @@ type Node struct {
|
||||||
infoLogPath string
|
infoLogPath string
|
||||||
errorLogPath string
|
errorLogPath string
|
||||||
|
|
||||||
// localConfig is the current state of local.conf
|
// localConfig is the current state of local.conf.
|
||||||
localConfig *LocalConfig
|
localConfig *LocalConfig
|
||||||
previousLocalConfig *LocalConfig
|
previousLocalConfig *LocalConfig
|
||||||
localConfigLock sync.RWMutex
|
localConfigLock sync.RWMutex
|
||||||
|
|
||||||
// logs for information, errors, and trace output
|
|
||||||
infoLogW *sizeLimitWriter
|
infoLogW *sizeLimitWriter
|
||||||
errLogW *sizeLimitWriter
|
errLogW *sizeLimitWriter
|
||||||
traceLogW io.Writer
|
traceLogW io.Writer
|
||||||
|
|
||||||
infoLog *log.Logger
|
infoLog *log.Logger
|
||||||
errLog *log.Logger
|
errLog *log.Logger
|
||||||
traceLog *log.Logger
|
traceLog *log.Logger
|
||||||
|
|
||||||
// gn is the GoNode instance
|
// gn is the GoNode instance, see go/native/GoNode.hpp
|
||||||
gn *C.ZT_GoNode
|
gn *C.ZT_GoNode
|
||||||
|
|
||||||
// zn is the underlying ZT_Node (ZeroTier::Node) instance
|
// zn is the underlying ZT_Node (ZeroTier::Node) instance
|
||||||
|
@ -137,11 +146,12 @@ type Node struct {
|
||||||
// id is the identity of this node (includes private key)
|
// id is the identity of this node (includes private key)
|
||||||
id *Identity
|
id *Identity
|
||||||
|
|
||||||
// HTTP server instances: one for a named socket (Unix domain or Windows named pipe) and one on a local TCP socket
|
namedSocketAPIServer *http.Server
|
||||||
namedSocketApiServer *http.Server
|
tcpAPIServer *http.Server
|
||||||
tcpApiServer *http.Server
|
|
||||||
|
|
||||||
// runWaitGroup is used to wait for all node goroutines on shutdown
|
// runWaitGroup is used to wait for all node goroutines on shutdown.
|
||||||
|
// Any new goroutine is tracked via this wait group so node shutdown can
|
||||||
|
// itself wait until all goroutines have exited.
|
||||||
runWaitGroup sync.WaitGroup
|
runWaitGroup sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +173,11 @@ func NewNode(basePath string) (n *Node, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cPtr < 0 {
|
if cPtr < 0 {
|
||||||
return nil, errors.New("too many nodes in this instance")
|
return nil, ErrInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check and delete node reference pointer if it's non-negative. This helps
|
||||||
|
// with error handling cleanup. At the end we set cPtr to -1 to disable.
|
||||||
defer func() {
|
defer func() {
|
||||||
if cPtr >= 0 {
|
if cPtr >= 0 {
|
||||||
atomic.StoreUint32(&cNodeRefUsed[cPtr], 0)
|
atomic.StoreUint32(&cNodeRefUsed[cPtr], 0)
|
||||||
|
@ -175,7 +188,7 @@ func NewNode(basePath string) (n *Node, err error) {
|
||||||
n.networks = make(map[NetworkID]*Network)
|
n.networks = make(map[NetworkID]*Network)
|
||||||
n.networksByMAC = make(map[MAC]*Network)
|
n.networksByMAC = make(map[MAC]*Network)
|
||||||
n.interfaceAddresses = make(map[string]net.IP)
|
n.interfaceAddresses = make(map[string]net.IP)
|
||||||
n.online = 0
|
|
||||||
n.running = 1
|
n.running = 1
|
||||||
|
|
||||||
_ = os.MkdirAll(basePath, 0755)
|
_ = os.MkdirAll(basePath, 0755)
|
||||||
|
@ -265,7 +278,7 @@ func NewNode(basePath string) (n *Node, err error) {
|
||||||
_ = n.localConfig.Write(n.localConfigPath)
|
_ = n.localConfig.Write(n.localConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.namedSocketApiServer, n.tcpApiServer, err = createAPIServer(basePath, n)
|
n.namedSocketAPIServer, n.tcpAPIServer, err = createAPIServer(basePath, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.infoLog.Printf("FATAL: unable to start API server: %s", err.Error())
|
n.infoLog.Printf("FATAL: unable to start API server: %s", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -293,12 +306,13 @@ func NewNode(basePath string) (n *Node, err error) {
|
||||||
defer n.runWaitGroup.Done()
|
defer n.runWaitGroup.Done()
|
||||||
lastMaintenanceRun := int64(0)
|
lastMaintenanceRun := int64(0)
|
||||||
for atomic.LoadUint32(&n.running) != 0 {
|
for atomic.LoadUint32(&n.running) != 0 {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
nowS := time.Now().Unix()
|
nowS := time.Now().Unix()
|
||||||
if (nowS - lastMaintenanceRun) >= 30 {
|
if (nowS - lastMaintenanceRun) >= 30 {
|
||||||
lastMaintenanceRun = nowS
|
lastMaintenanceRun = nowS
|
||||||
n.runMaintenance()
|
n.runMaintenance()
|
||||||
}
|
}
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -311,11 +325,11 @@ func NewNode(basePath string) (n *Node, err error) {
|
||||||
// Close closes this Node and frees its underlying C++ Node structures
|
// Close closes this Node and frees its underlying C++ Node structures
|
||||||
func (n *Node) Close() {
|
func (n *Node) Close() {
|
||||||
if atomic.SwapUint32(&n.running, 0) != 0 {
|
if atomic.SwapUint32(&n.running, 0) != 0 {
|
||||||
if n.namedSocketApiServer != nil {
|
if n.namedSocketAPIServer != nil {
|
||||||
_ = n.namedSocketApiServer.Close()
|
_ = n.namedSocketAPIServer.Close()
|
||||||
}
|
}
|
||||||
if n.tcpApiServer != nil {
|
if n.tcpAPIServer != nil {
|
||||||
_ = n.tcpApiServer.Close()
|
_ = n.tcpAPIServer.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
C.ZT_GoNode_delete(n.gn)
|
C.ZT_GoNode_delete(n.gn)
|
||||||
|
@ -369,9 +383,7 @@ func (n *Node) SetLocalConfig(lc *LocalConfig) (restartRequired bool, err error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.localConfig.Settings.PrimaryPort != lc.Settings.PrimaryPort ||
|
if n.localConfig.Settings.PrimaryPort != lc.Settings.PrimaryPort || n.localConfig.Settings.SecondaryPort != lc.Settings.SecondaryPort || n.localConfig.Settings.LogSizeMax != lc.Settings.LogSizeMax {
|
||||||
n.localConfig.Settings.SecondaryPort != lc.Settings.SecondaryPort ||
|
|
||||||
n.localConfig.Settings.LogSizeMax != lc.Settings.LogSizeMax {
|
|
||||||
restartRequired = true
|
restartRequired = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,17 +449,29 @@ func (n *Node) Leave(nwid NetworkID) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) AddRoot(id *Identity, loc *Locator) (*Peer, error) {
|
// AddRoot designates a peer as root, adding it if missing.
|
||||||
// TODO
|
func (n *Node) AddRoot(id *Identity) (*Peer, error) {
|
||||||
return nil, nil
|
if !id.initCIdentityPtr() {
|
||||||
|
return nil, ErrInvalidKey
|
||||||
|
}
|
||||||
|
rc := C.ZT_Node_addRoot(n.zn, nil, id.cid)
|
||||||
|
if rc != 0 {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
p := n.Peer(id.Fingerprint())
|
||||||
|
if p == nil {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveRoot un-designates a peer as root.
|
||||||
func (n *Node) RemoveRoot(address Address) {
|
func (n *Node) RemoveRoot(address Address) {
|
||||||
C.ZT_Node_removeRoot(n.zn, nil, C.uint64_t(address))
|
C.ZT_Node_removeRoot(n.zn, nil, C.uint64_t(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNetwork looks up a network by ID or returns nil if not joined
|
// Network looks up a network by ID or returns nil if not joined
|
||||||
func (n *Node) GetNetwork(nwid NetworkID) *Network {
|
func (n *Node) Network(nwid NetworkID) *Network {
|
||||||
n.networksLock.RLock()
|
n.networksLock.RLock()
|
||||||
nw := n.networks[nwid]
|
nw := n.networks[nwid]
|
||||||
n.networksLock.RUnlock()
|
n.networksLock.RUnlock()
|
||||||
|
@ -484,6 +508,32 @@ func (n *Node) Peers() []*Peer {
|
||||||
return peers
|
return peers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Peer looks up a single peer by address or full fingerprint.
|
||||||
|
// The fpOrAddress parameter may be either. If it is neither nil is returned.
|
||||||
|
// A nil pointer is returned if nothing is found.
|
||||||
|
func (n *Node) Peer(fpOrAddress interface{}) *Peer {
|
||||||
|
fp, _ := fpOrAddress.(*Fingerprint)
|
||||||
|
if fp == nil {
|
||||||
|
a, _ := fpOrAddress.(*Address)
|
||||||
|
if a == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fp = &Fingerprint{Address: *a}
|
||||||
|
}
|
||||||
|
pl := C.ZT_Node_peers(n.zn)
|
||||||
|
if pl != nil {
|
||||||
|
for i := uintptr(0); i < uintptr(pl.peerCount); i++ {
|
||||||
|
p, _ := newPeerFromCPeer((*C.ZT_Peer)(unsafe.Pointer(uintptr(unsafe.Pointer(pl.peers)) + (i * C.sizeof_ZT_Peer))))
|
||||||
|
if p != nil && p.Identity.Fingerprint().BestSpecificityEquals(fp) {
|
||||||
|
C.ZT_freeQueryResult(unsafe.Pointer(pl))
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
C.ZT_freeQueryResult(unsafe.Pointer(pl))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AddPeer adds a peer by explicit identity.
|
// AddPeer adds a peer by explicit identity.
|
||||||
func (n *Node) AddPeer(id *Identity) error {
|
func (n *Node) AddPeer(id *Identity) error {
|
||||||
if id == nil {
|
if id == nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue