mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +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
|
||||
func Join(basePath, authToken string, args []string) {
|
||||
if len(args) != 1 {
|
||||
if len(args) < 1 || len(args) > 2 {
|
||||
Help()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@ -39,9 +39,28 @@ func Join(basePath, authToken string, args []string) {
|
|||
}
|
||||
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
|
||||
network.ID = zerotier.NetworkID(nwid)
|
||||
apiPost(basePath, authToken, "/network/"+nwids, &network, nil)
|
||||
fmt.Printf("OK %s", nwids)
|
||||
network.ControllerFingerprint = fp
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -593,7 +593,7 @@ static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,
|
|||
&(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 {
|
||||
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)
|
||||
return nullptr;
|
||||
gn->taps[nwid] = tap;
|
||||
gn->node->join(nwid,tap.get(),nullptr);
|
||||
gn->node->join(nwid,controllerFingerprint,tap.get(),nullptr);
|
||||
return (ZT_GoTap *)tap.get();
|
||||
} catch ( ... ) {
|
||||
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 */
|
||||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (a Address) IsReserved() bool { return a == 0 || (a>>32) == 0xff }
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ type APINetwork struct {
|
|||
ID NetworkID `json:"id"`
|
||||
Config NetworkConfig `json:"config"`
|
||||
Settings *NetworkLocalSettings `json:"settings,omitempty"`
|
||||
ControllerFingerprint *Fingerprint `json:"controllerFingerprint,omitempty"`
|
||||
MulticastSubscriptions []*MulticastGroup `json:"multicastSubscriptions,omitempty"`
|
||||
PortType string `json:"portType"`
|
||||
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.
|
||||
// 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()
|
||||
if nw, have := n.networks[nwid]; have {
|
||||
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 {
|
||||
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 {
|
||||
n.infoLog.Printf("join network %.16x failed: tap device failed to initialize (check drivers / kernel modules)", uint64(nwid))
|
||||
return nil, ErrTapInitFailed
|
||||
|
|
|
@ -206,7 +206,7 @@ struct NetworkConfig : TriviallyCopyable
|
|||
ZT_INLINE bool permitsBridging(const Address &fromPeer) const noexcept
|
||||
{
|
||||
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 false;
|
||||
|
|
Loading…
Add table
Reference in a new issue