mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
More wiring up of addroot/removeroot etc.
This commit is contained in:
parent
5c6bf9d0a4
commit
e9656ecf11
13 changed files with 122 additions and 123 deletions
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* 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 cli
|
||||
|
||||
// AddRoot CLI command
|
||||
func AddRoot(basePath, authToken string, args []string) {
|
||||
}
|
|
@ -41,13 +41,13 @@ Commands:
|
|||
service Start as service
|
||||
status Show ZeroTier status and config
|
||||
peers Show VL1 peers and link information
|
||||
roots Show only root peers
|
||||
addroot <identity> [IP/port] Add root with optional bootstrap IP
|
||||
removeroot <address|identity> Remove root
|
||||
join <network ID> Join a virtual network
|
||||
leave <network ID> Leave a virtual network
|
||||
networks List joined VL2 virtual networks
|
||||
network <network ID> Show verbose network info
|
||||
addroot <identity> [IP/port] Add root with optional bootstrap IP
|
||||
removeroot <identity|address> Remove root
|
||||
roots Show configured VL1 root servers
|
||||
set <network ID> [option] [value] Get or set a network config option
|
||||
manageips <boolean> Is IP management allowed?
|
||||
manageroutes <boolean> Is route management allowed?
|
||||
|
|
|
@ -16,45 +16,52 @@ package cli
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"zerotier/pkg/zerotier"
|
||||
)
|
||||
|
||||
// Peers CLI command
|
||||
func Peers(basePath, authToken string, args []string, jsonOutput bool) {
|
||||
// Peers CLI command (also used for 'roots' command with rootsOnly set to true)
|
||||
func Peers(basePath, authToken string, args []string, jsonOutput bool, rootsOnly bool) {
|
||||
var peers []zerotier.Peer
|
||||
clock := apiGet(basePath, authToken, "/peer", &peers)
|
||||
apiGet(basePath, authToken, "/peer", &peers)
|
||||
|
||||
if rootsOnly {
|
||||
roots := make([]zerotier.Peer, 0, len(peers))
|
||||
for i := range peers {
|
||||
if peers[i].Root {
|
||||
roots = append(roots, peers[i])
|
||||
}
|
||||
}
|
||||
peers = roots
|
||||
}
|
||||
|
||||
if jsonOutput {
|
||||
fmt.Println(jsonDump(&peers))
|
||||
} else {
|
||||
fmt.Printf("<address> <ver> <role> <lat> <link> <lastTX> <lastRX> <path(s)>\n")
|
||||
fmt.Printf("<address> <ver> <root> <lat(ms)> <path(s)>\n")
|
||||
for _, peer := range peers {
|
||||
role := "LEAF"
|
||||
link := "RELAY"
|
||||
lastTX, lastRX := int64(0), int64(0)
|
||||
address := ""
|
||||
if len(peer.Paths) > 0 {
|
||||
link = "DIRECT"
|
||||
lastTX, lastRX = clock-peer.Paths[0].LastSend, clock-peer.Paths[0].LastReceive
|
||||
if lastTX < 0 {
|
||||
lastTX = 0
|
||||
}
|
||||
if lastRX < 0 {
|
||||
lastRX = 0
|
||||
}
|
||||
address = fmt.Sprintf("%s/%d", peer.Paths[0].IP.String(), peer.Paths[0].Port)
|
||||
root := ""
|
||||
if peer.Root {
|
||||
root = " *"
|
||||
}
|
||||
fmt.Printf("%.10x %-7s %-6s %-5d %-6s %-8d %-8d %s\n",
|
||||
|
||||
var paths strings.Builder
|
||||
if len(peer.Paths) > 0 {
|
||||
if paths.Len() > 0 {
|
||||
paths.WriteRune(' ')
|
||||
}
|
||||
paths.WriteString(fmt.Sprintf("%s/%d", peer.Paths[0].IP.String(), peer.Paths[0].Port))
|
||||
} else {
|
||||
paths.WriteString("(relayed)")
|
||||
}
|
||||
|
||||
fmt.Printf("%.10x %-7s %-6s %-9d %s\n",
|
||||
uint64(peer.Address),
|
||||
fmt.Sprintf("%d.%d.%d", peer.Version[0], peer.Version[1], peer.Version[2]),
|
||||
role,
|
||||
root,
|
||||
peer.Latency,
|
||||
link,
|
||||
lastTX,
|
||||
lastRX,
|
||||
address,
|
||||
)
|
||||
paths.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* 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 cli
|
||||
|
||||
// RemoveRoot CLI command
|
||||
func RemoveRoot(basePath, authToken string, args []string) {
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* 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 cli
|
||||
|
||||
// Roots CLI command
|
||||
func Roots(basePath, authToken string, args []string, jsonOutput bool) {
|
||||
}
|
52
go/cmd/zerotier/cli/setroot.go
Normal file
52
go/cmd/zerotier/cli/setroot.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"zerotier/pkg/zerotier"
|
||||
)
|
||||
|
||||
// SetRoot CLI command, used for addroot and removeroot.
|
||||
func SetRoot(basePath, authToken string, args []string, root bool) {
|
||||
if len(args) < 1 || len(args) > 2 {
|
||||
Help()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
id := readIdentity(args[0])
|
||||
if id == nil {
|
||||
fmt.Printf("ERROR: invalid identity '%s' (tried literal or reading as file)\n",args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var bootstrap *zerotier.InetAddress
|
||||
if len(args) == 2 {
|
||||
bootstrap = zerotier.NewInetAddressFromString(args[1])
|
||||
if bootstrap == nil || bootstrap.Nil() {
|
||||
fmt.Printf("ERROR: invalid bootstrap address '%s'\n",args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
var peer zerotier.PeerMutableFields
|
||||
peer.Identity = id
|
||||
peer.Bootstrap = bootstrap
|
||||
peer.Root = &root
|
||||
apiPost(basePath, authToken, "/peer/"+id.Address().String(), &peer, nil)
|
||||
fmt.Printf("OK %s", id.String())
|
||||
os.Exit(0)
|
||||
}
|
|
@ -133,16 +133,16 @@ func main() {
|
|||
cli.Status(basePath, authToken, cmdArgs, *jflag)
|
||||
case "peers", "listpeers":
|
||||
authTokenRequired(authToken)
|
||||
cli.Peers(basePath, authToken, cmdArgs, *jflag)
|
||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
|
||||
case "roots", "listroots":
|
||||
authTokenRequired(authToken)
|
||||
cli.Roots(basePath, authToken, cmdArgs, *jflag)
|
||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
|
||||
case "addroot":
|
||||
authTokenRequired(authToken)
|
||||
cli.AddRoot(basePath, authToken, cmdArgs)
|
||||
cli.SetRoot(basePath, authToken, cmdArgs, true)
|
||||
case "removeroot":
|
||||
authTokenRequired(authToken)
|
||||
cli.RemoveRoot(basePath, authToken, cmdArgs)
|
||||
cli.SetRoot(basePath, authToken, cmdArgs, false)
|
||||
case "identity":
|
||||
cli.Identity(cmdArgs)
|
||||
case "networks", "listnetworks":
|
||||
|
|
|
@ -226,12 +226,6 @@ func apiCheckAuth(out http.ResponseWriter, req *http.Request, token string) bool
|
|||
return false
|
||||
}
|
||||
|
||||
type peerMutableFields struct {
|
||||
Identity *Identity `json:"identity"`
|
||||
Role *int `json:"role"`
|
||||
Bootstrap *InetAddress `json:"bootstrap,omitempty"`
|
||||
}
|
||||
|
||||
// createAPIServer creates and starts an HTTP server for a given node
|
||||
func createAPIServer(basePath string, node *Node) (*http.Server, *http.Server, error) {
|
||||
// Read authorization token, automatically generating one if it's missing
|
||||
|
@ -372,14 +366,14 @@ func createAPIServer(basePath string, node *Node) (*http.Server, *http.Server, e
|
|||
_ = apiSendObj(out, req, http.StatusNotFound, &APIErr{"peer not found"})
|
||||
return
|
||||
}
|
||||
var peerChanges peerMutableFields
|
||||
var peerChanges PeerMutableFields
|
||||
if apiReadObj(out, req, &peerChanges) == nil {
|
||||
if peerChanges.Role != nil || peerChanges.Bootstrap != nil {
|
||||
if peerChanges.Root != nil || peerChanges.Bootstrap != nil {
|
||||
peers := node.Peers()
|
||||
for _, p := range peers {
|
||||
if p.Address == queriedID && (peerChanges.Identity == nil || peerChanges.Identity.Equals(p.Identity)) {
|
||||
if peerChanges.Role != nil && *peerChanges.Role != p.Role {
|
||||
if *peerChanges.Role == PeerRoleRoot {
|
||||
if peerChanges.Root != nil && *peerChanges.Root != p.Root {
|
||||
if *peerChanges.Root {
|
||||
_ = node.AddRoot(p.Identity, peerChanges.Bootstrap)
|
||||
} else {
|
||||
node.RemoveRoot(p.Identity)
|
||||
|
|
|
@ -105,6 +105,11 @@ type InetAddress struct {
|
|||
Port int
|
||||
}
|
||||
|
||||
// Nil returns true if this InetAddress is empty.
|
||||
func (ina *InetAddress) Nil() bool {
|
||||
return len(ina.IP) == 0
|
||||
}
|
||||
|
||||
// Less returns true if this IP/port is lexicographically less than another
|
||||
func (ina *InetAddress) Less(i2 *InetAddress) bool {
|
||||
c := bytes.Compare(ina.IP, i2.IP)
|
||||
|
|
|
@ -80,6 +80,7 @@ var (
|
|||
|
||||
// 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
|
||||
)
|
||||
|
||||
|
@ -130,6 +131,9 @@ 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
|
||||
|
@ -242,17 +246,18 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
}
|
||||
|
||||
nodesByUserPtrLock.Lock()
|
||||
nodesByUserPtr[uintptr(unsafe.Pointer(n))] = n
|
||||
nodesByUserPtrCtr++
|
||||
n.cPtr = nodesByUserPtrCtr
|
||||
nodesByUserPtr[n.cPtr] = n
|
||||
nodesByUserPtrLock.Unlock()
|
||||
|
||||
// Instantiate GoNode and friends from the land of C/C++
|
||||
cPath := C.CString(basePath)
|
||||
n.gn = C.ZT_GoNode_new(cPath, C.uintptr_t(uintptr(unsafe.Pointer(n))))
|
||||
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, uintptr(unsafe.Pointer(n)))
|
||||
delete(nodesByUserPtr, n.cPtr)
|
||||
nodesByUserPtrLock.Unlock()
|
||||
return nil, ErrNodeInitFailed
|
||||
}
|
||||
|
@ -261,7 +266,7 @@ func NewNode(basePath string) (n *Node, err error) {
|
|||
if err != nil {
|
||||
n.infoLog.Printf("FATAL: error obtaining node's identity")
|
||||
nodesByUserPtrLock.Lock()
|
||||
delete(nodesByUserPtr, uintptr(unsafe.Pointer(n)))
|
||||
delete(nodesByUserPtr, n.cPtr)
|
||||
nodesByUserPtrLock.Unlock()
|
||||
C.ZT_GoNode_delete(n.gn)
|
||||
return nil, err
|
||||
|
@ -600,7 +605,7 @@ func (n *Node) Peers() []*Peer {
|
|||
p2.IdentityHash = hex.EncodeToString((*[48]byte)(unsafe.Pointer(&p.identityHash[0]))[:])
|
||||
p2.Version = [3]int{int(p.versionMajor), int(p.versionMinor), int(p.versionRev)}
|
||||
p2.Latency = int(p.latency)
|
||||
p2.Role = int(p.role)
|
||||
p2.Root = p.root != 0
|
||||
p2.Bootstrap = NewInetAddressFromSockaddr(unsafe.Pointer(&p.bootstrap))
|
||||
|
||||
p2.Paths = make([]Path, 0, int(p.pathCount))
|
||||
|
|
|
@ -13,14 +13,6 @@
|
|||
|
||||
package zerotier
|
||||
|
||||
// Peer roles must be the same as in ZeroTierCore.h.
|
||||
|
||||
// PeerRoleLeaf indicates a normal leaf node.
|
||||
const PeerRoleLeaf = 0
|
||||
|
||||
// PeerRoleRoot indicates a root peer.
|
||||
const PeerRoleRoot = 1
|
||||
|
||||
// Peer is another ZeroTier node
|
||||
type Peer struct {
|
||||
Address Address `json:"address"`
|
||||
|
@ -28,7 +20,14 @@ type Peer struct {
|
|||
IdentityHash string `json:"identityHash"`
|
||||
Version [3]int `json:"version"`
|
||||
Latency int `json:"latency"`
|
||||
Role int `json:"role"`
|
||||
Root bool `json:"root"`
|
||||
Bootstrap *InetAddress `json:"bootstrap,omitempty"`
|
||||
Paths []Path `json:"paths,omitempty"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
|
|
@ -1323,15 +1323,6 @@ typedef struct
|
|||
int preferred;
|
||||
} ZT_PeerPhysicalPath;
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this peer have?
|
||||
*/
|
||||
enum ZT_PeerRole
|
||||
{
|
||||
ZT_PEER_ROLE_LEAF = 0,
|
||||
ZT_PEER_ROLE_ROOT = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Peer status result buffer
|
||||
*/
|
||||
|
@ -1373,9 +1364,9 @@ typedef struct
|
|||
int latency;
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this device have?
|
||||
* If non-zero this peer is a root
|
||||
*/
|
||||
enum ZT_PeerRole role;
|
||||
int root;
|
||||
|
||||
/**
|
||||
* Bootstrap address
|
||||
|
|
|
@ -446,7 +446,7 @@ ZT_PeerList *Node::peers() const
|
|||
p->latency = (int)(*pi)->latency();
|
||||
if (p->latency >= 0xffff)
|
||||
p->latency = -1;
|
||||
p->role = RR->topology->isRoot((*pi)->identity()) ? ZT_PEER_ROLE_ROOT : ZT_PEER_ROLE_LEAF;
|
||||
p->root = RR->topology->isRoot((*pi)->identity()) ? 1 : 0;
|
||||
memcpy(&p->bootstrap,&((*pi)->bootstrap()),sizeof(sockaddr_storage));
|
||||
|
||||
std::vector< SharedPtr<Path> > paths;
|
||||
|
|
Loading…
Add table
Reference in a new issue