mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
Move some toString/fromString to C++ since any ZT code base would need it, and stub out the controller commands.
This commit is contained in:
parent
a5390b1bc8
commit
1970dab13d
17 changed files with 414 additions and 67 deletions
17
go/cmd/zerotier/cli/controller.go
Normal file
17
go/cmd/zerotier/cli/controller.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
func Controller(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
|
}
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Help dumps help to stdout
|
|
||||||
func Help() {
|
func Help() {
|
||||||
fmt.Printf(`ZeroTier Network Hypervisor Service Version %d.%d.%d
|
fmt.Printf(`ZeroTier Network Hypervisor Service Version %d.%d.%d
|
||||||
(c)2013-2020 ZeroTier, Inc.
|
(c)2013-2020 ZeroTier, Inc.
|
||||||
|
@ -38,11 +37,11 @@ Commands:
|
||||||
service Start as service
|
service Start as service
|
||||||
status Show node status, identity, and config
|
status Show node status, identity, and config
|
||||||
peers List all VL1 peers
|
peers List all VL1 peers
|
||||||
join <network ID> [fingerprint] Join a virtual network
|
join <network> [fingerprint] Join a virtual network
|
||||||
leave <network ID> Leave a virtual network
|
leave <network> Leave a virtual network
|
||||||
networks List VL2 virtual networks
|
networks List VL2 virtual networks
|
||||||
network <network ID> Show verbose network info
|
network <network> Show verbose network info
|
||||||
set <network ID> [option] [value] Get or set a network config option
|
set <network> [option] [value] Get or set a network config option
|
||||||
manageips <boolean> Is IP management allowed?
|
manageips <boolean> Is IP management allowed?
|
||||||
manageroutes <boolean> Is route management allowed?
|
manageroutes <boolean> Is route management allowed?
|
||||||
globalips <boolean> Allow assignment of global IPs?
|
globalips <boolean> Allow assignment of global IPs?
|
||||||
|
@ -62,11 +61,20 @@ Commands:
|
||||||
verify <identity> <file> <sig> Verify a signature
|
verify <identity> <file> <sig> Verify a signature
|
||||||
locator <command> [args] Locator management commands
|
locator <command> [args] Locator management commands
|
||||||
new <identity> <address> [...] Create and sign a new locator
|
new <identity> <address> [...] Create and sign a new locator
|
||||||
show <locator> [<identity>] Show locator information
|
show <locator> [identity] Show locator information
|
||||||
roots List root peers
|
root [command] Root management commands
|
||||||
addroot <identity> <locator> Add a root or update its locator
|
list List root peers (same as no command)
|
||||||
addroot <url> Add or update roots from a URL
|
add <identity> <locator> Add or manually update a root
|
||||||
removeroot <address> Remove a peer from the root list
|
add <url> Add or update root(s) from a URL
|
||||||
|
remove <address> Un-designate a peer as a root
|
||||||
|
controller <command> [option] Local controller management commands
|
||||||
|
networks List networks run by local controller
|
||||||
|
new Create a new network
|
||||||
|
set <network> [setting] [value] Show or modify network settings
|
||||||
|
members <network> List members of a network
|
||||||
|
member <network> [setting] [value] Show or modify member level settings
|
||||||
|
auth <address|fingerprint> Authorize a peer
|
||||||
|
deauth <address|fingerprint> Deauthorize a peer
|
||||||
|
|
||||||
The 'service' command does not exit until the service receives a signal.
|
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
|
This is typically run from launchd (Mac), systemd or init (Linux), a Windows
|
||||||
|
@ -78,6 +86,5 @@ node.
|
||||||
|
|
||||||
Identities can be specified verbatim on the command line or as a path to
|
Identities can be specified verbatim on the command line or as a path to
|
||||||
a file. This is detected automatically.
|
a file. This is detected automatically.
|
||||||
|
|
||||||
`,zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
|
`,zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Identity command
|
|
||||||
func Identity(args []string) {
|
func Identity(args []string) {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
|
|
83
go/cmd/zerotier/cli/locator.go
Normal file
83
go/cmd/zerotier/cli/locator.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
"time"
|
||||||
|
"zerotier/pkg/zerotier"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Locator(args []string) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch args[0] {
|
||||||
|
|
||||||
|
case "new":
|
||||||
|
if len(args) >= 3 {
|
||||||
|
id := readIdentity(args[1])
|
||||||
|
if !id.HasPrivate() {
|
||||||
|
fmt.Println("ERROR: identity is missing private key and can't be used to sign a locator.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
var eps []zerotier.Endpoint
|
||||||
|
for i:=2;i<len(args);i++ {
|
||||||
|
ep, _ := zerotier.NewEndpointFromString(args[i])
|
||||||
|
if ep != nil {
|
||||||
|
eps = append(eps, *ep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loc, err := zerotier.NewLocator(zerotier.TimeMs(),eps,id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to create or sign locator: %s\n",err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println(loc.String())
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "show":
|
||||||
|
if len(args) > 1 && len(args) < 4 {
|
||||||
|
loc := readLocator(args[1])
|
||||||
|
var id *zerotier.Identity
|
||||||
|
if len(args) == 3 {
|
||||||
|
id = readIdentity(args[2])
|
||||||
|
}
|
||||||
|
ts, fp, eps, valid, _ := loc.GetInfo(id)
|
||||||
|
fmt.Printf("%s\n Timestamp: %s (%d)\n Validity: ",fp.String(),time.Unix(ts / 1000,ts * 1000).String(),ts)
|
||||||
|
if id == nil {
|
||||||
|
fmt.Printf("(no identity provided)\n")
|
||||||
|
} else {
|
||||||
|
if valid {
|
||||||
|
fmt.Printf("SIGNATURE VERIFIED\n")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("! INVALID SIGNATURE\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Print(" Endpoints: ")
|
||||||
|
for i := range eps {
|
||||||
|
if i > 0 {
|
||||||
|
fmt.Print(" ")
|
||||||
|
}
|
||||||
|
fmt.Print(eps[i].String())
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Help()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
|
@ -99,23 +99,43 @@ func readIdentity(s string) *zerotier.Identity {
|
||||||
}
|
}
|
||||||
idData, err := ioutil.ReadFile(s)
|
idData, err := ioutil.ReadFile(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("FATAL: identity '%s' cannot be resolved as file or literal identity: %s", s, err.Error())
|
fmt.Printf("FATAL: identity '%s' cannot be parsed as file or literal: %s", s, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
id, err := zerotier.NewIdentityFromString(string(idData))
|
id, err := zerotier.NewIdentityFromString(string(idData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("FATAL: identity '%s' cannot be resolved as file or literal identity: %s", s, err.Error())
|
fmt.Printf("FATAL: identity '%s' cannot be parsed as file or literal: %s", s, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readLocator(s string) *zerotier.Locator {
|
||||||
|
if strings.ContainsRune(s, '@') {
|
||||||
|
loc, _ := zerotier.NewLocatorFromString(s)
|
||||||
|
if loc != nil {
|
||||||
|
return loc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locData, err := ioutil.ReadFile(s)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("FATAL: locator '%s' cannot be parsed as file or literal: %s", s, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
loc, err := zerotier.NewLocatorFromString(string(locData))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("FATAL: locator '%s' cannot be parsed as file or literal: %s", s, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return loc
|
||||||
|
}
|
||||||
|
|
||||||
func networkStatusStr(status int) string {
|
func networkStatusStr(status int) string {
|
||||||
switch status {
|
switch status {
|
||||||
case zerotier.NetworkStatusNotFound:
|
case zerotier.NetworkStatusNotFound:
|
||||||
return "NOTFOUND"
|
return "NOTFOUND"
|
||||||
case zerotier.NetworkStatusAccessDenied:
|
case zerotier.NetworkStatusAccessDenied:
|
||||||
return "DENIED"
|
return "ACCESSDENIED"
|
||||||
case zerotier.NetworkStatusRequestConfiguration:
|
case zerotier.NetworkStatusRequestConfiguration:
|
||||||
return "UPDATING"
|
return "UPDATING"
|
||||||
case zerotier.NetworkStatusOK:
|
case zerotier.NetworkStatusOK:
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Network CLI command
|
|
||||||
func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
Help()
|
Help()
|
||||||
|
|
17
go/cmd/zerotier/cli/root.go
Normal file
17
go/cmd/zerotier/cli/root.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
func Root(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
|
}
|
|
@ -127,13 +127,6 @@ func main() {
|
||||||
case "peers", "listpeers", "lspeers":
|
case "peers", "listpeers", "lspeers":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
|
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
|
||||||
case "roots", "listroots", "lsroots":
|
|
||||||
authTokenRequired(authToken)
|
|
||||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
|
|
||||||
case "addroot":
|
|
||||||
// TODO
|
|
||||||
case "removeroot":
|
|
||||||
// TODO
|
|
||||||
case "join":
|
case "join":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Join(basePath, authToken, cmdArgs)
|
cli.Join(basePath, authToken, cmdArgs)
|
||||||
|
@ -151,8 +144,19 @@ func main() {
|
||||||
cli.Set(basePath, authToken, cmdArgs)
|
cli.Set(basePath, authToken, cmdArgs)
|
||||||
case "identity":
|
case "identity":
|
||||||
cli.Identity(cmdArgs)
|
cli.Identity(cmdArgs)
|
||||||
|
case "locator":
|
||||||
|
cli.Locator(cmdArgs)
|
||||||
|
case "root":
|
||||||
|
authTokenRequired(authToken)
|
||||||
|
cli.Root(basePath, authToken, cmdArgs, *jflag)
|
||||||
|
case "controller":
|
||||||
|
authTokenRequired(authToken)
|
||||||
|
cli.Controller(basePath, authToken, cmdArgs, *jflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commands in the 'cli' sub-package do not return, so if we make
|
||||||
|
// it here the command was not recognized.
|
||||||
|
|
||||||
cli.Help()
|
cli.Help()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@ package zerotier
|
||||||
// static inline uint64_t _getAddress(const ZT_Endpoint *ep) { return ep->value.fp.address; }
|
// static inline uint64_t _getAddress(const ZT_Endpoint *ep) { return ep->value.fp.address; }
|
||||||
// static inline uint64_t _getMAC(const ZT_Endpoint *ep) { return ep->value.mac; }
|
// static inline uint64_t _getMAC(const ZT_Endpoint *ep) { return ep->value.mac; }
|
||||||
// static inline const struct sockaddr_storage *_getSS(const ZT_Endpoint *ep) { return &(ep->value.ss); }
|
// static inline const struct sockaddr_storage *_getSS(const ZT_Endpoint *ep) { return &(ep->value.ss); }
|
||||||
|
// static inline void _setSS(ZT_Endpoint *ep,const void *ss) { memcpy(&(ep->value.ss),ss,sizeof(struct sockaddr_storage)); }
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,6 +30,42 @@ type Endpoint struct {
|
||||||
cep C.ZT_Endpoint
|
cep C.ZT_Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEndpointFromString constructs a new endpoint from an InetAddress or Endpoint string.
|
||||||
|
// This will auto detect whether this is a plain InetAddress or an Endpoint in string
|
||||||
|
// format. If the former it's created as a ZT_ENDPOINT_TYPE_IP_UDP endpoint.
|
||||||
|
func NewEndpointFromString(s string) (*Endpoint, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
var ep Endpoint
|
||||||
|
ep.cep._type = C.ZT_ENDPOINT_TYPE_NIL
|
||||||
|
return &ep, nil
|
||||||
|
}
|
||||||
|
if strings.IndexRune(s, '-') > 0 || (strings.IndexRune(s, ':') < 0 && strings.IndexRune(s, '.') < 0) {
|
||||||
|
var ep Endpoint
|
||||||
|
cs := C.CString(s)
|
||||||
|
defer C.free(cs)
|
||||||
|
if C.ZT_Endpoint_fromString(cs) == nil {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
return &ep, nil
|
||||||
|
}
|
||||||
|
inaddr := NewInetAddressFromString(s)
|
||||||
|
if inaddr == nil {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
return NewEndpointFromInetAddress(inaddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEndpointFromInetAddress(addr *InetAddress) (*Endpoint, error) {
|
||||||
|
var ep Endpoint
|
||||||
|
var ss C.struct_sockaddr_storage
|
||||||
|
if !makeSockaddrStorage(addr.IP, addr.Port, &ss) {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
ep.cep._type = C.ZT_ENDPOINT_TYPE_IP_UDP
|
||||||
|
C._setSS(&ep.cep, unsafe.Pointer(&ss))
|
||||||
|
return &ep, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Type returns this endpoint's type.
|
// Type returns this endpoint's type.
|
||||||
func (ep *Endpoint) Type() int {
|
func (ep *Endpoint) Type() int {
|
||||||
return int(ep.cep._type)
|
return int(ep.cep._type)
|
||||||
|
@ -77,15 +114,12 @@ func (ep *Endpoint) MAC() MAC {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *Endpoint) String() string {
|
func (ep *Endpoint) String() string {
|
||||||
switch ep.cep._type {
|
var buf [4096]byte
|
||||||
case EndpointTypeZeroTier:
|
cs := C.ZT_Endpoint_toString(&ep.cep,unsafe.Pointer(&buf[0]),4096)
|
||||||
return fmt.Sprintf("%d/%s", ep.Type(), ep.Fingerprint().String())
|
if cs == nil {
|
||||||
case EndpointTypeEthernet, EndpointTypeWifiDirect, EndpointTypeBluetooth:
|
return "0"
|
||||||
return fmt.Sprintf("%d/%s", ep.Type(), ep.MAC().String())
|
|
||||||
case EndpointTypeIp, EndpointTypeIpUdp, EndpointTypeIpTcp, EndpointTypeIpHttp2:
|
|
||||||
return fmt.Sprintf("%d/%s", ep.Type(), ep.InetAddress().String())
|
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%d", ep.Type())
|
return C.GoString(cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *Endpoint) MarshalJSON() ([]byte, error) {
|
func (ep *Endpoint) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -94,6 +128,15 @@ func (ep *Endpoint) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *Endpoint) UnmarshalJSON(j []byte) error {
|
func (ep *Endpoint) UnmarshalJSON(j []byte) error {
|
||||||
// TODO
|
var s string
|
||||||
|
err := json.Unmarshal(j, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ep2, err := NewEndpointFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ep = *ep2
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ func NewFingerprintFromString(fps string) (*Fingerprint, error) {
|
||||||
if len(fps) < AddressStringLength {
|
if len(fps) < AddressStringLength {
|
||||||
return nil, ErrInvalidZeroTierAddress
|
return nil, ErrInvalidZeroTierAddress
|
||||||
}
|
}
|
||||||
ss := strings.Split(fps, "/")
|
ss := strings.Split(fps, "-")
|
||||||
if len(ss) < 1 || len(ss) > 2 {
|
if len(ss) < 1 || len(ss) > 2 {
|
||||||
return nil, ErrInvalidParameter
|
return nil, ErrInvalidParameter
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func newFingerprintFromCFingerprint(cfp *C.ZT_Fingerprint) *Fingerprint {
|
||||||
|
|
||||||
func (fp *Fingerprint) String() string {
|
func (fp *Fingerprint) String() string {
|
||||||
if len(fp.Hash) == 48 {
|
if len(fp.Hash) == 48 {
|
||||||
return fmt.Sprintf("%.10x/%s", uint64(fp.Address), Base32StdLowerCase.EncodeToString(fp.Hash))
|
return fmt.Sprintf("%.10x-%s", uint64(fp.Address), Base32StdLowerCase.EncodeToString(fp.Hash))
|
||||||
}
|
}
|
||||||
return fp.Address.String()
|
return fp.Address.String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,26 @@ func NewLocatorFromBytes(lb []byte) (*Locator, error) {
|
||||||
return goloc, nil
|
return goloc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewLocatorFromString(s string) (*Locator, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
sb := []byte(s)
|
||||||
|
sb = append(sb,0)
|
||||||
|
loc := C.ZT_Locator_fromString(unsafe.Pointer(&sb[0]))
|
||||||
|
if uintptr(loc) == 0 {
|
||||||
|
return nil, ErrInvalidParameter
|
||||||
|
}
|
||||||
|
goloc := new(Locator)
|
||||||
|
goloc.cl = unsafe.Pointer(loc)
|
||||||
|
runtime.SetFinalizer(goloc, locatorFinalizer)
|
||||||
|
return goloc, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetInfo gets information about this locator, also validating its signature if 'id' is non-nil.
|
// GetInfo gets information about this locator, also validating its signature if 'id' is non-nil.
|
||||||
// If 'id' is nil the 'valid' return value is undefined.
|
// If 'id' is nil the 'valid' return value is undefined.
|
||||||
func (loc *Locator) GetInfo(id *Identity) (fp *Fingerprint, eps []Endpoint, valid bool, err error) {
|
func (loc *Locator) GetInfo(id *Identity) (ts int64, fp *Fingerprint, eps []Endpoint, valid bool, err error) {
|
||||||
|
ts = int64(C.ZT_Locator_timestamp(loc.cl))
|
||||||
cfp := C.ZT_Locator_fingerprint(loc.cl)
|
cfp := C.ZT_Locator_fingerprint(loc.cl)
|
||||||
if uintptr(unsafe.Pointer(cfp)) == 0 {
|
if uintptr(unsafe.Pointer(cfp)) == 0 {
|
||||||
err = ErrInternal
|
err = ErrInternal
|
||||||
|
@ -84,3 +101,14 @@ func (loc *Locator) GetInfo(id *Identity) (fp *Fingerprint, eps []Endpoint, vali
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (loc *Locator) String() string {
|
||||||
|
var buf [4096]byte
|
||||||
|
C.ZT_Locator_toString(loc.cl,unsafe.Pointer(&buf[0]),4096)
|
||||||
|
for i:=range buf {
|
||||||
|
if buf[i] == 0 {
|
||||||
|
return string(buf[0:i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -2123,6 +2123,17 @@ ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZT_SDK_API char *ZT_Endpoint_toString(
|
||||||
|
const ZT_Endpoint *ep,
|
||||||
|
char *buf,
|
||||||
|
int capacity);
|
||||||
|
|
||||||
|
ZT_SDK_API int ZT_Endpoint_fromString(
|
||||||
|
ZT_Endpoint *ep,
|
||||||
|
const char *str);
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and sign a new locator
|
* Create and sign a new locator
|
||||||
*
|
*
|
||||||
|
@ -2149,6 +2160,14 @@ ZT_SDK_API ZT_Locator *ZT_Locator_unmarshal(
|
||||||
const void *data,
|
const void *data,
|
||||||
unsigned int len);
|
unsigned int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a locator from string format
|
||||||
|
*
|
||||||
|
* @param str String format locator
|
||||||
|
* @return Locator or NULL if string is not valid
|
||||||
|
*/
|
||||||
|
ZT_SDK_API ZT_Locator *ZT_Locator_fromString(const char *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize this locator into a buffer
|
* Serialize this locator into a buffer
|
||||||
*
|
*
|
||||||
|
@ -2159,6 +2178,19 @@ ZT_SDK_API ZT_Locator *ZT_Locator_unmarshal(
|
||||||
*/
|
*/
|
||||||
ZT_SDK_API int ZT_Locator_marshal(const ZT_Locator *loc,void *buf,unsigned int bufSize);
|
ZT_SDK_API int ZT_Locator_marshal(const ZT_Locator *loc,void *buf,unsigned int bufSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this locator in string format
|
||||||
|
*
|
||||||
|
* @param loc Locator
|
||||||
|
* @param buf Buffer to store string
|
||||||
|
* @param capacity Capacity of buffer in bytes (recommended size: 4096)
|
||||||
|
* @return Pointer to buffer or NULL if an error occurs
|
||||||
|
*/
|
||||||
|
ZT_SDK_API char *ZT_Locator_toString(
|
||||||
|
const ZT_Locator *loc,
|
||||||
|
char *buf,
|
||||||
|
int capacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pointer to the fingerprint of this locator's signer.
|
* Get a pointer to the fingerprint of this locator's signer.
|
||||||
*
|
*
|
||||||
|
@ -2169,6 +2201,14 @@ ZT_SDK_API int ZT_Locator_marshal(const ZT_Locator *loc,void *buf,unsigned int b
|
||||||
*/
|
*/
|
||||||
ZT_SDK_API const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc);
|
ZT_SDK_API const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a locator's timestamp
|
||||||
|
*
|
||||||
|
* @param loc Locator to query
|
||||||
|
* @return Locator timestamp in milliseconds since epoch
|
||||||
|
*/
|
||||||
|
ZT_SDK_API int64_t ZT_Locator_timestamp(const ZT_Locator *loc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of endpoints in this locator
|
* Get the number of endpoints in this locator
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
void Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
|
char *Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
|
||||||
{
|
{
|
||||||
static const char *const s_endpointTypeChars = ZT_ENDPOINT_TYPE_CHAR_INDEX;
|
static const char *const s_endpointTypeChars = ZT_ENDPOINT_TYPE_CHAR_INDEX;
|
||||||
|
|
||||||
|
@ -30,14 +30,14 @@ void Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
|
||||||
break;
|
break;
|
||||||
case ZT_ENDPOINT_TYPE_ZEROTIER:
|
case ZT_ENDPOINT_TYPE_ZEROTIER:
|
||||||
s[0] = s_endpointTypeChars[ZT_ENDPOINT_TYPE_ZEROTIER];
|
s[0] = s_endpointTypeChars[ZT_ENDPOINT_TYPE_ZEROTIER];
|
||||||
s[1] = '/';
|
s[1] = '-';
|
||||||
zt().toString(s + 2);
|
zt().toString(s + 2);
|
||||||
break;
|
break;
|
||||||
case ZT_ENDPOINT_TYPE_ETHERNET:
|
case ZT_ENDPOINT_TYPE_ETHERNET:
|
||||||
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
|
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
|
||||||
case ZT_ENDPOINT_TYPE_BLUETOOTH:
|
case ZT_ENDPOINT_TYPE_BLUETOOTH:
|
||||||
s[0] = s_endpointTypeChars[this->type];
|
s[0] = s_endpointTypeChars[this->type];
|
||||||
s[1] = '/';
|
s[1] = '-';
|
||||||
eth().toString(s + 2);
|
eth().toString(s + 2);
|
||||||
break;
|
break;
|
||||||
case ZT_ENDPOINT_TYPE_IP:
|
case ZT_ENDPOINT_TYPE_IP:
|
||||||
|
@ -45,10 +45,12 @@ void Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
|
||||||
case ZT_ENDPOINT_TYPE_IP_TCP:
|
case ZT_ENDPOINT_TYPE_IP_TCP:
|
||||||
case ZT_ENDPOINT_TYPE_IP_HTTP2:
|
case ZT_ENDPOINT_TYPE_IP_HTTP2:
|
||||||
s[0] = s_endpointTypeChars[this->type];
|
s[0] = s_endpointTypeChars[this->type];
|
||||||
s[1] = '/';
|
s[1] = '-';
|
||||||
ip().toString(s + 2);
|
ip().toString(s + 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Endpoint::fromString(const char *s) noexcept
|
bool Endpoint::fromString(const char *s) noexcept
|
||||||
|
@ -57,7 +59,7 @@ bool Endpoint::fromString(const char *s) noexcept
|
||||||
if ((!s) || (!*s))
|
if ((!s) || (!*s))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const char *start = strchr(s, '/');
|
const char *start = strchr(s, '-');
|
||||||
if (start) {
|
if (start) {
|
||||||
char tmp[16];
|
char tmp[16];
|
||||||
for (unsigned int i = 0;i < 15;++i) {
|
for (unsigned int i = 0;i < 15;++i) {
|
||||||
|
@ -248,3 +250,26 @@ bool Endpoint::operator<(const Endpoint &ep) const noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
char *ZT_Endpoint_toString(
|
||||||
|
const ZT_Endpoint *ep,
|
||||||
|
char *buf,
|
||||||
|
int capacity)
|
||||||
|
{
|
||||||
|
if ((!ep) || (!buf) || (capacity < ZT_ENDPOINT_STRING_SIZE_MAX))
|
||||||
|
return nullptr;
|
||||||
|
return reinterpret_cast<const ZeroTier::Endpoint *>(ep)->toString(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZT_Endpoint_fromString(
|
||||||
|
ZT_Endpoint *ep,
|
||||||
|
const char *str)
|
||||||
|
{
|
||||||
|
if ((!ep) || (!str))
|
||||||
|
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||||
|
return reinterpret_cast<ZeroTier::Endpoint *>(ep)->fromString(str) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // C API
|
||||||
|
|
|
@ -147,14 +147,9 @@ public:
|
||||||
ZT_INLINE Fingerprint zt() const noexcept
|
ZT_INLINE Fingerprint zt() const noexcept
|
||||||
{ return Fingerprint(this->value.fp); }
|
{ return Fingerprint(this->value.fp); }
|
||||||
|
|
||||||
void toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
|
char *toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
|
||||||
|
|
||||||
ZT_INLINE String toString() const
|
ZT_INLINE String toString() const { char tmp[ZT_ENDPOINT_STRING_SIZE_MAX]; return String(toString(tmp)); }
|
||||||
{
|
|
||||||
char tmp[ZT_ENDPOINT_STRING_SIZE_MAX];
|
|
||||||
toString(tmp);
|
|
||||||
return String(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fromString(const char *s) noexcept;
|
bool fromString(const char *s) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
{
|
{
|
||||||
Address(this->address).toString(s);
|
Address(this->address).toString(s);
|
||||||
if (haveHash()) {
|
if (haveHash()) {
|
||||||
s[ZT_ADDRESS_LENGTH_HEX] = '/';
|
s[ZT_ADDRESS_LENGTH_HEX] = '-';
|
||||||
Utils::b32e(this->hash, ZT_FINGERPRINT_HASH_SIZE, s + (ZT_ADDRESS_LENGTH_HEX + 1), ZT_FINGERPRINT_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
|
Utils::b32e(this->hash, ZT_FINGERPRINT_HASH_SIZE, s + (ZT_ADDRESS_LENGTH_HEX + 1), ZT_FINGERPRINT_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,33 @@ bool Locator::verify(const Identity &id) const noexcept
|
||||||
const unsigned int signlen = marshal(signdata, true);
|
const unsigned int signlen = marshal(signdata, true);
|
||||||
return id.verify(signdata, signlen, m_signature.data(), m_signature.size());
|
return id.verify(signdata, signlen, m_signature.data(), m_signature.size());
|
||||||
}
|
}
|
||||||
} catch ( ... ) {} // fail verify on any unexpected exception
|
} catch (...) {} // fail verify on any unexpected exception
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Locator::toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept
|
||||||
|
{
|
||||||
|
static_assert(ZT_LOCATOR_STRING_SIZE_MAX > ((((ZT_LOCATOR_MARSHAL_SIZE_MAX / 5) + 1) * 8) + ZT_ADDRESS_LENGTH_HEX + 1), "overflow");
|
||||||
|
uint8_t bin[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
||||||
|
Address(m_signer.address).toString(s);
|
||||||
|
s[ZT_ADDRESS_LENGTH_HEX] = '@';
|
||||||
|
Utils::b32e(bin, marshal(bin, false), s + (ZT_ADDRESS_LENGTH_HEX + 1), ZT_LOCATOR_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Locator::fromString(const char *s) noexcept
|
||||||
|
{
|
||||||
|
if (!s)
|
||||||
|
return false;
|
||||||
|
if (strlen(s) < (ZT_ADDRESS_LENGTH_HEX + 1))
|
||||||
|
return false;
|
||||||
|
uint8_t bin[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
||||||
|
const int bl = Utils::b32d(s + (ZT_ADDRESS_LENGTH_HEX + 1), bin, ZT_LOCATOR_MARSHAL_SIZE_MAX);
|
||||||
|
if ((bl <= 0) || (bl > ZT_LOCATOR_MARSHAL_SIZE_MAX))
|
||||||
|
return false;
|
||||||
|
return unmarshal(bin, bl) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool excludeSignature) const noexcept
|
int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool excludeSignature) const noexcept
|
||||||
{
|
{
|
||||||
Utils::storeBigEndian<uint64_t>(data, (uint64_t) m_ts);
|
Utils::storeBigEndian<uint64_t>(data, (uint64_t) m_ts);
|
||||||
|
@ -96,7 +119,7 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept
|
||||||
m_ts = (int64_t) Utils::loadBigEndian<uint64_t>(data);
|
m_ts = (int64_t) Utils::loadBigEndian<uint64_t>(data);
|
||||||
int p = 8;
|
int p = 8;
|
||||||
|
|
||||||
int l = m_signer.unmarshal(data + p,len - p);
|
int l = m_signer.unmarshal(data + p, len - p);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
p += l;
|
p += l;
|
||||||
|
@ -123,7 +146,7 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept
|
||||||
return -1;
|
return -1;
|
||||||
const unsigned int siglen = Utils::loadBigEndian<uint16_t>(data + p);
|
const unsigned int siglen = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
p += 2;
|
p += 2;
|
||||||
if (unlikely((siglen > ZT_SIGNATURE_BUFFER_SIZE) || ((p + (int)siglen) > len)))
|
if (unlikely((siglen > ZT_SIGNATURE_BUFFER_SIZE) || ((p + (int) siglen) > len)))
|
||||||
return -1;
|
return -1;
|
||||||
m_signature.unsafeSetSize(siglen);
|
m_signature.unsafeSetSize(siglen);
|
||||||
Utils::copy(m_signature.data(), data + p, siglen);
|
Utils::copy(m_signature.data(), data + p, siglen);
|
||||||
|
@ -148,9 +171,25 @@ ZT_Locator *ZT_Locator_create(
|
||||||
if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
|
if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||||
for(unsigned int i=0;i<endpointCount;++i)
|
for (unsigned int i = 0;i < endpointCount;++i)
|
||||||
loc->add(reinterpret_cast<const ZeroTier::Endpoint *>(endpoints)[i]);
|
loc->add(reinterpret_cast<const ZeroTier::Endpoint *>(endpoints)[i]);
|
||||||
if (!loc->sign(ts,*reinterpret_cast<const ZeroTier::Identity *>(signer))) {
|
if (!loc->sign(ts, *reinterpret_cast<const ZeroTier::Identity *>(signer))) {
|
||||||
|
delete loc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<ZT_Locator *>(loc);
|
||||||
|
} catch (...) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZT_Locator *ZT_Locator_fromString(const char *str)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!str)
|
||||||
|
return nullptr;
|
||||||
|
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||||
|
if (!loc->fromString(str)) {
|
||||||
delete loc;
|
delete loc;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -168,45 +207,62 @@ ZT_Locator *ZT_Locator_unmarshal(
|
||||||
if ((!data) || (len == 0))
|
if ((!data) || (len == 0))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||||
if (loc->unmarshal(reinterpret_cast<const uint8_t *>(data),(int)len) <= 0) {
|
if (loc->unmarshal(reinterpret_cast<const uint8_t *>(data), (int) len) <= 0) {
|
||||||
delete loc;
|
delete loc;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return reinterpret_cast<ZT_Locator *>(loc);
|
return reinterpret_cast<ZT_Locator *>(loc);
|
||||||
} catch ( ... ) {
|
} catch (...) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZT_Locator_marshal(const ZT_Locator *loc,void *buf,unsigned int bufSize)
|
int ZT_Locator_marshal(const ZT_Locator *loc, void *buf, unsigned int bufSize)
|
||||||
{
|
{
|
||||||
if ((!loc) || (bufSize < ZT_LOCATOR_MARSHAL_SIZE_MAX))
|
if ((!loc) || (bufSize < ZT_LOCATOR_MARSHAL_SIZE_MAX))
|
||||||
return -1;
|
return -1;
|
||||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->marshal(reinterpret_cast<uint8_t *>(buf),(int)bufSize);
|
return reinterpret_cast<const ZeroTier::Locator *>(loc)->marshal(reinterpret_cast<uint8_t *>(buf), (int) bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ZT_Locator_toString(
|
||||||
|
const ZT_Locator *loc,
|
||||||
|
char *buf,
|
||||||
|
int capacity)
|
||||||
|
{
|
||||||
|
if ((!loc) || (capacity < ZT_LOCATOR_STRING_SIZE_MAX))
|
||||||
|
return nullptr;
|
||||||
|
return reinterpret_cast<const ZeroTier::Locator *>(loc)->toString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
|
const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
|
||||||
{
|
{
|
||||||
if (!loc)
|
if (!loc)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return (ZT_Fingerprint *)(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->signer()));
|
return (ZT_Fingerprint *) (&(reinterpret_cast<const ZeroTier::Locator *>(loc)->signer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ZT_Locator_timestamp(const ZT_Locator *loc)
|
||||||
|
{
|
||||||
|
if (!loc)
|
||||||
|
return 0;
|
||||||
|
return reinterpret_cast<const ZeroTier::Locator *>(loc)->timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
|
unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
|
||||||
{
|
{
|
||||||
return (loc) ? (unsigned int)(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
|
return (loc) ? (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc,const unsigned int ep)
|
const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int ep)
|
||||||
{
|
{
|
||||||
if (!loc)
|
if (!loc)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (ep >= (unsigned int)(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()))
|
if (ep >= (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return reinterpret_cast<const ZT_Endpoint *>(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints()[ep]));
|
return reinterpret_cast<const ZT_Endpoint *>(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints()[ep]));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZT_Locator_verify(const ZT_Locator *loc,const ZT_Identity *signer)
|
int ZT_Locator_verify(const ZT_Locator *loc, const ZT_Identity *signer)
|
||||||
{
|
{
|
||||||
if ((!loc) || (!signer))
|
if ((!loc) || (!signer))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#define ZT_LOCATOR_MAX_ENDPOINTS 8
|
#define ZT_LOCATOR_MAX_ENDPOINTS 8
|
||||||
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + ZT_FINGERPRINT_MARSHAL_SIZE + 2 + (ZT_LOCATOR_MAX_ENDPOINTS * ZT_ENDPOINT_MARSHAL_SIZE_MAX) + 2 + 2 + ZT_SIGNATURE_BUFFER_SIZE)
|
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + ZT_FINGERPRINT_MARSHAL_SIZE + 2 + (ZT_LOCATOR_MAX_ENDPOINTS * ZT_ENDPOINT_MARSHAL_SIZE_MAX) + 2 + 2 + ZT_SIGNATURE_BUFFER_SIZE)
|
||||||
|
#define ZT_LOCATOR_STRING_SIZE_MAX 4096
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -105,14 +106,27 @@ public:
|
||||||
*/
|
*/
|
||||||
bool verify(const Identity &id) const noexcept;
|
bool verify(const Identity &id) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this locator to a string
|
||||||
|
*
|
||||||
|
* @param s String buffer
|
||||||
|
* @return Pointer to buffer
|
||||||
|
*/
|
||||||
|
char *toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a string format locator
|
||||||
|
*
|
||||||
|
* @param s Locator from toString()
|
||||||
|
* @return True if format was valid
|
||||||
|
*/
|
||||||
|
bool fromString(const char *s) noexcept;
|
||||||
|
|
||||||
explicit ZT_INLINE operator bool() const noexcept
|
explicit ZT_INLINE operator bool() const noexcept
|
||||||
{ return m_ts > 0; }
|
{ return m_ts > 0; }
|
||||||
|
|
||||||
static constexpr int marshalSizeMax() noexcept
|
static constexpr int marshalSizeMax() noexcept { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
||||||
{ return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
|
||||||
|
|
||||||
int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], bool excludeSignature = false) const noexcept;
|
int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], bool excludeSignature = false) const noexcept;
|
||||||
|
|
||||||
int unmarshal(const uint8_t *data, int len) noexcept;
|
int unmarshal(const uint8_t *data, int len) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Reference in a new issue