Go build works now

This commit is contained in:
Adam Ierymenko 2020-01-10 22:12:56 -08:00
parent a5aea2f3bb
commit f814a07ab3
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
14 changed files with 94 additions and 403 deletions

View file

@ -59,6 +59,7 @@ else(WIN32)
add_compile_options( add_compile_options(
-Wall -Wall
-Wno-deprecated -Wno-deprecated
-Wno-unused-function
-mmacosx-version-min=10.9 -mmacosx-version-min=10.9
$<$<CONFIG:Debug>:-g> $<$<CONFIG:Debug>:-g>
$<$<CONFIG:DEBUG>:-O0> $<$<CONFIG:DEBUG>:-O0>
@ -80,6 +81,7 @@ else(WIN32)
add_compile_options( add_compile_options(
-Wall -Wall
-Wno-deprecated -Wno-deprecated
-Wno-unused-function
$<$<CONFIG:Debug>:-g> $<$<CONFIG:Debug>:-g>
$<$<CONFIG:DEBUG>:-O0> $<$<CONFIG:DEBUG>:-O0>
$<$<CONFIG:RELEASE>:-O3> $<$<CONFIG:RELEASE>:-O3>

View file

@ -13,53 +13,6 @@
package cli package cli
import (
"encoding/base64"
"fmt"
"io/ioutil"
"net/url"
"os"
"strings"
"zerotier/pkg/zerotier"
)
// AddRoot CLI command // AddRoot CLI command
func AddRoot(basePath, authToken string, args []string) { func AddRoot(basePath, authToken string, args []string) {
if len(args) == 0 {
Help()
os.Exit(0)
}
locData, err := ioutil.ReadFile(args[0])
if err != nil {
locData, err2 := base64.StdEncoding.DecodeString(strings.TrimSpace(args[0]))
if err2 != nil || len(locData) == 0 {
fmt.Printf("ERROR: unable to read locator: %s\n", err.Error())
os.Exit(1)
}
}
loc, err := zerotier.NewLocatorFromBytes(locData)
if err != nil {
fmt.Printf("ERROR: invalid locator '%s' (tried as file and base64 literal): %s\n", args[0], err.Error())
os.Exit(1)
}
var name string
if len(args) > 1 {
if len(args) > 2 {
Help()
os.Exit(1)
}
name = strings.TrimSpace(args[1])
}
var result zerotier.Root
apiPost(basePath, authToken, "/root/"+url.PathEscape(name), &zerotier.Root{
Name: name,
Locator: loc,
}, &result)
fmt.Println(jsonDump(&result))
os.Exit(0)
} }

View file

@ -41,12 +41,8 @@ Commands:
status Show ZeroTier service status and config status Show ZeroTier service status and config
peers Show VL1 peers peers Show VL1 peers
roots Show configured VL1 root servers roots Show configured VL1 root servers
addroot <locator> [name] Add a VL1 root addroot <identity> Add VL1 root server
removeroot <name> Remove a VL1 root removeroot <identity|address> Remove VL1 root server
locator <command> [args] Locator management commands
new <identity> <address> [...] Create and sign locator for identity
newdnskey Create a secure DNS name and secret
getdns <dns key> <locator> Create secure DNS TXT records
identity <command> [args] Identity management commands identity <command> [args] Identity management commands
new [c25519|p384] Create new identity (including secret) new [c25519|p384] Create new identity (including secret)
getpublic <identity> Extract only public part of identity getpublic <identity> Extract only public part of identity

View file

@ -1,137 +0,0 @@
/*
* 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 cli
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"zerotier/pkg/zerotier"
)
func locatorNew(args []string) {
if len(args) < 2 {
Help()
os.Exit(1)
}
identity := readIdentity(args[0])
if !identity.HasPrivate() {
fmt.Println("FATAL: identity does not contain a secret key (required to sign locator)")
os.Exit(1)
}
var virt []*zerotier.Identity
var phys []*zerotier.InetAddress
for i := 1; i < len(args); i++ {
if strings.Contains(args[i], "/") {
a := zerotier.NewInetAddressFromString(args[i])
if a == nil {
fmt.Printf("FATAL: IP/port address '%s' is not valid\n", args[i])
os.Exit(1)
}
phys = append(phys, a)
} else {
a, err := zerotier.NewIdentityFromString(args[i])
if err != nil {
fmt.Printf("FATAL: identity (virtual address) '%s' is not valid: %s\n", args[i], err.Error())
os.Exit(1)
}
virt = append(virt, a)
}
}
loc, err := zerotier.NewLocator(identity, virt, phys)
if err != nil {
fmt.Printf("FATAL: internal error creating locator: %s\n", err.Error())
os.Exit(1)
}
fmt.Println(jsonDump(loc))
os.Exit(0)
}
func locatorNewDNSKey(args []string) {
if len(args) != 0 {
Help()
os.Exit(0)
}
sk, err := zerotier.NewLocatorDNSSigningKey()
if err != nil {
fmt.Printf("FATAL: error creating secure DNS signing key: %s", err.Error())
os.Exit(1)
}
fmt.Println(jsonDump(sk))
os.Exit(0)
}
func locatorGetDNS(args []string) {
if len(args) < 2 {
Help()
os.Exit(1)
}
keyData, err := ioutil.ReadFile(args[0])
if err != nil {
fmt.Printf("FATAL: unable to read secure DNS key file: %s\n", err.Error())
os.Exit(1)
}
var sk zerotier.LocatorDNSSigningKey
err = json.Unmarshal(keyData, &sk)
if err != nil {
fmt.Printf("FATAL: DNS key file invalid: %s", err.Error())
os.Exit(1)
}
locData, err := ioutil.ReadFile(args[1])
if err != nil {
fmt.Printf("FATAL: unable to read locator: %s\n", err.Error())
os.Exit(1)
}
var loc zerotier.Locator
err = json.Unmarshal(locData, &loc)
if err != nil {
fmt.Printf("FATAL: locator invalid: %s", err.Error())
os.Exit(1)
}
txt, err := loc.MakeTXTRecords(&sk)
if err != nil {
fmt.Printf("FATAL: error creating TXT records: %s\n", err.Error())
os.Exit(1)
}
for _, t := range txt {
fmt.Println(t)
}
os.Exit(0)
}
// Locator CLI command
func Locator(args []string) {
if len(args) > 0 {
switch args[0] {
case "new":
locatorNew(args[1:])
case "newdnskey":
locatorNewDNSKey(args[1:])
case "getdns":
locatorGetDNS(args[1:])
}
}
Help()
os.Exit(1)
}

View file

@ -13,51 +13,6 @@
package cli package cli
import (
"fmt"
"os"
"zerotier/pkg/zerotier"
)
// Roots CLI command // Roots CLI command
func Roots(basePath, authToken string, args []string, jsonOutput bool) { func Roots(basePath, authToken string, args []string, jsonOutput bool) {
var roots []zerotier.Root
apiGet(basePath, authToken, "/root", &roots)
if jsonOutput {
fmt.Println(jsonDump(roots))
} else {
fmt.Printf("%32s <address> <physical/virtual>\n", "<name>")
for _, r := range roots {
rn := r.Name
if len(rn) > 32 {
rn = rn[len(rn)-32:]
}
if r.Locator != nil {
if len(r.Locator.Physical) == 0 && len(r.Locator.Virtual) == 0 {
fmt.Printf("%32s %.10x -\n", rn, uint64(r.Locator.Identity.Address()))
} else {
fmt.Printf("%32s %.10x ", rn, uint64(r.Locator.Identity.Address()))
for i, a := range r.Locator.Physical {
if i > 0 {
fmt.Print(",")
}
fmt.Print(a.String())
}
for i, a := range r.Locator.Virtual {
if i > 0 || len(r.Locator.Physical) > 0 {
fmt.Print(",")
}
fmt.Print(a.String())
}
fmt.Printf("\n")
}
} else {
fmt.Printf("%32s - -\n", rn)
}
}
}
os.Exit(0)
} }

View file

@ -18,6 +18,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"zerotier/pkg/zerotier" "zerotier/pkg/zerotier"
) )

View file

@ -127,8 +127,6 @@ func main() {
case "removeroot": case "removeroot":
authTokenRequired(authToken) authTokenRequired(authToken)
cli.RemoveRoot(basePath, authToken, cmdArgs) cli.RemoveRoot(basePath, authToken, cmdArgs)
case "locator":
cli.Locator(cmdArgs)
case "identity": case "identity":
cli.Identity(cmdArgs) cli.Identity(cmdArgs)
case "networks", "listnetworks": case "networks", "listnetworks":

View file

@ -460,10 +460,10 @@ func createAPIServer(basePath string, node *Node) (*http.Server, *http.Server, e
} }
apiSetStandardHeaders(out) apiSetStandardHeaders(out)
var queriedName string //var queriedName string
if len(req.URL.Path) > 6 { //if len(req.URL.Path) > 6 {
queriedName = req.URL.Path[6:] // queriedName = req.URL.Path[6:]
} //}
if req.Method == http.MethodDelete { if req.Method == http.MethodDelete {
} else if req.Method == http.MethodPost || req.Method == http.MethodPut { } else if req.Method == http.MethodPost || req.Method == http.MethodPut {

View file

@ -48,13 +48,17 @@ type Identity struct {
// NewIdentity generates a new identity of the selected type // NewIdentity generates a new identity of the selected type
func NewIdentity(identityType int) (*Identity, error) { func NewIdentity(identityType int) (*Identity, error) {
cIdStr := C.ZT_GoIdentity_generate(C.int(identityType)) cid := C.ZT_Identity_new(C.enum_ZT_Identity_Type(identityType))
if uintptr(unsafe.Pointer(cIdStr)) == 0 { if uintptr(unsafe.Pointer(cid)) == 0 {
return nil, ErrInternal return nil, ErrInternal
} }
id, err := NewIdentityFromString(C.GoString(cIdStr)) defer C.ZT_Identity_delete(cid)
C.free(unsafe.Pointer(cIdStr)) var idStrBuf [4096]byte
return id, err idStr := C.ZT_Identity_toString(cid,(*C.char)(unsafe.Pointer(&idStrBuf[0])),4096,1)
if uintptr(unsafe.Pointer(idStr)) == 0 {
return nil, ErrInternal
}
return NewIdentityFromString(C.GoString(idStr))
} }
// NewIdentityFromString generates a new identity from its string representation. // NewIdentityFromString generates a new identity from its string representation.
@ -158,7 +162,12 @@ func (id *Identity) String() string {
func (id *Identity) LocallyValidate() bool { func (id *Identity) LocallyValidate() bool {
idCStr := C.CString(id.String()) idCStr := C.CString(id.String())
defer C.free(unsafe.Pointer(idCStr)) defer C.free(unsafe.Pointer(idCStr))
return C.ZT_GoIdentity_validate(idCStr) != 0 cid := C.ZT_Identity_fromString(idCStr)
if uintptr(cid) == 0 {
return false
}
defer C.ZT_Identity_delete(cid)
return C.ZT_Identity_validate(cid) != 0
} }
// Sign signs a message with this identity // Sign signs a message with this identity

View file

@ -609,59 +609,21 @@ func (n *Node) Peers() []*Peer {
p2.Role = int(p.role) p2.Role = int(p.role)
p2.Paths = make([]Path, 0, int(p.pathCount)) p2.Paths = make([]Path, 0, int(p.pathCount))
usingAllocation := false
for j := uintptr(0); j < uintptr(p.pathCount); j++ { for j := uintptr(0); j < uintptr(p.pathCount); j++ {
pt := &p.paths[j] pt := &p.paths[j]
if pt.alive != 0 { if pt.alive != 0 {
a := sockaddrStorageToUDPAddr(&pt.address) a := sockaddrStorageToUDPAddr(&pt.address)
if a != nil { if a != nil {
alloc := float32(pt.allocation)
if alloc > 0.0 {
usingAllocation = true
}
p2.Paths = append(p2.Paths, Path{ p2.Paths = append(p2.Paths, Path{
IP: a.IP, IP: a.IP,
Port: a.Port, Port: a.Port,
LastSend: int64(pt.lastSend), LastSend: int64(pt.lastSend),
LastReceive: int64(pt.lastReceive), LastReceive: int64(pt.lastReceive),
TrustedPathID: uint64(pt.trustedPathId), 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: alloc,
}) })
} }
} }
} }
if !usingAllocation { // if all allocations are zero fall back to single path mode that uses the preferred flag
for i, j := 0, uintptr(0); j < uintptr(p.pathCount); j++ {
pt := &p.paths[j]
if pt.alive != 0 {
if pt.preferred == 0 {
p2.Paths[i].Allocation = 0.0
} else {
p2.Paths[i].Allocation = 1.0
}
i++
}
}
}
sort.Slice(p2.Paths, func(a, b int) bool {
pa := &p2.Paths[a]
pb := &p2.Paths[b]
if pb.Allocation < pa.Allocation { // invert order, put highest allocation paths first
return true
}
if pa.Allocation == pb.Allocation {
return pa.LastReceive < pb.LastReceive // then sort by most recent activity
}
return false
})
p2.Clock = TimeMs() p2.Clock = TimeMs()
peers = append(peers, p2) peers = append(peers, p2)
@ -775,9 +737,6 @@ func (n *Node) handleTrace(traceMessage string) {
func (n *Node) handleUserMessage(originAddress, messageTypeID uint64, data []byte) { func (n *Node) handleUserMessage(originAddress, messageTypeID uint64, data []byte) {
} }
func (n *Node) handleRemoteTrace(originAddress uint64, dictData []byte) {
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// These are callbacks called by the core and GoGlue stuff to talk to the // These are callbacks called by the core and GoGlue stuff to talk to the
@ -866,38 +825,6 @@ func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Poin
return -1 return -1
} }
//export goDNSResolverFunc
func goDNSResolverFunc(gn unsafe.Pointer, dnsRecordTypes unsafe.Pointer, numDNSRecordTypes C.int, name unsafe.Pointer, requestID C.uintptr_t) {
go func() {
nodesByUserPtrLock.RLock()
node := nodesByUserPtr[uintptr(gn)]
nodesByUserPtrLock.RUnlock()
if node == nil {
return
}
recordTypes := C.GoBytes(dnsRecordTypes, numDNSRecordTypes)
recordName := C.GoString((*C.char)(name))
recordNameCStrCopy := C.CString(recordName)
for _, rt := range recordTypes {
switch rt {
case C.ZT_DNS_RECORD_TXT:
recs, _ := net.LookupTXT(recordName)
for _, rec := range recs {
if len(rec) > 0 {
rnCS := C.CString(rec)
C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD_TXT, unsafe.Pointer(rnCS), C.uint(len(rec)), 0)
C.free(unsafe.Pointer(rnCS))
}
}
}
}
C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD__END_OF_RESULTS, nil, 0, 0)
C.free(unsafe.Pointer(recordNameCStrCopy))
}()
}
//export goVirtualNetworkConfigFunc //export goVirtualNetworkConfigFunc
func goVirtualNetworkConfigFunc(gn, _ unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) { func goVirtualNetworkConfigFunc(gn, _ unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) {
go func() { go func() {
@ -976,9 +903,6 @@ func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
case C.ZT_EVENT_USER_MESSAGE: case C.ZT_EVENT_USER_MESSAGE:
um := (*C.ZT_UserMessage)(data) um := (*C.ZT_UserMessage)(data)
node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length))) node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
case C.ZT_EVENT_REMOTE_TRACE:
rt := (*C.ZT_RemoteTrace)(data)
node.handleRemoteTrace(uint64(rt.origin), C.GoBytes(unsafe.Pointer(rt.data), C.int(rt.len)))
} }
}() }()
} }

View file

@ -22,13 +22,4 @@ type Path struct {
LastSend int64 `json:"lastSend"` LastSend int64 `json:"lastSend"`
LastReceive int64 `json:"lastReceive"` LastReceive int64 `json:"lastReceive"`
TrustedPathID uint64 `json:"trustedPathID"` TrustedPathID uint64 `json:"trustedPathID"`
Latency float32 `json:"latency"`
PacketDelayVariance float32 `json:"packetDelayVariance"`
ThroughputDisturbCoeff float32 `json:"throughputDisturbCoeff"`
PacketErrorRatio float32 `json:"packetErrorRatio"`
PacketLossRatio float32 `json:"packetLossRatio"`
Stability float32 `json:"stability"`
Throughput uint64 `json:"throughput"`
MaxThroughput uint64 `json:"maxThroughput"`
Allocation float32 `json:"allocation"`
} }

View file

@ -656,12 +656,12 @@ public:
static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress); static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress);
}; };
InetAddress *asInetAddress(sockaddr_in *p) { return reinterpret_cast<InetAddress *>(p); } static ZT_ALWAYS_INLINE InetAddress *asInetAddress(sockaddr_in *p) { return reinterpret_cast<InetAddress *>(p); }
InetAddress *asInetAddress(sockaddr_in6 *p) { return reinterpret_cast<InetAddress *>(p); } static ZT_ALWAYS_INLINE InetAddress *asInetAddress(sockaddr_in6 *p) { return reinterpret_cast<InetAddress *>(p); }
InetAddress *asInetAddress(sockaddr *p) { return reinterpret_cast<InetAddress *>(p); } static ZT_ALWAYS_INLINE InetAddress *asInetAddress(sockaddr *p) { return reinterpret_cast<InetAddress *>(p); }
const InetAddress *asInetAddress(const sockaddr_in *p) { return reinterpret_cast<const InetAddress *>(p); } static ZT_ALWAYS_INLINE const InetAddress *asInetAddress(const sockaddr_in *p) { return reinterpret_cast<const InetAddress *>(p); }
const InetAddress *asInetAddress(const sockaddr_in6 *p) { return reinterpret_cast<const InetAddress *>(p); } static ZT_ALWAYS_INLINE const InetAddress *asInetAddress(const sockaddr_in6 *p) { return reinterpret_cast<const InetAddress *>(p); }
const InetAddress *asInetAddress(const sockaddr *p) { return reinterpret_cast<const InetAddress *>(p); } static ZT_ALWAYS_INLINE const InetAddress *asInetAddress(const sockaddr *p) { return reinterpret_cast<const InetAddress *>(p); }
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -42,21 +42,21 @@ namespace ZeroTier {
#ifdef __APPLE__ #ifdef __APPLE__
#define ZT_HAVE_NATIVE_SHA512 1 #define ZT_HAVE_NATIVE_SHA512 1
ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len) static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA512_Init(&ctx); CC_SHA512_Init(&ctx);
CC_SHA512_Update(&ctx,data,len); CC_SHA512_Update(&ctx,data,len);
CC_SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx); CC_SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len) static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx); CC_SHA384_Init(&ctx);
CC_SHA384_Update(&ctx,data,len); CC_SHA384_Update(&ctx,data,len);
CC_SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx); CC_SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx); CC_SHA384_Init(&ctx);
@ -69,21 +69,21 @@ ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,co
#ifndef ZT_HAVE_NATIVE_SHA512 #ifndef ZT_HAVE_NATIVE_SHA512
#ifdef ZT_USE_LIBCRYPTO #ifdef ZT_USE_LIBCRYPTO
#define ZT_HAVE_NATIVE_SHA512 1 #define ZT_HAVE_NATIVE_SHA512 1
ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len) static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA512_Init(&ctx); SHA512_Init(&ctx);
SHA512_Update(&ctx,data,len); SHA512_Update(&ctx,data,len);
SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx); SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len) static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA384_Init(&ctx); SHA384_Init(&ctx);
SHA384_Update(&ctx,data,len); SHA384_Update(&ctx,data,len);
SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx); SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA384_Init(&ctx); SHA384_Init(&ctx);

View file

@ -174,14 +174,7 @@ uint64_t random();
*/ */
bool scopy(char *dest,unsigned int len,const char *src); bool scopy(char *dest,unsigned int len,const char *src);
/** static ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
* Tokenize a string (alias for strtok_r or strtok_s depending on platform)
*
* @param str String to split
* @param delim Delimiters
* @param saveptr Pointer to a char * for temporary reentrant storage
*/
ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return strtok_s(str,delim,saveptr); return strtok_s(str,delim,saveptr);
@ -190,19 +183,11 @@ ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
#endif #endif
} }
ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); } #if 0
ZT_ALWAYS_INLINE int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); } static ZT_ALWAYS_INLINE int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
ZT_ALWAYS_INLINE unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); } static ZT_ALWAYS_INLINE unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
ZT_ALWAYS_INLINE long strToLong(const char *s) { return strtol(s,(char **)0,10); } static ZT_ALWAYS_INLINE long strToLong(const char *s) { return strtol(s,(char **)0,10); }
ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s) static ZT_ALWAYS_INLINE long long strTo64(const char *s)
{
#ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,10);
#else
return strtoull(s,(char **)0,10);
#endif
}
ZT_ALWAYS_INLINE long long strTo64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,10); return (long long)_strtoi64(s,(char **)0,10);
@ -210,19 +195,24 @@ ZT_ALWAYS_INLINE long long strTo64(const char *s)
return strtoll(s,(char **)0,10); return strtoll(s,(char **)0,10);
#endif #endif
} }
ZT_ALWAYS_INLINE unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); } static ZT_ALWAYS_INLINE unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
ZT_ALWAYS_INLINE int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); } static ZT_ALWAYS_INLINE int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); } static ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); } static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s) #endif
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,16); return (unsigned long long)_strtoui64(s,(char **)0,10);
#else #else
return strtoull(s,(char **)0,16); return strtoull(s,(char **)0,10);
#endif #endif
} }
ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,16); return (long long)_strtoi64(s,(char **)0,16);
@ -231,6 +221,15 @@ ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
#endif #endif
} }
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
{
#ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,16);
#else
return strtoull(s,(char **)0,16);
#endif
}
/** /**
* Calculate a non-cryptographic hash of a byte string * Calculate a non-cryptographic hash of a byte string
* *
@ -238,29 +237,29 @@ ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
* @param len Length in bytes * @param len Length in bytes
* @return Non-cryptographic hash suitable for use in a hash table * @return Non-cryptographic hash suitable for use in a hash table
*/ */
ZT_ALWAYS_INLINE unsigned long hashString(const void *restrict key,const unsigned int len) static ZT_ALWAYS_INLINE unsigned long hashString(const void *restrict key,const unsigned int len)
{ {
const uint8_t *p = reinterpret_cast<const uint8_t *>(key); const uint8_t *p = reinterpret_cast<const uint8_t *>(key);
unsigned long h = 0; unsigned long h = 0;
for (unsigned int i=0;i<len;++i) { for (unsigned int i=0;i<len;++i) {
h += p[i]; h += p[i];
h += (h << 10); h += (h << 10U);
h ^= (h >> 6); h ^= (h >> 6U);
} }
h += (h << 3); h += (h << 3U);
h ^= (h >> 11); h ^= (h >> 11U);
h += (h << 15); h += (h << 15U);
return h; return h;
} }
#ifdef __GNUC__ #ifdef __GNUC__
ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); } static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); } static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
ZT_ALWAYS_INLINE unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); } static ZT_ALWAYS_INLINE unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); } static ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
#else #else
template<typename T> template<typename T>
ZT_ALWAYS_INLINE unsigned int countBits(T v) static ZT_ALWAYS_INLINE unsigned int countBits(T v)
{ {
v = v - ((v >> 1) & (T)~(T)0/3); v = v - ((v >> 1) & (T)~(T)0/3);
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3); v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
@ -270,9 +269,9 @@ ZT_ALWAYS_INLINE unsigned int countBits(T v)
#endif #endif
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; } static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; }
ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; } static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; }
ZT_ALWAYS_INLINE uint16_t hton(uint16_t n) static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -284,8 +283,8 @@ ZT_ALWAYS_INLINE uint16_t hton(uint16_t n)
return htons(n); return htons(n);
#endif #endif
} }
ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); } static ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
ZT_ALWAYS_INLINE uint32_t hton(uint32_t n) static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -297,8 +296,8 @@ ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
return htonl(n); return htonl(n);
#endif #endif
} }
ZT_ALWAYS_INLINE int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); } static ZT_ALWAYS_INLINE int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
ZT_ALWAYS_INLINE uint64_t hton(uint64_t n) static ZT_ALWAYS_INLINE uint64_t hton(uint64_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -319,16 +318,16 @@ ZT_ALWAYS_INLINE uint64_t hton(uint64_t n)
); );
#endif #endif
} }
ZT_ALWAYS_INLINE int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); } static ZT_ALWAYS_INLINE int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
#else #else
template<typename T> template<typename T>
static ZT_ALWAYS_INLINE T hton(T n) { return n; } static ZT_ALWAYS_INLINE T hton(T n) { return n; }
#endif #endif
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; } static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; }
ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; } static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; }
ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n) static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -340,8 +339,8 @@ ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n)
return htons(n); return htons(n);
#endif #endif
} }
ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); } static ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n) static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -353,8 +352,8 @@ ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
return ntohl(n); return ntohl(n);
#endif #endif
} }
ZT_ALWAYS_INLINE int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); } static ZT_ALWAYS_INLINE int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n) static ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -375,13 +374,13 @@ ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n)
); );
#endif #endif
} }
ZT_ALWAYS_INLINE int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); } static ZT_ALWAYS_INLINE int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
#else #else
template<typename T> template<typename T>
ZT_ALWAYS_INLINE T ntoh(T n) { return n; } static ZT_ALWAYS_INLINE T ntoh(T n) { return n; }
#endif #endif
ZT_ALWAYS_INLINE uint64_t readUInt64(const void *const p) static ZT_ALWAYS_INLINE uint64_t readUInt64(const void *const p)
{ {
#ifdef ZT_NO_TYPE_PUNNING #ifdef ZT_NO_TYPE_PUNNING
const uint8_t *const b = reinterpret_cast<const uint8_t *>(p); const uint8_t *const b = reinterpret_cast<const uint8_t *>(p);
@ -399,7 +398,7 @@ ZT_ALWAYS_INLINE uint64_t readUInt64(const void *const p)
#endif #endif
} }
ZT_ALWAYS_INLINE void putUInt64(void *const p,const uint64_t i) static ZT_ALWAYS_INLINE void putUInt64(void *const p,const uint64_t i)
{ {
#ifdef ZT_NO_TYPE_PUNNING #ifdef ZT_NO_TYPE_PUNNING
uint8_t *const b = reinterpret_cast<uint8_t *>(p); uint8_t *const b = reinterpret_cast<uint8_t *>(p);