mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
Implement fingerprint option on join in Go land
This commit is contained in:
parent
1df7f21f5f
commit
60fa07bff2
8 changed files with 102 additions and 9 deletions
|
@ -23,7 +23,7 @@ import (
|
||||||
|
|
||||||
// Join CLI command
|
// Join CLI command
|
||||||
func Join(basePath, authToken string, args []string) {
|
func Join(basePath, authToken string, args []string) {
|
||||||
if len(args) != 1 {
|
if len(args) < 1 || len(args) > 2 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,28 @@ func Join(basePath, authToken string, args []string) {
|
||||||
}
|
}
|
||||||
nwids := fmt.Sprintf("%.16x", nwid)
|
nwids := fmt.Sprintf("%.16x", nwid)
|
||||||
|
|
||||||
|
var fp *zerotier.Fingerprint
|
||||||
|
if len(args) == 2 {
|
||||||
|
fp, err = zerotier.NewFingerprintFromString(args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: invalid network controller fingerprint: %s\n", args[1])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var network zerotier.APINetwork
|
var network zerotier.APINetwork
|
||||||
network.ID = zerotier.NetworkID(nwid)
|
network.ID = zerotier.NetworkID(nwid)
|
||||||
apiPost(basePath, authToken, "/network/"+nwids, &network, nil)
|
network.ControllerFingerprint = fp
|
||||||
fmt.Printf("OK %s", nwids)
|
|
||||||
|
if apiPost(basePath, authToken, "/network/"+nwids, &network, nil) <= 0 {
|
||||||
|
fmt.Printf("FAILED\n")
|
||||||
|
} else {
|
||||||
|
if fp == nil {
|
||||||
|
fmt.Printf("OK %s\n", nwids)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("OK %s %s\n", nwids, fp.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,7 +593,7 @@ static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,
|
||||||
&(reinterpret_cast<ZT_GoNode *>(uptr)->nextBackgroundTaskDeadline));
|
&(reinterpret_cast<ZT_GoNode *>(uptr)->nextBackgroundTaskDeadline));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid)
|
extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid,const ZT_Fingerprint *const controllerFingerprint)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> l(gn->taps_l);
|
std::lock_guard<std::mutex> l(gn->taps_l);
|
||||||
|
@ -606,7 +606,7 @@ extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid)
|
||||||
if (!tap)
|
if (!tap)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
gn->taps[nwid] = tap;
|
gn->taps[nwid] = tap;
|
||||||
gn->node->join(nwid,tap.get(),nullptr);
|
gn->node->join(nwid,controllerFingerprint,tap.get(),nullptr);
|
||||||
return (ZT_GoTap *)tap.get();
|
return (ZT_GoTap *)tap.get();
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -54,7 +54,7 @@ int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,int po
|
||||||
/* Close all listener threads for a given local IP and port */
|
/* Close all listener threads for a given local IP and port */
|
||||||
int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,int port);
|
int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,int port);
|
||||||
|
|
||||||
ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid);
|
ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid,const ZT_Fingerprint *controllerFingerprint);
|
||||||
|
|
||||||
void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid);
|
void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid);
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,15 @@ 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.
|
||||||
|
func (a Address) CopyTo(b []byte) {
|
||||||
|
b[0] = byte(a >> 32)
|
||||||
|
b[1] = byte(a >> 24)
|
||||||
|
b[2] = byte(a >> 16)
|
||||||
|
b[3] = byte(a >> 8)
|
||||||
|
b[4] = byte(a)
|
||||||
|
}
|
||||||
|
|
||||||
// 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 }
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ type APINetwork struct {
|
||||||
ID NetworkID `json:"id"`
|
ID NetworkID `json:"id"`
|
||||||
Config NetworkConfig `json:"config"`
|
Config NetworkConfig `json:"config"`
|
||||||
Settings *NetworkLocalSettings `json:"settings,omitempty"`
|
Settings *NetworkLocalSettings `json:"settings,omitempty"`
|
||||||
|
ControllerFingerprint *Fingerprint `json:"controllerFingerprint,omitempty"`
|
||||||
MulticastSubscriptions []*MulticastGroup `json:"multicastSubscriptions,omitempty"`
|
MulticastSubscriptions []*MulticastGroup `json:"multicastSubscriptions,omitempty"`
|
||||||
PortType string `json:"portType"`
|
PortType string `json:"portType"`
|
||||||
PortName string `json:"portName"`
|
PortName string `json:"portName"`
|
||||||
|
|
60
go/pkg/zerotier/fingerprint.go
Normal file
60
go/pkg/zerotier/fingerprint.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2024-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
//#cgo CFLAGS: -O3
|
||||||
|
//#include "../../native/GoGlue.h"
|
||||||
|
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)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(fpb) != 53 {
|
||||||
|
return nil, errors.New("invalid fingerprint length")
|
||||||
|
}
|
||||||
|
var fp Fingerprint
|
||||||
|
fp.Address, _ = NewAddressFromBytes(fpb[0:5])
|
||||||
|
copy(fp.Hash[:],fpb[5:])
|
||||||
|
return &fp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fp *Fingerprint) String() string {
|
||||||
|
var tmp [53]byte
|
||||||
|
fp.Address.CopyTo(tmp[0:5])
|
||||||
|
copy(tmp[5:],fp.Hash[:])
|
||||||
|
return ztBase32.EncodeToString(tmp[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fp *Fingerprint) apiFingerprint() *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
|
||||||
|
}
|
|
@ -498,7 +498,7 @@ func (n *Node) SetLocalConfig(lc *LocalConfig) (restartRequired bool, err error)
|
||||||
|
|
||||||
// Join a network.
|
// Join a network.
|
||||||
// If tap is nil, the default system tap for this OS/platform is used (if available).
|
// If tap is nil, the default system tap for this OS/platform is used (if available).
|
||||||
func (n *Node) Join(nwid NetworkID, settings *NetworkLocalSettings, tap Tap) (*Network, error) {
|
func (n *Node) Join(nwid NetworkID, controllerFingerprint *Fingerprint, settings *NetworkLocalSettings, tap Tap) (*Network, error) {
|
||||||
n.networksLock.RLock()
|
n.networksLock.RLock()
|
||||||
if nw, have := n.networks[nwid]; have {
|
if nw, have := n.networks[nwid]; have {
|
||||||
n.infoLog.Printf("join network %.16x ignored: already a member", nwid)
|
n.infoLog.Printf("join network %.16x ignored: already a member", nwid)
|
||||||
|
@ -512,7 +512,11 @@ func (n *Node) Join(nwid NetworkID, settings *NetworkLocalSettings, tap Tap) (*N
|
||||||
if tap != nil {
|
if tap != nil {
|
||||||
panic("non-native taps not yet implemented")
|
panic("non-native taps not yet implemented")
|
||||||
}
|
}
|
||||||
ntap := C.ZT_GoNode_join(n.gn, C.uint64_t(nwid))
|
var fp *C.ZT_Fingerprint
|
||||||
|
if controllerFingerprint != nil {
|
||||||
|
fp = controllerFingerprint.apiFingerprint()
|
||||||
|
}
|
||||||
|
ntap := C.ZT_GoNode_join(n.gn, C.uint64_t(nwid), fp)
|
||||||
if ntap == nil {
|
if ntap == nil {
|
||||||
n.infoLog.Printf("join network %.16x failed: tap device failed to initialize (check drivers / kernel modules)", uint64(nwid))
|
n.infoLog.Printf("join network %.16x failed: tap device failed to initialize (check drivers / kernel modules)", uint64(nwid))
|
||||||
return nil, ErrTapInitFailed
|
return nil, ErrTapInitFailed
|
||||||
|
|
|
@ -206,7 +206,7 @@ struct NetworkConfig : TriviallyCopyable
|
||||||
ZT_INLINE bool permitsBridging(const Address &fromPeer) const noexcept
|
ZT_INLINE bool permitsBridging(const Address &fromPeer) const noexcept
|
||||||
{
|
{
|
||||||
for(unsigned int i=0;i<specialistCount;++i) {
|
for(unsigned int i=0;i<specialistCount;++i) {
|
||||||
if ((fromPeer == specialists[i])&&((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0))
|
if ((fromPeer.toInt() == (specialists[i] & ZT_ADDRESS_MASK))&&((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue