mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Golang fixes
This commit is contained in:
parent
c881094202
commit
964c235ecf
15 changed files with 349 additions and 293 deletions
|
@ -63,7 +63,7 @@ Commands:
|
|||
validate <identity> Locally validate an identity
|
||||
sign <identity> <file> Sign a file with an identity's key
|
||||
verify <identity> <file> <sig> Verify a signature
|
||||
makeroot <identity> <address> [...] Make a root spec (see docs)
|
||||
makeroot <identity> <address[,...]> Make a root spec (see docs)
|
||||
|
||||
The 'service' command does not exit until the service receives a signal.
|
||||
This is typically run from launchd (Mac), systemd or init (Linux), a Windows
|
||||
|
|
|
@ -5,5 +5,5 @@ go 1.13
|
|||
require (
|
||||
github.com/Microsoft/go-winio v0.4.14
|
||||
github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect
|
||||
)
|
||||
|
|
|
@ -19,3 +19,5 @@ golang.org/x/sys v0.0.0-20200120151820-655fe14d7479 h1:LhLiKguPgZL+Tglay4GhVtfF0
|
|||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -18,21 +18,18 @@ package zerotier
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"errors"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var ztBase32 = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
|
||||
|
||||
type Fingerprint struct {
|
||||
Address Address `json:"address"`
|
||||
Hash [48]byte `json:"hash"`
|
||||
}
|
||||
|
||||
func NewFingerprintFromString(fps string) (*Fingerprint, error) {
|
||||
fpb, err := ztBase32.DecodeString(strings.TrimSpace(strings.ToLower(fps)))
|
||||
fpb, err := Base32StdLowerCase.DecodeString(strings.TrimSpace(strings.ToLower(fps)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -49,7 +46,7 @@ func (fp *Fingerprint) String() string {
|
|||
var tmp [53]byte
|
||||
fp.Address.CopyTo(tmp[0:5])
|
||||
copy(tmp[5:],fp.Hash[:])
|
||||
return ztBase32.EncodeToString(tmp[:])
|
||||
return Base32StdLowerCase.EncodeToString(tmp[:])
|
||||
}
|
||||
|
||||
func (fp *Fingerprint) apiFingerprint() *C.ZT_Fingerprint {
|
||||
|
|
|
@ -27,18 +27,14 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// IdentityTypeC25519 is a classic Curve25519/Ed25519 identity
|
||||
const IdentityTypeC25519 = 0
|
||||
|
||||
// IdentityTypeP384 is an identity containing both NIST P-384 and Curve25519/Ed25519 key types and leveraging both when possible
|
||||
const IdentityTypeP384 = 1
|
||||
|
||||
// Sizes of components of different identity types
|
||||
const (
|
||||
IdentityTypeC25519PublicKeySize = 64 // C25519/Ed25519 keys
|
||||
IdentityTypeC25519PrivateKeySize = 64 // C25519/Ed25519 private keys
|
||||
IdentityTypeP384PublicKeySize = 209 // C25519/Ed25519, P-384 point-compressed public, P-384 self-signature
|
||||
IdentityTypeP384PrivateKeySize = 112 // C25519/Ed25519 and P-384 private keys
|
||||
IdentityTypeC25519 = C.ZT_IDENTITY_TYPE_C25519
|
||||
IdentityTypeP384 = C.ZT_IDENTITY_TYPE_P384
|
||||
|
||||
IdentityTypeC25519PublicKeySize = C.ZT_IDENTITY_C25519_PUBLIC_KEY_SIZE
|
||||
IdentityTypeC25519PrivateKeySize = C.ZT_IDENTITY_C25519_PRIVATE_KEY_SIZE
|
||||
IdentityTypeP384PublicKeySize = C.ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE
|
||||
IdentityTypeP384PrivateKeySize = C.ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE
|
||||
)
|
||||
|
||||
// Identity is precisely what it sounds like: the address and associated keys for a ZeroTier node
|
||||
|
@ -79,18 +75,18 @@ func newIdentityFromCIdentity(cid unsafe.Pointer) (*Identity, error) {
|
|||
return id, nil
|
||||
}
|
||||
|
||||
// cIdentity returns a pointer to the core ZT_Identity instance or nil/0 on error.
|
||||
func (id *Identity) cIdentity() unsafe.Pointer {
|
||||
// initCIdentityPtr returns a pointer to the core ZT_Identity instance or nil/0 on error.
|
||||
func (id *Identity) initCIdentityPtr() bool {
|
||||
if uintptr(id.cid) == 0 {
|
||||
idCStr := C.CString(id.String())
|
||||
defer C.free(unsafe.Pointer(idCStr))
|
||||
id.cid = C.ZT_Identity_fromString(idCStr)
|
||||
if uintptr(id.cid) == 0 {
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
runtime.SetFinalizer(id, identityFinalizer)
|
||||
}
|
||||
return id.cid
|
||||
return true
|
||||
}
|
||||
|
||||
// NewIdentity generates a new identity of the selected type
|
||||
|
@ -197,8 +193,7 @@ func (id *Identity) String() string {
|
|||
|
||||
// LocallyValidate performs local self-validation of this identity
|
||||
func (id *Identity) LocallyValidate() bool {
|
||||
id.cIdentity()
|
||||
if uintptr(id.cid) == 0 {
|
||||
if !id.initCIdentityPtr() {
|
||||
return false
|
||||
}
|
||||
return C.ZT_Identity_validate(id.cid) != 0
|
||||
|
@ -206,8 +201,7 @@ func (id *Identity) LocallyValidate() bool {
|
|||
|
||||
// Sign signs a message with this identity
|
||||
func (id *Identity) Sign(msg []byte) ([]byte, error) {
|
||||
id.cIdentity()
|
||||
if uintptr(id.cid) == 0 {
|
||||
if !id.initCIdentityPtr() {
|
||||
return nil, ErrInvalidKey
|
||||
}
|
||||
|
||||
|
@ -226,15 +220,9 @@ func (id *Identity) Sign(msg []byte) ([]byte, error) {
|
|||
|
||||
// Verify verifies a signature
|
||||
func (id *Identity) Verify(msg, sig []byte) bool {
|
||||
if len(sig) == 0 {
|
||||
if len(sig) == 0 || !id.initCIdentityPtr() {
|
||||
return false
|
||||
}
|
||||
|
||||
id.cIdentity()
|
||||
if uintptr(id.cid) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var dataP unsafe.Pointer
|
||||
if len(msg) > 0 {
|
||||
dataP = unsafe.Pointer(&msg[0])
|
||||
|
@ -247,9 +235,7 @@ func (id *Identity) MakeRoot(addresses []InetAddress) ([]byte, error) {
|
|||
if len(addresses) == 0 {
|
||||
return nil, errors.New("at least one static address must be specified for a root")
|
||||
}
|
||||
|
||||
id.cIdentity()
|
||||
if uintptr(id.cid) == 0 {
|
||||
if !id.initCIdentityPtr() {
|
||||
return nil, errors.New("error initializing ZT_Identity")
|
||||
}
|
||||
|
||||
|
|
|
@ -159,25 +159,27 @@ func (t *nativeTap) AddMulticastGroupChangeHandler(handler func(bool, *Multicast
|
|||
}
|
||||
|
||||
func handleTapMulticastGroupChange(gn unsafe.Pointer, nwid, mac C.uint64_t, adi C.uint32_t, added bool) {
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
node.networksLock.RLock()
|
||||
network := node.networks[NetworkID(nwid)]
|
||||
node.networksLock.RUnlock()
|
||||
if network == nil {
|
||||
return
|
||||
}
|
||||
|
||||
node.runWaitGroup.Add(1)
|
||||
go func() {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
node.networksLock.RLock()
|
||||
network := node.networks[NetworkID(nwid)]
|
||||
node.networksLock.RUnlock()
|
||||
if network != nil {
|
||||
tap, _ := network.tap.(*nativeTap)
|
||||
if tap != nil {
|
||||
mg := &MulticastGroup{MAC: MAC(mac), ADI: uint32(adi)}
|
||||
tap.multicastGroupHandlersLock.Lock()
|
||||
defer tap.multicastGroupHandlersLock.Unlock()
|
||||
for _, h := range tap.multicastGroupHandlers {
|
||||
h(added, mg)
|
||||
}
|
||||
defer node.runWaitGroup.Done()
|
||||
tap, _ := network.tap.(*nativeTap)
|
||||
if tap != nil {
|
||||
mg := &MulticastGroup{MAC: MAC(mac), ADI: uint32(adi)}
|
||||
tap.multicastGroupHandlersLock.Lock()
|
||||
defer tap.multicastGroupHandlersLock.Unlock()
|
||||
for _, h := range tap.multicastGroupHandlers {
|
||||
h(added, mg)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
|
|
@ -45,7 +45,6 @@ import (
|
|||
|
||||
var nullLogger = log.New(ioutil.Discard, "", 0)
|
||||
|
||||
// Network status states
|
||||
const (
|
||||
NetworkIDStringLength = 16
|
||||
AddressStringLength = 10
|
||||
|
@ -62,16 +61,17 @@ const (
|
|||
networkConfigOpUpdate int = C.ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE
|
||||
|
||||
defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU
|
||||
|
||||
// maxCNodeRefs is the maximum number of Node instances that can be created in this process (increasing is fine)
|
||||
maxCNodeRefs = 4
|
||||
)
|
||||
|
||||
var (
|
||||
// PlatformDefaultHomePath is the default location of ZeroTier's working path on this system
|
||||
PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
|
||||
|
||||
// This map is used to get the Go Node object from a pointer passed back in via C callbacks
|
||||
nodesByUserPtr = make(map[uintptr]*Node)
|
||||
nodesByUserPtrCtr = uintptr(0)
|
||||
nodesByUserPtrLock sync.RWMutex
|
||||
cNodeRefs [maxCNodeRefs]*Node
|
||||
cNodeRefUsed [maxCNodeRefs]uint32
|
||||
|
||||
CoreVersionMajor int
|
||||
CoreVersionMinor int
|
||||
|
@ -90,6 +90,9 @@ func init() {
|
|||
|
||||
// Node is an instance of a virtual port on the global switch.
|
||||
type Node struct {
|
||||
// an arbitrary uintptr given to the core as its pointer back to Go's Node instance
|
||||
cPtr uintptr
|
||||
|
||||
// networks contains networks we have joined, and networksByMAC by their local MAC address
|
||||
networks map[NetworkID]*Network
|
||||
networksByMAC map[MAC]*Network // locked by networksLock
|
||||
|
@ -107,10 +110,13 @@ type Node struct {
|
|||
peersPath string
|
||||
networksPath string
|
||||
localConfigPath string
|
||||
infoLogPath string
|
||||
errorLogPath string
|
||||
|
||||
// localConfig is the current state of local.conf
|
||||
localConfig LocalConfig
|
||||
localConfigLock sync.RWMutex
|
||||
localConfig *LocalConfig
|
||||
previousLocalConfig *LocalConfig
|
||||
localConfigLock sync.RWMutex
|
||||
|
||||
// logs for information, errors, and trace output
|
||||
infoLogW *sizeLimitWriter
|
||||
|
@ -120,13 +126,13 @@ type Node struct {
|
|||
errLog *log.Logger
|
||||
traceLog *log.Logger
|
||||
|
||||
// gn is the instance of GoNode, the Go wrapper and multithreaded I/O engine
|
||||
// gn is the GoNode instance
|
||||
gn *C.ZT_GoNode
|
||||
|
||||
// zn is the underlying instance of the ZeroTier core
|
||||
// zn is the underlying ZT_Node (ZeroTier::Node) instance
|
||||
zn unsafe.Pointer
|
||||
|
||||
// id is the identity of this node
|
||||
// id is the identity of this node (includes private key)
|
||||
id *Identity
|
||||
|
||||
// HTTP server instances: one for a named socket (Unix domain or Windows named pipe) and one on a local TCP socket
|
||||
|
@ -135,14 +141,34 @@ type Node struct {
|
|||
|
||||
// runWaitGroup is used to wait for all node goroutines on shutdown
|
||||
runWaitGroup sync.WaitGroup
|
||||
|
||||
// an arbitrary uintptr given to the core as its pointer back to Go's Node instance
|
||||
cPtr uintptr
|
||||
}
|
||||
|
||||
// NewNode creates and initializes a new instance of the ZeroTier node service
|
||||
func NewNode(basePath string) (n *Node, err error) {
|
||||
n = new(Node)
|
||||
|
||||
// Register this with the cNodeRefs lookup array and set up a deferred function
|
||||
// to unregister this if we exit before the end of the constructor such as by
|
||||
// returning an error.
|
||||
cPtr := -1
|
||||
for i:=0;i<maxCNodeRefs;i++ {
|
||||
if atomic.CompareAndSwapUint32(&cNodeRefUsed[i],0,1) {
|
||||
cNodeRefs[i] = n
|
||||
cPtr = i
|
||||
n.cPtr = uintptr(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if cPtr < 0 {
|
||||
return nil, errors.New("too many nodes in this instance")
|
||||
}
|
||||
defer func() {
|
||||
if cPtr >= 0 {
|
||||
atomic.StoreUint32(&cNodeRefUsed[cPtr],0)
|
||||
cNodeRefs[cPtr] = nil
|
||||
}
|
||||
}()
|
||||
|
||||
n.networks = make(map[NetworkID]*Network)
|
||||
n.networksByMAC = make(map[MAC]*Network)
|
||||
n.interfaceAddresses = make(map[string]net.IP)
|
||||
|
@ -168,17 +194,20 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
n.localConfigPath = path.Join(basePath, "local.conf")
|
||||
|
||||
_, identitySecretNotFoundErr := os.Stat(path.Join(basePath, "identity.secret"))
|
||||
n.localConfig = new(LocalConfig)
|
||||
err = n.localConfig.Read(n.localConfigPath, true, identitySecretNotFoundErr != nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
n.infoLogPath = path.Join(basePath, "info.log")
|
||||
n.errorLogPath = path.Join(basePath, "error.log")
|
||||
if n.localConfig.Settings.LogSizeMax >= 0 {
|
||||
n.infoLogW, err = sizeLimitWriterOpen(path.Join(basePath, "info.log"))
|
||||
n.infoLogW, err = sizeLimitWriterOpen(n.infoLogPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n.errLogW, err = sizeLimitWriterOpen(path.Join(basePath, "error.log"))
|
||||
n.errLogW, err = sizeLimitWriterOpen(n.errorLogPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -186,6 +215,7 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
n.errLog = log.New(n.errLogW, "", log.LstdFlags)
|
||||
} else {
|
||||
n.infoLog = nullLogger
|
||||
n.errLog = nullLogger
|
||||
}
|
||||
|
||||
if n.localConfig.Settings.PortSearch {
|
||||
|
@ -249,29 +279,17 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
nodesByUserPtrLock.Lock()
|
||||
nodesByUserPtrCtr++
|
||||
n.cPtr = nodesByUserPtrCtr
|
||||
nodesByUserPtr[n.cPtr] = n
|
||||
nodesByUserPtrLock.Unlock()
|
||||
|
||||
cPath := C.CString(basePath)
|
||||
n.gn = C.ZT_GoNode_new(cPath, C.uintptr_t(n.cPtr))
|
||||
C.free(unsafe.Pointer(cPath))
|
||||
if n.gn == nil {
|
||||
n.infoLog.Println("FATAL: node initialization failed")
|
||||
nodesByUserPtrLock.Lock()
|
||||
delete(nodesByUserPtr, n.cPtr)
|
||||
nodesByUserPtrLock.Unlock()
|
||||
return nil, ErrNodeInitFailed
|
||||
}
|
||||
n.zn = unsafe.Pointer(C.ZT_GoNode_getNode(n.gn))
|
||||
n.id, err = newIdentityFromCIdentity(C.ZT_Node_identity(n.zn))
|
||||
if err != nil {
|
||||
n.infoLog.Printf("FATAL: error obtaining node's identity")
|
||||
nodesByUserPtrLock.Lock()
|
||||
delete(nodesByUserPtr, n.cPtr)
|
||||
nodesByUserPtrLock.Unlock()
|
||||
C.ZT_GoNode_delete(n.gn)
|
||||
return nil, err
|
||||
}
|
||||
|
@ -281,137 +299,20 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
n.runWaitGroup.Add(1)
|
||||
go func() {
|
||||
defer n.runWaitGroup.Done()
|
||||
var previousExplicitExternalAddresses []ExternalAddress // empty at first so these will be configured
|
||||
lastMaintenanceRun := int64(0)
|
||||
|
||||
for atomic.LoadUint32(&n.running) != 0 {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
nowS := time.Now().Unix()
|
||||
if (nowS - lastMaintenanceRun) >= 30 {
|
||||
lastMaintenanceRun = nowS
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
n.localConfigLock.RLock()
|
||||
|
||||
// Get local physical interface addresses, excluding blacklisted and ZeroTier-created interfaces
|
||||
interfaceAddresses := make(map[string]net.IP)
|
||||
ifs, _ := net.Interfaces()
|
||||
if len(ifs) > 0 {
|
||||
n.networksLock.RLock()
|
||||
scanInterfaces:
|
||||
for _, i := range ifs {
|
||||
for _, bl := range n.localConfig.Settings.InterfacePrefixBlacklist {
|
||||
if strings.HasPrefix(strings.ToLower(i.Name), strings.ToLower(bl)) {
|
||||
continue scanInterfaces
|
||||
}
|
||||
}
|
||||
m, _ := NewMACFromBytes(i.HardwareAddr)
|
||||
if _, isZeroTier := n.networksByMAC[m]; !isZeroTier {
|
||||
addrs, _ := i.Addrs()
|
||||
for _, a := range addrs {
|
||||
ipn, _ := a.(*net.IPNet)
|
||||
if ipn != nil && len(ipn.IP) > 0 && !ipn.IP.IsLinkLocalUnicast() && !ipn.IP.IsMulticast() {
|
||||
interfaceAddresses[ipn.IP.String()] = ipn.IP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.networksLock.RUnlock()
|
||||
}
|
||||
|
||||
// Open or close locally bound UDP ports for each local interface address.
|
||||
// This opens ports if they are not already open and then closes ports if
|
||||
// they are open but no longer seem to exist.
|
||||
interfaceAddressesChanged := false
|
||||
ports := make([]int, 0, 2)
|
||||
if n.localConfig.Settings.PrimaryPort > 0 && n.localConfig.Settings.PrimaryPort < 65536 {
|
||||
ports = append(ports, n.localConfig.Settings.PrimaryPort)
|
||||
}
|
||||
if n.localConfig.Settings.SecondaryPort > 0 && n.localConfig.Settings.SecondaryPort < 65536 {
|
||||
ports = append(ports, n.localConfig.Settings.SecondaryPort)
|
||||
}
|
||||
n.interfaceAddressesLock.Lock()
|
||||
for astr, ipn := range interfaceAddresses {
|
||||
if _, alreadyKnown := n.interfaceAddresses[astr]; !alreadyKnown {
|
||||
interfaceAddressesChanged = true
|
||||
ipCstr := C.CString(ipn.String())
|
||||
for pn, p := range ports {
|
||||
n.infoLog.Printf("UDP binding to port %d on interface %s", p, astr)
|
||||
primary := C.int(0)
|
||||
if pn == 0 {
|
||||
primary = 1
|
||||
}
|
||||
C.ZT_GoNode_phyStartListen(n.gn, nil, ipCstr, C.int(p), primary)
|
||||
}
|
||||
C.free(unsafe.Pointer(ipCstr))
|
||||
}
|
||||
}
|
||||
for astr, ipn := range n.interfaceAddresses {
|
||||
if _, stillPresent := interfaceAddresses[astr]; !stillPresent {
|
||||
interfaceAddressesChanged = true
|
||||
ipCstr := C.CString(ipn.String())
|
||||
for _, p := range ports {
|
||||
n.infoLog.Printf("UDP closing socket bound to port %d on interface %s", p, astr)
|
||||
C.ZT_GoNode_phyStopListen(n.gn, nil, ipCstr, C.int(p))
|
||||
}
|
||||
C.free(unsafe.Pointer(ipCstr))
|
||||
}
|
||||
}
|
||||
n.interfaceAddresses = interfaceAddresses
|
||||
n.interfaceAddressesLock.Unlock()
|
||||
|
||||
// Update node's understanding of our interface addresses if they've changed
|
||||
if interfaceAddressesChanged || reflect.DeepEqual(n.localConfig.Settings.ExplicitAddresses, previousExplicitExternalAddresses) {
|
||||
previousExplicitExternalAddresses = n.localConfig.Settings.ExplicitAddresses
|
||||
|
||||
// Consolidate explicit and detected interface addresses, removing duplicates.
|
||||
externalAddresses := make(map[[3]uint64]*ExternalAddress)
|
||||
for _, ip := range interfaceAddresses {
|
||||
for _, p := range ports {
|
||||
a := &ExternalAddress{
|
||||
InetAddress: InetAddress{
|
||||
IP: ip,
|
||||
Port: p,
|
||||
},
|
||||
Permanent: false,
|
||||
}
|
||||
externalAddresses[a.key()] = a
|
||||
}
|
||||
}
|
||||
for _, a := range n.localConfig.Settings.ExplicitAddresses {
|
||||
externalAddresses[a.key()] = &a
|
||||
}
|
||||
|
||||
if len(externalAddresses) > 0 {
|
||||
cAddrs := make([]C.ZT_InterfaceAddress, len(externalAddresses))
|
||||
cAddrCount := 0
|
||||
for _, a := range externalAddresses {
|
||||
makeSockaddrStorage(a.IP, a.Port, &(cAddrs[cAddrCount].address))
|
||||
if a.Permanent {
|
||||
cAddrs[cAddrCount].permanent = 1
|
||||
} else {
|
||||
cAddrs[cAddrCount].permanent = 0
|
||||
}
|
||||
cAddrCount++
|
||||
}
|
||||
C.ZT_Node_setInterfaceAddresses(n.zn, &cAddrs[0], C.uint(cAddrCount))
|
||||
} else {
|
||||
C.ZT_Node_setInterfaceAddresses(n.zn, nil, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Trim infoLog if it's gone over its size limit
|
||||
if n.localConfig.Settings.LogSizeMax > 0 && n.infoLogW != nil {
|
||||
_ = n.infoLogW.trim(n.localConfig.Settings.LogSizeMax*1024, 0.5, true)
|
||||
}
|
||||
|
||||
n.localConfigLock.RUnlock()
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
n.runMaintenance()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Stop deferred cPtr table cleanup function from deregistering this instance
|
||||
cPtr = -1
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
|
@ -429,9 +330,8 @@ func (n *Node) Close() {
|
|||
|
||||
n.runWaitGroup.Wait()
|
||||
|
||||
nodesByUserPtrLock.Lock()
|
||||
delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
|
||||
nodesByUserPtrLock.Unlock()
|
||||
cNodeRefs[n.cPtr] = nil
|
||||
atomic.StoreUint32(&cNodeRefUsed[n.cPtr],0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,7 +357,7 @@ func (n *Node) InterfaceAddresses() []net.IP {
|
|||
}
|
||||
|
||||
// LocalConfig gets this node's local configuration
|
||||
func (n *Node) LocalConfig() LocalConfig {
|
||||
func (n *Node) LocalConfig() *LocalConfig {
|
||||
n.localConfigLock.RLock()
|
||||
defer n.localConfigLock.RUnlock()
|
||||
return n.localConfig
|
||||
|
@ -477,24 +377,14 @@ func (n *Node) SetLocalConfig(lc *LocalConfig) (restartRequired bool, err error)
|
|||
}
|
||||
}
|
||||
|
||||
if n.localConfig.Settings.PrimaryPort != lc.Settings.PrimaryPort || n.localConfig.Settings.SecondaryPort != lc.Settings.SecondaryPort {
|
||||
if n.localConfig.Settings.PrimaryPort != lc.Settings.PrimaryPort ||
|
||||
n.localConfig.Settings.SecondaryPort != lc.Settings.SecondaryPort ||
|
||||
n.localConfig.Settings.LogSizeMax != lc.Settings.LogSizeMax {
|
||||
restartRequired = true
|
||||
}
|
||||
if lc.Settings.LogSizeMax < 0 {
|
||||
n.infoLog = nullLogger
|
||||
_ = n.infoLogW.Close()
|
||||
n.infoLogW = nil
|
||||
} else if n.infoLogW != nil {
|
||||
n.infoLogW, err = sizeLimitWriterOpen(path.Join(n.basePath, "service.infoLog"))
|
||||
if err == nil {
|
||||
n.infoLog = log.New(n.infoLogW, "", log.LstdFlags)
|
||||
} else {
|
||||
n.infoLog = nullLogger
|
||||
n.infoLogW = nil
|
||||
}
|
||||
}
|
||||
|
||||
n.localConfig = *lc
|
||||
n.previousLocalConfig = n.localConfig
|
||||
n.localConfig = lc
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -555,30 +445,11 @@ func (n *Node) Leave(nwid NetworkID) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// AddRoot adds a root server with an optional bootstrap address for establishing first contact.
|
||||
// If you're already using roots backed by proper global LF data stores the bootstrap address may
|
||||
// be unnecessary as your node can probably find the new root automatically.
|
||||
func (n *Node) AddRoot(id *Identity, bootstrap *InetAddress) error {
|
||||
if id == nil {
|
||||
return ErrInvalidParameter
|
||||
}
|
||||
var cBootstrap C.struct_sockaddr_storage
|
||||
if bootstrap != nil {
|
||||
makeSockaddrStorage(bootstrap.IP, bootstrap.Port, &cBootstrap)
|
||||
} else {
|
||||
zeroSockaddrStorage(&cBootstrap)
|
||||
}
|
||||
C.ZT_Node_addRoot(n.zn, nil, id.cIdentity(), &cBootstrap)
|
||||
func (n *Node) AddRoot(spec []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveRoot removes a root server for this node.
|
||||
// This doesn't instantly close paths to the given peer or forget about it. It just
|
||||
// demotes it to a normal peer.
|
||||
func (n *Node) RemoveRoot(id *Identity) {
|
||||
if id != nil {
|
||||
C.ZT_Node_removeRoot(n.zn, nil, id.cIdentity())
|
||||
}
|
||||
func (n *Node) RemoveRoot(address Address) {
|
||||
}
|
||||
|
||||
// GetNetwork looks up a network by ID or returns nil if not joined
|
||||
|
@ -618,7 +489,7 @@ func (n *Node) Peers() []*Peer {
|
|||
|
||||
p2.Paths = make([]Path, 0, int(p.pathCount))
|
||||
for j := 0; j < len(p2.Paths); j++ {
|
||||
pt := (*C.ZT_PeerPhysicalPath)(unsafe.Pointer(uintptr(unsafe.Pointer(p.paths)) + uintptr(j * C.sizeof_ZT_PeerPhysicalPath)))
|
||||
pt := (*C.ZT_PeerPhysicalPath)(unsafe.Pointer(uintptr(unsafe.Pointer(p.paths)) + uintptr(j*C.sizeof_ZT_PeerPhysicalPath)))
|
||||
if pt.alive != 0 {
|
||||
a := sockaddrStorageToUDPAddr(&pt.address)
|
||||
if a != nil {
|
||||
|
@ -645,6 +516,116 @@ func (n *Node) Peers() []*Peer {
|
|||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
func (n *Node) runMaintenance() {
|
||||
n.localConfigLock.RLock()
|
||||
defer n.localConfigLock.RUnlock()
|
||||
|
||||
// Get local physical interface addresses, excluding blacklisted and ZeroTier-created interfaces
|
||||
interfaceAddresses := make(map[string]net.IP)
|
||||
ifs, _ := net.Interfaces()
|
||||
if len(ifs) > 0 {
|
||||
n.networksLock.RLock()
|
||||
scanInterfaces:
|
||||
for _, i := range ifs {
|
||||
for _, bl := range n.localConfig.Settings.InterfacePrefixBlacklist {
|
||||
if strings.HasPrefix(strings.ToLower(i.Name), strings.ToLower(bl)) {
|
||||
continue scanInterfaces
|
||||
}
|
||||
}
|
||||
m, _ := NewMACFromBytes(i.HardwareAddr)
|
||||
if _, isZeroTier := n.networksByMAC[m]; !isZeroTier {
|
||||
addrs, _ := i.Addrs()
|
||||
for _, a := range addrs {
|
||||
ipn, _ := a.(*net.IPNet)
|
||||
if ipn != nil && len(ipn.IP) > 0 && !ipn.IP.IsLinkLocalUnicast() && !ipn.IP.IsMulticast() {
|
||||
interfaceAddresses[ipn.IP.String()] = ipn.IP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.networksLock.RUnlock()
|
||||
}
|
||||
|
||||
// Open or close locally bound UDP ports for each local interface address.
|
||||
// This opens ports if they are not already open and then closes ports if
|
||||
// they are open but no longer seem to exist.
|
||||
interfaceAddressesChanged := false
|
||||
ports := make([]int, 0, 2)
|
||||
if n.localConfig.Settings.PrimaryPort > 0 && n.localConfig.Settings.PrimaryPort < 65536 {
|
||||
ports = append(ports, n.localConfig.Settings.PrimaryPort)
|
||||
}
|
||||
if n.localConfig.Settings.SecondaryPort > 0 && n.localConfig.Settings.SecondaryPort < 65536 {
|
||||
ports = append(ports, n.localConfig.Settings.SecondaryPort)
|
||||
}
|
||||
n.interfaceAddressesLock.Lock()
|
||||
for astr, ipn := range interfaceAddresses {
|
||||
if _, alreadyKnown := n.interfaceAddresses[astr]; !alreadyKnown {
|
||||
interfaceAddressesChanged = true
|
||||
ipCstr := C.CString(ipn.String())
|
||||
for pn, p := range ports {
|
||||
n.infoLog.Printf("UDP binding to port %d on interface %s", p, astr)
|
||||
primary := C.int(0)
|
||||
if pn == 0 {
|
||||
primary = 1
|
||||
}
|
||||
C.ZT_GoNode_phyStartListen(n.gn, nil, ipCstr, C.int(p), primary)
|
||||
}
|
||||
C.free(unsafe.Pointer(ipCstr))
|
||||
}
|
||||
}
|
||||
for astr, ipn := range n.interfaceAddresses {
|
||||
if _, stillPresent := interfaceAddresses[astr]; !stillPresent {
|
||||
interfaceAddressesChanged = true
|
||||
ipCstr := C.CString(ipn.String())
|
||||
for _, p := range ports {
|
||||
n.infoLog.Printf("UDP closing socket bound to port %d on interface %s", p, astr)
|
||||
C.ZT_GoNode_phyStopListen(n.gn, nil, ipCstr, C.int(p))
|
||||
}
|
||||
C.free(unsafe.Pointer(ipCstr))
|
||||
}
|
||||
}
|
||||
n.interfaceAddresses = interfaceAddresses
|
||||
n.interfaceAddressesLock.Unlock()
|
||||
|
||||
// Update node's interface address list if detected or configured addresses have changed.
|
||||
if interfaceAddressesChanged || n.previousLocalConfig == nil || !reflect.DeepEqual(n.localConfig.Settings.ExplicitAddresses, n.previousLocalConfig.Settings.ExplicitAddresses) {
|
||||
var cAddrs []C.ZT_InterfaceAddress
|
||||
externalAddresses := make(map[[3]uint64]*InetAddress)
|
||||
for _, a := range n.localConfig.Settings.ExplicitAddresses {
|
||||
ak := a.key()
|
||||
if _, have := externalAddresses[ak]; !have {
|
||||
externalAddresses[ak] = &a
|
||||
cAddrs = append(cAddrs, C.ZT_InterfaceAddress{})
|
||||
makeSockaddrStorage(a.IP, a.Port, &(cAddrs[len(cAddrs)-1].address))
|
||||
cAddrs[len(cAddrs)-1].permanent = 1 // explicit addresses are permanent, meaning they can be put in a locator
|
||||
}
|
||||
}
|
||||
for _, ip := range interfaceAddresses {
|
||||
for _, p := range ports {
|
||||
a := InetAddress{ IP: ip, Port: p }
|
||||
ak := a.key()
|
||||
if _, have := externalAddresses[ak]; !have {
|
||||
externalAddresses[ak] = &a
|
||||
cAddrs = append(cAddrs, C.ZT_InterfaceAddress{})
|
||||
makeSockaddrStorage(a.IP, a.Port, &(cAddrs[len(cAddrs)-1].address))
|
||||
cAddrs[len(cAddrs)-1].permanent = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(cAddrs) > 0 {
|
||||
C.ZT_Node_setInterfaceAddresses(n.zn, &cAddrs[0], C.uint(len(cAddrs)))
|
||||
} else {
|
||||
C.ZT_Node_setInterfaceAddresses(n.zn, nil, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Trim infoLog if it's gone over its size limit
|
||||
if n.localConfig.Settings.LogSizeMax > 0 && n.infoLogW != nil {
|
||||
_ = n.infoLogW.trim(n.localConfig.Settings.LogSizeMax*1024, 0.5, true)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Node) multicastSubscribe(nwid uint64, mg *MulticastGroup) {
|
||||
C.ZT_Node_multicastSubscribe(n.zn, nil, C.uint64_t(nwid), C.uint64_t(mg.MAC), C.ulong(mg.ADI))
|
||||
}
|
||||
|
@ -743,20 +724,17 @@ func (n *Node) handleTrace(traceMessage string) {
|
|||
}
|
||||
}
|
||||
|
||||
// func (n *Node) handleUserMessage(origin *Identity, messageTypeID uint64, data []byte) {
|
||||
// }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// These are callbacks called by the core and GoGlue stuff to talk to the
|
||||
// service. These launch goroutines to do their work where possible to
|
||||
// avoid blocking anything in the core.
|
||||
|
||||
//export goPathCheckFunc
|
||||
func goPathCheckFunc(gn, _ unsafe.Pointer, af C.int, ip unsafe.Pointer, _ C.int) C.int {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
var nip net.IP
|
||||
if af == syscall.AF_INET {
|
||||
nip = ((*[4]byte)(ip))[:]
|
||||
|
@ -765,17 +743,16 @@ func goPathCheckFunc(gn, _ unsafe.Pointer, af C.int, ip unsafe.Pointer, _ C.int)
|
|||
} else {
|
||||
return 0
|
||||
}
|
||||
if node != nil && len(nip) > 0 && node.pathCheck(nip) {
|
||||
if len(nip) > 0 && node.pathCheck(nip) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
//export goPathLookupFunc
|
||||
func goPathLookupFunc(gn unsafe.Pointer, _ C.uint64_t, _ int, identity, familyP, ipP, portP unsafe.Pointer) C.int {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
|
@ -807,19 +784,17 @@ func goPathLookupFunc(gn unsafe.Pointer, _ C.uint64_t, _ int, identity, familyP,
|
|||
|
||||
//export goStateObjectPutFunc
|
||||
func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, len C.int) {
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
id2 := *((*[2]uint64)(id))
|
||||
var data2 []byte
|
||||
if len > 0 {
|
||||
data2 = C.GoBytes(data, len)
|
||||
}
|
||||
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
node.runWaitGroup.Add(1)
|
||||
go func() {
|
||||
if len < 0 {
|
||||
|
@ -833,12 +808,11 @@ func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Poin
|
|||
|
||||
//export goStateObjectGetFunc
|
||||
func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, dataP unsafe.Pointer) C.int {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
*((*uintptr)(dataP)) = 0
|
||||
tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
|
||||
if found && len(tmp) > 0 {
|
||||
|
@ -849,14 +823,13 @@ func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, dataP unsafe.Poi
|
|||
*((*uintptr)(dataP)) = uintptr(cData)
|
||||
return C.int(len(tmp))
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
//export goVirtualNetworkConfigFunc
|
||||
func goVirtualNetworkConfigFunc(gn, _ unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
@ -916,12 +889,11 @@ func goVirtualNetworkConfigFunc(gn, _ unsafe.Pointer, nwid C.uint64_t, op C.int,
|
|||
|
||||
//export goZtEvent
|
||||
func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
node := cNodeRefs[uintptr(gn)]
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch eventType {
|
||||
case C.ZT_EVENT_OFFLINE:
|
||||
atomic.StoreUint32(&node.online, 0)
|
||||
|
|
|
@ -27,7 +27,6 @@ type Peer struct {
|
|||
|
||||
// PeerMutableFields contains only the mutable fields of Peer as nullable pointers.
|
||||
type PeerMutableFields struct {
|
||||
Identity *Identity `json:"identity"`
|
||||
Root *bool `json:"root"`
|
||||
Bootstrap *InetAddress `json:"bootstrap,omitempty"`
|
||||
RootSpec []byte `json:"rootSpec"`
|
||||
}
|
||||
|
|
30
go/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
Normal file
30
go/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package unsafeheader contains header declarations for the Go runtime's
|
||||
// slice and string implementations.
|
||||
//
|
||||
// This package allows x/sys to use types equivalent to
|
||||
// reflect.SliceHeader and reflect.StringHeader without introducing
|
||||
// a dependency on the (relatively heavy) "reflect" package.
|
||||
package unsafeheader
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Slice is the runtime representation of a slice.
|
||||
// It cannot be used safely or portably and its representation may change in a later release.
|
||||
type Slice struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
Cap int
|
||||
}
|
||||
|
||||
// String is the runtime representation of a string.
|
||||
// It cannot be used safely or portably and its representation may change in a later release.
|
||||
type String struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
}
|
29
go/vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
29
go/vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
|
@ -104,6 +104,35 @@ func (d *DLL) MustFindProc(name string) *Proc {
|
|||
return p
|
||||
}
|
||||
|
||||
// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc
|
||||
// if found. It returns an error if search fails.
|
||||
func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) {
|
||||
a, e := GetProcAddressByOrdinal(d.Handle, ordinal)
|
||||
name := "#" + itoa(int(ordinal))
|
||||
if e != nil {
|
||||
return nil, &DLLError{
|
||||
Err: e,
|
||||
ObjName: name,
|
||||
Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
|
||||
}
|
||||
}
|
||||
p := &Proc{
|
||||
Dll: d,
|
||||
Name: name,
|
||||
addr: a,
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails.
|
||||
func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc {
|
||||
p, e := d.FindProcByOrdinal(ordinal)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Release unloads DLL d from memory.
|
||||
func (d *DLL) Release() (err error) {
|
||||
return FreeLibrary(d.Handle)
|
||||
|
|
11
go/vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
11
go/vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
|
@ -8,7 +8,6 @@ package windows
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
@ -40,17 +39,11 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
|||
defer DestroyEnvironmentBlock(block)
|
||||
blockp := uintptr(unsafe.Pointer(block))
|
||||
for {
|
||||
entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:]
|
||||
for i, v := range entry {
|
||||
if v == 0 {
|
||||
entry = entry[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
|
||||
if len(entry) == 0 {
|
||||
break
|
||||
}
|
||||
env = append(env, string(utf16.Decode(entry)))
|
||||
env = append(env, entry)
|
||||
blockp += 2 * (uintptr(len(entry)) + 1)
|
||||
}
|
||||
return env, nil
|
||||
|
|
20
go/vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
20
go/vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
|
@ -7,6 +7,8 @@ package windows
|
|||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/internal/unsafeheader"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -1229,7 +1231,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string {
|
|||
return ""
|
||||
}
|
||||
defer LocalFree(Handle(unsafe.Pointer(sddl)))
|
||||
return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(sddl))[:])
|
||||
return UTF16PtrToString(sddl)
|
||||
}
|
||||
|
||||
// ToAbsolute converts a self-relative security descriptor into an absolute one.
|
||||
|
@ -1307,9 +1309,17 @@ func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURIT
|
|||
}
|
||||
|
||||
func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
|
||||
sdBytes := make([]byte, selfRelativeSD.Length())
|
||||
copy(sdBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(selfRelativeSD))[:len(sdBytes)])
|
||||
return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&sdBytes[0]))
|
||||
sdLen := (int)(selfRelativeSD.Length())
|
||||
|
||||
var src []byte
|
||||
h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
|
||||
h.Data = unsafe.Pointer(selfRelativeSD)
|
||||
h.Len = sdLen
|
||||
h.Cap = sdLen
|
||||
|
||||
dst := make([]byte, sdLen)
|
||||
copy(dst, src)
|
||||
return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
|
||||
}
|
||||
|
||||
// SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
|
||||
|
@ -1391,6 +1401,6 @@ func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL
|
|||
}
|
||||
defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
|
||||
aclBytes := make([]byte, winHeapACL.aclSize)
|
||||
copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes)])
|
||||
copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
|
||||
return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
|
||||
}
|
||||
|
|
37
go/vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
37
go/vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
|
@ -13,6 +13,8 @@ import (
|
|||
"time"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/internal/unsafeheader"
|
||||
)
|
||||
|
||||
type Handle uintptr
|
||||
|
@ -117,6 +119,32 @@ func UTF16PtrFromString(s string) (*uint16, error) {
|
|||
return &a[0], nil
|
||||
}
|
||||
|
||||
// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string.
|
||||
// If the pointer is nil, this returns the empty string. This assumes that the UTF-16 sequence is terminated
|
||||
// at a zero word; if the zero word is not present, the program may crash.
|
||||
func UTF16PtrToString(p *uint16) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
if *p == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Find NUL terminator.
|
||||
n := 0
|
||||
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
||||
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
||||
}
|
||||
|
||||
var s []uint16
|
||||
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
||||
h.Data = unsafe.Pointer(p)
|
||||
h.Len = n
|
||||
h.Cap = n
|
||||
|
||||
return string(utf16.Decode(s))
|
||||
}
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
|
||||
|
@ -1181,7 +1209,12 @@ type IPv6Mreq struct {
|
|||
Interface uint32
|
||||
}
|
||||
|
||||
func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
|
||||
func GetsockoptInt(fd Handle, level, opt int) (int, error) {
|
||||
v := int32(0)
|
||||
l := int32(unsafe.Sizeof(v))
|
||||
err := Getsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), &l)
|
||||
return int(v), err
|
||||
}
|
||||
|
||||
func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
|
||||
sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
|
||||
|
@ -1378,7 +1411,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e
|
|||
return "", err
|
||||
}
|
||||
defer CoTaskMemFree(unsafe.Pointer(p))
|
||||
return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]), nil
|
||||
return UTF16PtrToString(p), nil
|
||||
}
|
||||
|
||||
// RtlGetVersion returns the version of the underlying operating system, ignoring
|
||||
|
|
3
go/vendor/modules.txt
vendored
3
go/vendor/modules.txt
vendored
|
@ -4,5 +4,6 @@ github.com/Microsoft/go-winio/pkg/guid
|
|||
# github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95
|
||||
github.com/hectane/go-acl
|
||||
github.com/hectane/go-acl/api
|
||||
# golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
|
||||
# golang.org/x/sys v0.0.0-20200523222454-059865788121
|
||||
golang.org/x/sys/internal/unsafeheader
|
||||
golang.org/x/sys/windows
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
#include "Fingerprint.hpp"
|
||||
#include "Containers.hpp"
|
||||
|
||||
#define ZT_IDENTITY_STRING_BUFFER_LENGTH 1024
|
||||
#define ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE (1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE)
|
||||
#define ZT_IDENTITY_STRING_BUFFER_LENGTH 1024
|
||||
#define ZT_IDENTITY_C25519_PUBLIC_KEY_SIZE ZT_C25519_COMBINED_PUBLIC_KEY_SIZE
|
||||
#define ZT_IDENTITY_C25519_PRIVATE_KEY_SIZE ZT_C25519_COMBINED_PRIVATE_KEY_SIZE
|
||||
#define ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE (1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE)
|
||||
#define ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE (ZT_C25519_COMBINED_PRIVATE_KEY_SIZE + ZT_ECC384_PRIVATE_KEY_SIZE)
|
||||
#define ZT_IDENTITY_MARSHAL_SIZE_MAX (ZT_ADDRESS_LENGTH + 4 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE)
|
||||
#define ZT_IDENTITY_MARSHAL_SIZE_MAX (ZT_ADDRESS_LENGTH + 4 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue