mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-21 10:01:46 +00:00
Peers and paths
This commit is contained in:
parent
ccc9be2d4d
commit
90d4d79828
@ -336,14 +336,16 @@ extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath)
|
||||
gn->run = true;
|
||||
|
||||
gn->backgroundTaskThread = std::thread([gn] {
|
||||
int64_t lastScannedMulticastGroups = 0;
|
||||
int64_t lastCheckedTaps = 0;
|
||||
while (gn->run) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
const int64_t now = OSUtils::now();
|
||||
|
||||
if (now >= gn->nextBackgroundTaskDeadline)
|
||||
gn->node->processBackgroundTasks(nullptr,now,&(gn->nextBackgroundTaskDeadline));
|
||||
if ((now - lastScannedMulticastGroups) > 5000) {
|
||||
lastScannedMulticastGroups = now;
|
||||
|
||||
if ((now - lastCheckedTaps) > 10000) {
|
||||
lastCheckedTaps = now;
|
||||
std::vector<MulticastGroup> added,removed;
|
||||
std::lock_guard<std::mutex> tl(gn->taps_l);
|
||||
for(auto t=gn->taps.begin();t!=gn->taps.end();++t) {
|
||||
@ -354,6 +356,8 @@ extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath)
|
||||
goHandleTapAddedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
|
||||
for(auto g=removed.begin();g!=removed.end();++g)
|
||||
goHandleTapRemovedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
|
||||
|
||||
t->second->syncRoutes();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -705,8 +709,3 @@ extern "C" int ZT_GoTap_removeRoute(ZT_GoTap *tap,int targetAf,const void *targe
|
||||
}
|
||||
return reinterpret_cast<EthernetTap *>(tap)->removeRoute(target,via,metric);
|
||||
}
|
||||
|
||||
extern "C" int ZT_GoTap_syncRoutes(ZT_GoTap *tap)
|
||||
{
|
||||
return reinterpret_cast<EthernetTap *>(tap)->syncRoutes();
|
||||
}
|
||||
|
@ -95,8 +95,6 @@ int ZT_GoTap_addRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int target
|
||||
|
||||
int ZT_GoTap_removeRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric);
|
||||
|
||||
int ZT_GoTap_syncRoutes(ZT_GoTap *tap);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -31,6 +31,17 @@ func NewAddressFromString(s string) (Address, error) {
|
||||
return Address(a & 0xffffffffff), err
|
||||
}
|
||||
|
||||
// NewAddressFromBytes reads a 5-byte 40-bit address.
|
||||
func NewAddressFromBytes(b []byte) (Address, error) {
|
||||
if len(b) < 5 {
|
||||
return Address(0), ErrInvalidZeroTierAddress
|
||||
}
|
||||
return Address((uint64(b[0]) << 32) | (uint64(b[1]) << 24) | (uint64(b[2]) << 16) | (uint64(b[3]) << 8) | uint64(b[4])), nil
|
||||
}
|
||||
|
||||
// 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 }
|
||||
|
||||
// String returns this address's 10-digit hex identifier
|
||||
func (a Address) String() string {
|
||||
return fmt.Sprintf("%.10x", uint64(a))
|
||||
|
@ -23,6 +23,7 @@ const (
|
||||
ErrNodeInitFailed Err = "unable to initialize core Node instance"
|
||||
ErrInvalidMACAddress Err = "invalid MAC address"
|
||||
ErrInvalidZeroTierAddress Err = "invalid ZeroTier address"
|
||||
ErrInvalidNetworkID Err = "invalid network ID"
|
||||
ErrInvalidParameter Err = "invalid parameter"
|
||||
ErrTapInitFailed Err = "unable to create native Tap instance"
|
||||
ErrUncrecognizedIdentityType Err = "unrecognized identity type"
|
||||
|
@ -123,9 +123,15 @@ func (id *Identity) PrivateKeyString() string {
|
||||
// PublicKeyString returns the address and public key (identity.public contents).
|
||||
// An empty string is returned if this identity is invalid or not initialized.
|
||||
func (id *Identity) String() string {
|
||||
if len(id.publicKey) == IdentityTypeC25519PublicKeySize {
|
||||
s := fmt.Sprintf("%.10x:0:%x", id.address, id.publicKey)
|
||||
return s
|
||||
switch id.idtype {
|
||||
case IdentityTypeC25519:
|
||||
if len(id.publicKey) == IdentityTypeC25519PublicKeySize {
|
||||
return fmt.Sprintf("%.10x:0:%x", id.address, id.publicKey)
|
||||
}
|
||||
case IdentityTypeP384:
|
||||
if len(id.publicKey) == IdentityTypeP384PublicKeySize {
|
||||
return fmt.Sprintf("%.10x:1:%s", uint64(id.address), base32StdLowerCase.EncodeToString(id.publicKey))
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||
var base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
|
||||
|
||||
// TimeMs returns the time in milliseconds since epoch.
|
||||
func TimeMs() int64 { return int64(time.Now().UnixNano()) / int64(1000000) }
|
||||
|
@ -14,6 +14,7 @@
|
||||
package zerotier
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
@ -28,17 +29,32 @@ type NetworkID uint64
|
||||
// NewNetworkIDFromString parses a network ID in string form
|
||||
func NewNetworkIDFromString(s string) (NetworkID, error) {
|
||||
if len(s) != 16 {
|
||||
return NetworkID(0), ErrInvalidZeroTierAddress
|
||||
return NetworkID(0), ErrInvalidNetworkID
|
||||
}
|
||||
n, err := strconv.ParseUint(s, 16, 64)
|
||||
return NetworkID(n), err
|
||||
}
|
||||
|
||||
// NewNetworkIDFromBytes reads an 8-byte / 64-bit network ID.
|
||||
func NewNetworkIDFromBytes(b []byte) (NetworkID, error) {
|
||||
if len(b) < 8 {
|
||||
return NetworkID(0), ErrInvalidNetworkID
|
||||
}
|
||||
return NetworkID(binary.BigEndian.Uint64(b)), nil
|
||||
}
|
||||
|
||||
// String returns this network ID's 16-digit hex identifier
|
||||
func (n NetworkID) String() string {
|
||||
return fmt.Sprintf("%.16x", uint64(n))
|
||||
}
|
||||
|
||||
// Bytes returns this network ID as an 8-byte / 64-bit big-endian value.
|
||||
func (n NetworkID) Bytes() []byte {
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(n))
|
||||
return b[:]
|
||||
}
|
||||
|
||||
// MarshalJSON marshals this NetworkID as a string
|
||||
func (n NetworkID) MarshalJSON() ([]byte, error) {
|
||||
return []byte("\"" + n.String() + "\""), nil
|
||||
@ -56,7 +72,7 @@ func (n *NetworkID) UnmarshalJSON(j []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// NetworkConfig represents the network's current state
|
||||
// NetworkConfig represents the network's current configuration as distributed by its network controller.
|
||||
type NetworkConfig struct {
|
||||
// ID is this network's 64-bit globally unique identifier
|
||||
ID NetworkID
|
||||
|
@ -266,9 +266,9 @@ func (n *Node) RemoveDynamicRoot(dnsName string) {
|
||||
C.free(unsafe.Pointer(dn))
|
||||
}
|
||||
|
||||
// ListRoots retrieves a list of root servers on this node and their preferred and online status.
|
||||
func (n *Node) ListRoots() []Root {
|
||||
var roots []Root
|
||||
// Roots retrieves a list of root servers on this node and their preferred and online status.
|
||||
func (n *Node) Roots() []*Root {
|
||||
var roots []*Root
|
||||
rl := C.ZT_Node_listRoots(unsafe.Pointer(n.zn), C.int64_t(TimeMs()))
|
||||
if rl != nil {
|
||||
for i := 0; i < int(rl.count); i++ {
|
||||
@ -282,7 +282,7 @@ func (n *Node) ListRoots() []Root {
|
||||
addrs = append(addrs, a)
|
||||
}
|
||||
}
|
||||
roots = append(roots, Root{
|
||||
roots = append(roots, &Root{
|
||||
DNSName: C.GoString(root.dnsName),
|
||||
Identity: id,
|
||||
Addresses: addrs,
|
||||
@ -291,11 +291,53 @@ func (n *Node) ListRoots() []Root {
|
||||
})
|
||||
}
|
||||
}
|
||||
defer C.ZT_Node_freeQueryResult(unsafe.Pointer(n.zn), unsafe.Pointer(rl))
|
||||
C.ZT_Node_freeQueryResult(unsafe.Pointer(n.zn), unsafe.Pointer(rl))
|
||||
}
|
||||
return roots
|
||||
}
|
||||
|
||||
// Peers retrieves a list of current peers
|
||||
func (n *Node) Peers() []*Peer {
|
||||
var peers []*Peer
|
||||
pl := C.ZT_Node_peers(unsafe.Pointer(n.zn))
|
||||
if pl != nil {
|
||||
for i := uintptr(0); i < uintptr(pl.peerCount); i++ {
|
||||
p := (*C.ZT_Peer)(unsafe.Pointer(uintptr(unsafe.Pointer(pl.peers)) + (i * C.sizeof_ZT_Peer)))
|
||||
p2 := new(Peer)
|
||||
p2.Address = Address(p.address)
|
||||
p2.Version = [3]int{int(p.versionMajor), int(p.versionMinor), int(p.versionRev)}
|
||||
p2.Latency = int(p.latency)
|
||||
p2.Role = int(p.role)
|
||||
p2.Paths = make([]Path, 0, int(p.pathCount))
|
||||
for j := uintptr(0); j < uintptr(p.pathCount); j++ {
|
||||
pt := &p.paths[j]
|
||||
a := sockaddrStorageToUDPAddr(&pt.address)
|
||||
if a != nil {
|
||||
p2.Paths = append(p2.Paths, Path{
|
||||
IP: a.IP,
|
||||
Port: a.Port,
|
||||
LastSend: int64(pt.lastSend),
|
||||
LastReceive: int64(pt.lastReceive),
|
||||
TrustedPathID: uint64(pt.trustedPathId),
|
||||
Latency: float32(pt.latency),
|
||||
PacketDelayVariance: float32(pt.packetDelayVariance),
|
||||
ThroughputDisturbCoeff: float32(pt.throughputDisturbCoeff),
|
||||
PacketErrorRatio: float32(pt.packetErrorRatio),
|
||||
PacketLossRatio: float32(pt.packetLossRatio),
|
||||
Stability: float32(pt.stability),
|
||||
Throughput: uint64(pt.throughput),
|
||||
MaxThroughput: uint64(pt.maxThroughput),
|
||||
Allocation: float32(pt.allocation),
|
||||
})
|
||||
}
|
||||
}
|
||||
peers = append(peers, p2)
|
||||
}
|
||||
C.ZT_Node_freeQueryResult(unsafe.Pointer(n.zn), unsafe.Pointer(pl))
|
||||
}
|
||||
return peers
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (n *Node) multicastSubscribe(nwid uint64, mg *MulticastGroup) {
|
||||
|
34
go/pkg/zerotier/path.go
Normal file
34
go/pkg/zerotier/path.go
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c)2019 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: 2023-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
|
||||
|
||||
import "net"
|
||||
|
||||
// Path is a path to another peer on the network
|
||||
type Path struct {
|
||||
IP net.IP
|
||||
Port int
|
||||
LastSend int64
|
||||
LastReceive int64
|
||||
TrustedPathID uint64
|
||||
Latency float32
|
||||
PacketDelayVariance float32
|
||||
ThroughputDisturbCoeff float32
|
||||
PacketErrorRatio float32
|
||||
PacketLossRatio float32
|
||||
Stability float32
|
||||
Throughput uint64
|
||||
MaxThroughput uint64
|
||||
Allocation float32
|
||||
}
|
23
go/pkg/zerotier/peer.go
Normal file
23
go/pkg/zerotier/peer.go
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c)2019 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: 2023-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
|
||||
|
||||
// Peer is another ZeroTier node
|
||||
type Peer struct {
|
||||
Address Address
|
||||
Version [3]int
|
||||
Latency int
|
||||
Role int
|
||||
Paths []Path
|
||||
}
|
@ -1171,12 +1171,12 @@ typedef struct
|
||||
/**
|
||||
* Time of last send in milliseconds or 0 for never
|
||||
*/
|
||||
uint64_t lastSend;
|
||||
int64_t lastSend;
|
||||
|
||||
/**
|
||||
* Time of last receive in milliseconds or 0 for never
|
||||
*/
|
||||
uint64_t lastReceive;
|
||||
int64_t lastReceive;
|
||||
|
||||
/**
|
||||
* Is this a trusted path? If so this will be its nonzero ID.
|
||||
|
Loading…
x
Reference in New Issue
Block a user