mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-19 21:46:54 +02:00
.
This commit is contained in:
parent
19899de5a6
commit
627533cf48
20 changed files with 346 additions and 630 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,8 @@
|
|||
build/
|
||||
/build
|
||||
/cmake-build-debug
|
||||
/cmake-build-release
|
||||
/version.h
|
||||
/.idea
|
||||
.DS_Store
|
||||
.Trashes
|
||||
*.swp
|
||||
|
|
7
.idea/ZeroTierOne.iml
generated
7
.idea/ZeroTierOne.iml
generated
|
@ -1,9 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<module classpath="CMake" type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
|
|
346
CMakeLists.txt
346
CMakeLists.txt
|
@ -1,208 +1,144 @@
|
|||
cmake_minimum_required (VERSION 3.8)
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(ZeroTierOne)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.15)
|
||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
else()
|
||||
cmake_policy(VERSION 3.15)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
if(WIN32)
|
||||
# If building on Windows, set minimum target to Windows 7
|
||||
set(CMAKE_SYSTEM_VERSION "7" CACHE STRING INTERNAL FORCE)
|
||||
endif(WIN32)
|
||||
include_directories(controller)
|
||||
include_directories(ext)
|
||||
include_directories(ext/json)
|
||||
include_directories(include)
|
||||
include_directories(node)
|
||||
include_directories(osdep)
|
||||
include_directories(root)
|
||||
|
||||
set(ZEROTIER_ONE_VERSION_MAJOR 2 CACHE INTERNAL "")
|
||||
set(ZEROTIER_ONE_VERSION_MINOR 0 CACHE INTERNAL "")
|
||||
set(ZEROTIER_ONE_VERSION_REVISION 0 CACHE INTERNAL "")
|
||||
set(ZEROTIER_ONE_VERSION_BUILD 0 CACHE INTERNAL "")
|
||||
|
||||
set(default_build_type "Release")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
set(default_build_type "Debug")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
|
||||
STRING "Choose the type of build." FORCE)
|
||||
# Set the possible values of build type for cmake-gui
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
option(BUILD_CENTRAL_CONTROLLER "Build ZeroTier Central Controller" OFF)
|
||||
option(ZT_TRACE "Trace Messages" OFF)
|
||||
option(ZT_DEBUG_TRACE "Debug Trace Messages" OFF)
|
||||
|
||||
if (BUILD_CENTRAL_CONTROLLER)
|
||||
find_package(PostgreSQL REQUIRED)
|
||||
set(ENABLE_SSL_SUPPORT OFF)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_EXAMPLES OFF)
|
||||
set(BUILD_TOOLS OFF)
|
||||
set(BUILD_TESTS OFF)
|
||||
set(BUILD_API_DOCS OFF)
|
||||
add_subdirectory("ext/librabbitmq")
|
||||
endif(BUILD_CENTRAL_CONTROLLER)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X Deployment Version")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_definitions(-DZT_TRACE)
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
project(zerotier
|
||||
DESCRIPTION "ZeroTier Network Hypervisor"
|
||||
LANGUAGES CXX C)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DNOMINMAX)
|
||||
else(WIN32)
|
||||
if(APPLE)
|
||||
|
||||
message("Setting macOS Compiler Flags ${CMAKE_BUILD_TYPE}")
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-deprecated
|
||||
-mmacosx-version-min=10.9
|
||||
$<$<CONFIG:Debug>:-g>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
$<$<CONFIG:RELEASE>:-Ofast>
|
||||
$<$<CONFIG:RELEASE>:-fPIE>
|
||||
$<$<CONFIG:RELEASE>:-flto>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-Ofast>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-fPIE>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-g>
|
||||
)
|
||||
add_link_options(
|
||||
-mmacosx-version-min=10.9
|
||||
$<$<CONFIG:RELEASE>:-flto>
|
||||
)
|
||||
|
||||
elseif (
|
||||
CMAKE_SYSTEM_NAME MATCHES "Linux" OR
|
||||
CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR
|
||||
CMAKE_SYSTEM_NAME MATCHES "OpenBSD" OR
|
||||
CMAKE_SYSTEM_NAME MATCHES "NetBSD"
|
||||
)
|
||||
|
||||
message("Setting Linux/BSD Compiler Flags (${CMAKE_BUILD_TYPE})")
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-deprecated
|
||||
$<$<CONFIG:Debug>:-g>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
$<$<CONFIG:RELEASE>:-O3>
|
||||
$<$<CONFIG:RELEASE>:-fPIE>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-O3>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-fPIE>
|
||||
$<$<CONFIG:RELWITHDEBINFO>:-g>
|
||||
)
|
||||
|
||||
endif(APPLE)
|
||||
endif(WIN32)
|
||||
|
||||
if (
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "i386" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "i486" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "i586" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "i686"
|
||||
)
|
||||
message("Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
add_compile_options(
|
||||
-maes
|
||||
-mmmx
|
||||
-mrdrnd
|
||||
-mpclmul
|
||||
-msse
|
||||
-msse2
|
||||
-msse3
|
||||
-msse4.1
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ZT_TRACE)
|
||||
add_definitions(-DZT_TRACE)
|
||||
endif()
|
||||
if(ZT_DEBUG_TRACE)
|
||||
add_definitions(-DZT_DEBUG_TRACE)
|
||||
endif()
|
||||
|
||||
add_subdirectory(node)
|
||||
add_subdirectory(controller)
|
||||
add_subdirectory(osdep)
|
||||
add_subdirectory(root)
|
||||
add_subdirectory(go/native)
|
||||
|
||||
#if(WIN32)
|
||||
# add_subdirectory("windows/WinUI")
|
||||
# add_subdirectory("windows/copyutil")
|
||||
# add_definitions(-DNOMINMAX)
|
||||
#endif(WIN32)
|
||||
|
||||
set(
|
||||
zt_osdep
|
||||
zt_core
|
||||
zt_controller
|
||||
zt_go_native
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/version.h.in
|
||||
${CMAKE_BINARY_DIR}/version.h
|
||||
)
|
||||
|
||||
#set(src
|
||||
# one.cpp
|
||||
# "ext/http-parser/http_parser.c"
|
||||
#)
|
||||
#set(headers
|
||||
# "ext/http-parser/http_parser.h"
|
||||
#)
|
||||
|
||||
if(WIN32)
|
||||
set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi)
|
||||
else(WIN32)
|
||||
set(libs ${libs} pthread)
|
||||
endif(WIN32)
|
||||
|
||||
#if(WIN32)
|
||||
# set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi)
|
||||
# set(src
|
||||
# ${src}
|
||||
# "windows/ZeroTierOne/ServiceBase.cpp"
|
||||
# "windows/ZeroTierOne/ServiceInstaller.cpp"
|
||||
# "windows/ZeroTierOne/ZeroTierOneService.cpp"
|
||||
# "windows/ZeroTierOne/ZeroTierOne.rc"
|
||||
# )
|
||||
# set(headers
|
||||
# ${headers}
|
||||
# "windows/ZeroTierOne/ServiceBase.h"
|
||||
# "windows/ZeroTierOne/ServiceInstaller.h"
|
||||
# "windows/ZeroTierOne/ZeroTierOneService.h"
|
||||
# )
|
||||
#else(WIN32)
|
||||
# set(libs ${libs} pthread resolv)
|
||||
#endif(WIN32)
|
||||
|
||||
#if(BUILD_CENTRAL_CONTROLLER)
|
||||
# set(libs ${libs} rabbitmq-static ${PostgreSQL_LIBRARIES})
|
||||
#endif(BUILD_CENTRAL_CONTROLLER)
|
||||
|
||||
#add_executable(${PROJECT_NAME} ${src} ${headers})
|
||||
#target_link_libraries(${PROJECT_NAME} ${libs})
|
||||
#target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT zerotier
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/go
|
||||
COMMAND go build -trimpath -ldflags -s -o ../build/zerotier cmd/zerotier/zerotier.go
|
||||
DEPENDS zt_osdep zt_core zt_go_native
|
||||
)
|
||||
add_custom_target(build_zerotier ALL DEPENDS zerotier)
|
||||
|
||||
add_executable(zerotier-selftest selftest.cpp)
|
||||
target_link_libraries(zerotier-selftest ${libs} zt_core zt_osdep)
|
||||
target_compile_features(zerotier-selftest PUBLIC cxx_std_11)
|
||||
add_executable(ZeroTierOne
|
||||
controller/CMakeLists.txt
|
||||
controller/DB.cpp
|
||||
controller/DB.hpp
|
||||
controller/DBMirrorSet.cpp
|
||||
controller/DBMirrorSet.hpp
|
||||
controller/EmbeddedNetworkController.cpp
|
||||
controller/EmbeddedNetworkController.hpp
|
||||
controller/FileDB.cpp
|
||||
controller/FileDB.hpp
|
||||
controller/LFDB.cpp
|
||||
controller/LFDB.hpp
|
||||
controller/PostgreSQL.cpp
|
||||
controller/PostgreSQL.hpp
|
||||
controller/RabbitMQ.cpp
|
||||
controller/RabbitMQ.hpp
|
||||
ext/json/json.hpp
|
||||
include/ZeroTierCore.h
|
||||
include/ZeroTierDebug.h
|
||||
node/Address.hpp
|
||||
node/AES-aesni.c
|
||||
node/AES.cpp
|
||||
node/AES.hpp
|
||||
node/AtomicCounter.hpp
|
||||
node/Buffer.hpp
|
||||
node/C25519.cpp
|
||||
node/C25519.hpp
|
||||
node/Capability.hpp
|
||||
node/CertificateOfMembership.hpp
|
||||
node/CertificateOfOwnership.hpp
|
||||
node/CMakeLists.txt
|
||||
node/Constants.hpp
|
||||
node/Credential.cpp
|
||||
node/Credential.hpp
|
||||
node/Dictionary.hpp
|
||||
node/ECC384.cpp
|
||||
node/ECC384.hpp
|
||||
node/Endpoint.hpp
|
||||
node/Hashtable.hpp
|
||||
node/Identity.cpp
|
||||
node/Identity.hpp
|
||||
node/IncomingPacket.cpp
|
||||
node/IncomingPacket.hpp
|
||||
node/InetAddress.cpp
|
||||
node/InetAddress.hpp
|
||||
node/Locator.hpp
|
||||
node/MAC.hpp
|
||||
node/Membership.cpp
|
||||
node/Membership.hpp
|
||||
node/Meter.hpp
|
||||
node/MulticastGroup.hpp
|
||||
node/Mutex.hpp
|
||||
node/Network.cpp
|
||||
node/Network.hpp
|
||||
node/NetworkConfig.cpp
|
||||
node/NetworkConfig.hpp
|
||||
node/NetworkController.hpp
|
||||
node/Node.cpp
|
||||
node/Node.hpp
|
||||
node/OS.hpp
|
||||
node/Packet.cpp
|
||||
node/Packet.hpp
|
||||
node/Path.cpp
|
||||
node/Path.hpp
|
||||
node/Peer.cpp
|
||||
node/Peer.hpp
|
||||
node/Poly1305.cpp
|
||||
node/Poly1305.hpp
|
||||
node/README.md
|
||||
node/Revocation.hpp
|
||||
node/RingBuffer.hpp
|
||||
node/RuntimeEnvironment.hpp
|
||||
node/Salsa20.cpp
|
||||
node/Salsa20.hpp
|
||||
node/ScopedPtr.hpp
|
||||
node/SelfAwareness.cpp
|
||||
node/SelfAwareness.hpp
|
||||
node/SHA512.cpp
|
||||
node/SHA512.hpp
|
||||
node/SharedPtr.hpp
|
||||
node/Str.hpp
|
||||
node/Switch.cpp
|
||||
node/Switch.hpp
|
||||
node/Tag.hpp
|
||||
node/Topology.hpp
|
||||
node/Trace.cpp
|
||||
node/Trace.hpp
|
||||
node/Utils.cpp
|
||||
node/Utils.hpp
|
||||
osdep/Arp.cpp
|
||||
osdep/Arp.hpp
|
||||
osdep/BlockingQueue.hpp
|
||||
osdep/BSDEthernetTap.cpp
|
||||
osdep/BSDEthernetTap.hpp
|
||||
osdep/CMakeLists.txt
|
||||
osdep/EthernetTap.cpp
|
||||
osdep/EthernetTap.hpp
|
||||
osdep/freebsd_getifmaddrs.c
|
||||
osdep/freebsd_getifmaddrs.h
|
||||
osdep/LinuxEthernetTap.cpp
|
||||
osdep/LinuxEthernetTap.hpp
|
||||
osdep/LinuxNetLink.cpp
|
||||
osdep/LinuxNetLink.hpp
|
||||
osdep/MacEthernetTap.cpp
|
||||
osdep/MacEthernetTap.hpp
|
||||
osdep/MacEthernetTapAgent.c
|
||||
osdep/MacEthernetTapAgent.h
|
||||
osdep/MacKextEthernetTap.cpp
|
||||
osdep/MacKextEthernetTap.hpp
|
||||
osdep/ManagedRoute.cpp
|
||||
osdep/ManagedRoute.hpp
|
||||
osdep/NeighborDiscovery.cpp
|
||||
osdep/NeighborDiscovery.hpp
|
||||
osdep/NetBSDEthernetTap.cpp
|
||||
osdep/NetBSDEthernetTap.hpp
|
||||
osdep/OSUtils.cpp
|
||||
osdep/OSUtils.hpp
|
||||
osdep/README.md
|
||||
osdep/Thread.hpp
|
||||
osdep/WindowsEthernetTap.cpp
|
||||
osdep/WindowsEthernetTap.hpp
|
||||
root/CMakeLists.txt
|
||||
root/geoip-html.h
|
||||
root/root.cpp
|
||||
AUTHORS.md
|
||||
CMakeLists.txt
|
||||
LICENSE.txt
|
||||
OFFICIAL-RELEASE-STEPS.md
|
||||
README.md
|
||||
RELEASE-NOTES.md
|
||||
selftest.cpp)
|
||||
|
|
|
@ -17,7 +17,6 @@ set(core_headers
|
|||
Credential.hpp
|
||||
Dictionary.hpp
|
||||
ECC384.hpp
|
||||
EphemeralKey.hpp
|
||||
Hashtable.hpp
|
||||
Identity.hpp
|
||||
InetAddress.hpp
|
||||
|
|
|
@ -31,11 +31,6 @@
|
|||
*/
|
||||
#define ZT_ADDRESS_LENGTH 5
|
||||
|
||||
/**
|
||||
* Length of a hexadecimal ZeroTier address
|
||||
*/
|
||||
#define ZT_ADDRESS_LENGTH_HEX 10
|
||||
|
||||
/**
|
||||
* Addresses beginning with this byte are reserved for the joy of in-band signaling
|
||||
*/
|
||||
|
@ -131,30 +126,6 @@
|
|||
*/
|
||||
#define ZT_MULTICAST_ANNOUNCE_PERIOD 60000
|
||||
|
||||
/**
|
||||
* Period for multicast GATHER on multicast groups
|
||||
*/
|
||||
#define ZT_MULTICAST_GATHER_PERIOD ZT_MULTICAST_ANNOUNCE_PERIOD
|
||||
|
||||
/**
|
||||
* Period for multicast GATHER if there are no known recipients
|
||||
*/
|
||||
#define ZT_MULTICAST_GATHER_PERIOD_WHEN_NO_RECIPIENTS 2500
|
||||
|
||||
/**
|
||||
* Timeout for outgoing multicasts
|
||||
*
|
||||
* This is how long we wait for explicit or implicit gather results.
|
||||
*/
|
||||
#define ZT_MULTICAST_TRANSMIT_TIMEOUT 5000
|
||||
|
||||
/**
|
||||
* How frequently to check for changes to the system's network interfaces. When
|
||||
* the service decides to use this constant it's because we want to react more
|
||||
* quickly to new interfaces that pop up or go down.
|
||||
*/
|
||||
#define ZT_MULTIPATH_BINDER_REFRESH_PERIOD 5000
|
||||
|
||||
/**
|
||||
* Packets are only used for QoS/ACK statistical sampling if their packet ID is divisible by
|
||||
* this integer. This is to provide a mechanism for both peers to agree on which packets need
|
||||
|
@ -319,11 +290,6 @@
|
|||
*/
|
||||
#define ZT_QOS_DEFAULT_BUCKET 0
|
||||
|
||||
/**
|
||||
* Do not accept HELLOs over a given path more often than this
|
||||
*/
|
||||
#define ZT_PATH_HELLO_RATE_LIMIT 1000
|
||||
|
||||
/**
|
||||
* Delay between full-fledge pings of directly connected peers
|
||||
*
|
||||
|
@ -348,21 +314,6 @@
|
|||
#define ZT_PEER_ACTIVITY_TIMEOUT 30000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Rescan for best/fastest root every N milliseconds
|
||||
*/
|
||||
#define ZT_FIND_BEST_ROOT_PERIOD 2000
|
||||
|
||||
/**
|
||||
* General rate limit timeout for multiple packet types (HELLO, etc.)
|
||||
*/
|
||||
#define ZT_PEER_GENERAL_INBOUND_RATE_LIMIT 500
|
||||
|
||||
/**
|
||||
* General limit for max RTT for requests over the network
|
||||
*/
|
||||
#define ZT_GENERAL_RTT_LIMIT 5000
|
||||
|
||||
/**
|
||||
* Delay between requests for updated network autoconf information
|
||||
*
|
||||
|
@ -477,7 +428,7 @@
|
|||
*/
|
||||
#define ZT_THREAD_MIN_STACK_SIZE 1048576
|
||||
|
||||
// Internal cryptographic algorithm IDs
|
||||
// Internal cryptographic algorithm IDs (these match relevant identity types)
|
||||
#define ZT_CRYPTO_ALG_C25519 0
|
||||
#define ZT_CRYPTO_ALG_P384 1
|
||||
|
||||
|
@ -491,4 +442,9 @@
|
|||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN 202
|
||||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING 203
|
||||
|
||||
/* Ethernet frame types that might be relevant to us */
|
||||
#define ZT_ETHERTYPE_IPV4 0x0800
|
||||
#define ZT_ETHERTYPE_ARP 0x0806
|
||||
#define ZT_ETHERTYPE_IPV6 0x86dd
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,24 +44,24 @@ public:
|
|||
ETHERNET = 5 // 48-bit LAN-local Ethernet address
|
||||
};
|
||||
|
||||
inline Endpoint() { memset(reinterpret_cast<void *>(this),0,sizeof(Endpoint)); }
|
||||
ZT_ALWAYS_INLINE Endpoint() { memset(reinterpret_cast<void *>(this),0,sizeof(Endpoint)); }
|
||||
|
||||
inline Endpoint(const InetAddress &sa) : _t(INETADDR) { _v.sa = sa; }
|
||||
inline Endpoint(const Address &zt,const uint8_t identityHash[ZT_IDENTITY_HASH_SIZE]) : _t(ZEROTIER) { _v.zt.a = zt.toInt(); memcpy(_v.zt.idh,identityHash,ZT_IDENTITY_HASH_SIZE); }
|
||||
inline Endpoint(const char *name,const int port) : _t(DNSNAME) { Utils::scopy(_v.dns.name,sizeof(_v.dns.name),name); _v.dns.port = port; }
|
||||
inline Endpoint(const char *url) : _t(URL) { Utils::scopy(_v.url,sizeof(_v.url),url); }
|
||||
ZT_ALWAYS_INLINE Endpoint(const InetAddress &sa) : _t(INETADDR) { _v.sa = sa; }
|
||||
ZT_ALWAYS_INLINE Endpoint(const Address &zt,const uint8_t identityHash[ZT_IDENTITY_HASH_SIZE]) : _t(ZEROTIER) { _v.zt.a = zt.toInt(); memcpy(_v.zt.idh,identityHash,ZT_IDENTITY_HASH_SIZE); }
|
||||
ZT_ALWAYS_INLINE Endpoint(const char *name,const int port) : _t(DNSNAME) { Utils::scopy(_v.dns.name,sizeof(_v.dns.name),name); _v.dns.port = port; }
|
||||
ZT_ALWAYS_INLINE Endpoint(const char *url) : _t(URL) { Utils::scopy(_v.url,sizeof(_v.url),url); }
|
||||
|
||||
inline const InetAddress *sockaddr() const { return (_t == INETADDR) ? reinterpret_cast<const InetAddress *>(&_v.sa) : nullptr; }
|
||||
inline const char *dnsName() const { return (_t == DNSNAME) ? _v.dns.name : nullptr; }
|
||||
inline const int dnsPort() const { return (_t == DNSNAME) ? _v.dns.port : -1; }
|
||||
inline Address ztAddress() const { return (_t == ZEROTIER) ? Address(_v.zt.a) : Address(); }
|
||||
inline const uint8_t *ztIdentityHash() const { return (_t == ZEROTIER) ? _v.zt.idh : nullptr; }
|
||||
inline const char *url() const { return (_t == URL) ? _v.url : nullptr; }
|
||||
inline MAC ethernet() const { return (_t == ETHERNET) ? MAC(_v.eth) : MAC(); }
|
||||
ZT_ALWAYS_INLINE const InetAddress *sockaddr() const { return (_t == INETADDR) ? reinterpret_cast<const InetAddress *>(&_v.sa) : nullptr; }
|
||||
ZT_ALWAYS_INLINE const char *dnsName() const { return (_t == DNSNAME) ? _v.dns.name : nullptr; }
|
||||
ZT_ALWAYS_INLINE const int dnsPort() const { return (_t == DNSNAME) ? _v.dns.port : -1; }
|
||||
ZT_ALWAYS_INLINE Address ztAddress() const { return (_t == ZEROTIER) ? Address(_v.zt.a) : Address(); }
|
||||
ZT_ALWAYS_INLINE const uint8_t *ztIdentityHash() const { return (_t == ZEROTIER) ? _v.zt.idh : nullptr; }
|
||||
ZT_ALWAYS_INLINE const char *url() const { return (_t == URL) ? _v.url : nullptr; }
|
||||
ZT_ALWAYS_INLINE MAC ethernet() const { return (_t == ETHERNET) ? MAC(_v.eth) : MAC(); }
|
||||
|
||||
inline Type type() const { return _t; }
|
||||
ZT_ALWAYS_INLINE Type type() const { return _t; }
|
||||
|
||||
static inline int marshalSizeMax() { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
|
||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
|
||||
inline int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const
|
||||
{
|
||||
int p;
|
||||
|
|
|
@ -1,118 +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.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#ifndef ZT_EPHEMERALKEY_HPP
|
||||
#define ZT_EPHEMERALKEY_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "ECC384.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
#define ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE (ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE)
|
||||
#define ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE (ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE)
|
||||
|
||||
/**
|
||||
* An ephemeral key exchanged to implement forward secrecy
|
||||
*
|
||||
* This key includes both C25519 and ECC384 keys and key agreement executes
|
||||
* ECDH for both and hashes the results together. This should be able to be
|
||||
* FIPS compliant (if the C25519 portion is just considered a nonce) while
|
||||
* simultaneously being more secure than either curve alone.
|
||||
*
|
||||
* Serialization includes only the public portion since ephemeral private
|
||||
* keys are never shared or stored anywhere.
|
||||
*/
|
||||
class EphemeralKey
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
NONE = 0,
|
||||
C25519ECC384 = 1
|
||||
};
|
||||
|
||||
inline EphemeralKey() : _priv(nullptr),_type(NONE) {}
|
||||
|
||||
inline ~EphemeralKey()
|
||||
{
|
||||
if (_priv) {
|
||||
Utils::burn(_priv,ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE);
|
||||
delete [] _priv;
|
||||
}
|
||||
}
|
||||
|
||||
inline Type type() const { return (Type)_type; }
|
||||
inline bool hasPrivate() const { return (_priv != nullptr); }
|
||||
|
||||
inline void generate()
|
||||
{
|
||||
if (!_priv)
|
||||
_priv = new uint8_t[ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE];
|
||||
C25519::generate(_pub,_priv);
|
||||
ECC384GenerateKey(_pub + ZT_C25519_PUBLIC_KEY_LEN,_priv + ZT_C25519_PRIVATE_KEY_LEN);
|
||||
_type = C25519ECC384;
|
||||
}
|
||||
|
||||
inline bool agree(const EphemeralKey &theirs,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const
|
||||
{
|
||||
if ((_priv)&&(_type == 1)) {
|
||||
uint8_t rawkey[128],h[48];
|
||||
C25519::agree(_priv,theirs._pub,rawkey);
|
||||
ECC384ECDH(theirs._pub + ZT_C25519_PUBLIC_KEY_LEN,_priv + ZT_C25519_PRIVATE_KEY_LEN,rawkey + ZT_C25519_SHARED_KEY_LEN);
|
||||
SHA384(h,rawkey,ZT_C25519_SHARED_KEY_LEN + ZT_ECC384_SHARED_SECRET_SIZE);
|
||||
memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
{
|
||||
b.append(_type);
|
||||
if (_type == C25519ECC384)
|
||||
b.append(_pub,ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE);
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
delete [] _priv;
|
||||
_priv = nullptr;
|
||||
switch(b[p++]) {
|
||||
case C25519ECC384:
|
||||
memcpy(_pub,b.field(p,ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE),ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE);
|
||||
p += ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE;
|
||||
break;
|
||||
default:
|
||||
_type = NONE;
|
||||
break;
|
||||
}
|
||||
return (p - startAt);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t *_priv;
|
||||
uint8_t _pub[ZT_EPHEMERAL_KEY_TYPE_1_PUBLIC_SIZE];
|
||||
uint8_t _type;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
|
@ -33,10 +33,10 @@ class Hashtable
|
|||
private:
|
||||
struct _Bucket
|
||||
{
|
||||
inline _Bucket(const K &k,const V &v) : k(k),v(v) {}
|
||||
inline _Bucket(const K &k) : k(k),v() {}
|
||||
inline _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
|
||||
inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
|
||||
ZT_ALWAYS_INLINE _Bucket(const K &k,const V &v) : k(k),v(v) {}
|
||||
ZT_ALWAYS_INLINE _Bucket(const K &k) : k(k),v() {}
|
||||
ZT_ALWAYS_INLINE _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
|
||||
ZT_ALWAYS_INLINE _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
|
||||
_Bucket *next; // must be set manually for each _Bucket
|
||||
const K k;
|
||||
V v;
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
/**
|
||||
* @param ht Hash table to iterate over
|
||||
*/
|
||||
inline Iterator(Hashtable &ht) :
|
||||
ZT_ALWAYS_INLINE Iterator(Hashtable &ht) :
|
||||
_idx(0),
|
||||
_ht(&ht),
|
||||
_b(ht._t[0])
|
||||
|
@ -68,7 +68,7 @@ public:
|
|||
* @param vptr Pointer to set to point to next value
|
||||
* @return True if kptr and vptr are set, false if no more entries
|
||||
*/
|
||||
inline bool next(K *&kptr,V *&vptr)
|
||||
ZT_ALWAYS_INLINE bool next(K *&kptr,V *&vptr)
|
||||
{
|
||||
for(;;) {
|
||||
if (_b) {
|
||||
|
@ -358,23 +358,23 @@ public:
|
|||
/**
|
||||
* @return Number of entries
|
||||
*/
|
||||
inline unsigned long size() const { return _s; }
|
||||
ZT_ALWAYS_INLINE unsigned long size() const { return _s; }
|
||||
|
||||
/**
|
||||
* @return True if table is empty
|
||||
*/
|
||||
inline bool empty() const { return (_s == 0); }
|
||||
ZT_ALWAYS_INLINE bool empty() const { return (_s == 0); }
|
||||
|
||||
private:
|
||||
template<typename O>
|
||||
static inline unsigned long _hc(const O &obj) { return (unsigned long)obj.hashCode(); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const O &obj) { return (unsigned long)obj.hashCode(); }
|
||||
|
||||
static inline unsigned long _hc(const uint64_t i) { return (unsigned long)(i ^ (i >> 32)); }
|
||||
static inline unsigned long _hc(const uint32_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
|
||||
static inline unsigned long _hc(const uint16_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
|
||||
static inline unsigned long _hc(const int i) { return ((unsigned long)i * (unsigned long)0x9e3379b1); }
|
||||
static inline unsigned long _hc(void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
|
||||
static inline unsigned long _hc(const void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const uint64_t i) { return (unsigned long)(i ^ (i >> 32)); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const uint32_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const uint16_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const int i) { return ((unsigned long)i * (unsigned long)0x9e3379b1); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
|
||||
static ZT_ALWAYS_INLINE unsigned long _hc(const void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
|
||||
|
||||
inline void _grow()
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ class Network;
|
|||
class IncomingPacket : public Packet
|
||||
{
|
||||
public:
|
||||
inline IncomingPacket() : Packet(),_receiveTime(0),_path() {}
|
||||
ZT_ALWAYS_INLINE IncomingPacket() : Packet(),_receiveTime(0),_path() {}
|
||||
|
||||
/**
|
||||
* Create a new packet-in-decode
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
* @param now Current time
|
||||
* @throws std::out_of_range Range error processing packet
|
||||
*/
|
||||
inline IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
|
||||
ZT_ALWAYS_INLINE IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
|
||||
Packet(data,len),
|
||||
_receiveTime(now),
|
||||
_path(path)
|
||||
|
@ -73,7 +73,7 @@ public:
|
|||
* @param now Current time
|
||||
* @throws std::out_of_range Range error processing packet
|
||||
*/
|
||||
inline void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now)
|
||||
ZT_ALWAYS_INLINE void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now)
|
||||
{
|
||||
copyFrom(data,len);
|
||||
_receiveTime = now;
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
/**
|
||||
* @return Time of packet receipt / start of decode
|
||||
*/
|
||||
inline uint64_t receiveTime() const { return _receiveTime; }
|
||||
ZT_ALWAYS_INLINE uint64_t receiveTime() const { return _receiveTime; }
|
||||
|
||||
private:
|
||||
uint64_t _receiveTime;
|
||||
|
|
|
@ -75,59 +75,55 @@ struct InetAddress : public sockaddr_storage
|
|||
IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc.
|
||||
};
|
||||
|
||||
// Can be used with the unordered maps and sets in c++11. We don't use C++11 in the core
|
||||
// but this is safe to put here.
|
||||
struct Hasher
|
||||
{
|
||||
inline std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); }
|
||||
};
|
||||
// Hasher for unordered sets and maps in C++11
|
||||
struct Hasher { ZT_ALWAYS_INLINE std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); } };
|
||||
|
||||
inline InetAddress() { memset(this,0,sizeof(InetAddress)); }
|
||||
inline InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
|
||||
inline InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
|
||||
inline InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
|
||||
inline InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
|
||||
inline InetAddress(const struct sockaddr &sa) { *this = sa; }
|
||||
inline InetAddress(const struct sockaddr *sa) { *this = sa; }
|
||||
inline InetAddress(const struct sockaddr_in &sa) { *this = sa; }
|
||||
inline InetAddress(const struct sockaddr_in *sa) { *this = sa; }
|
||||
inline InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
|
||||
inline InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
|
||||
inline InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
|
||||
inline InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
|
||||
inline InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
|
||||
ZT_ALWAYS_INLINE InetAddress() { memset(this,0,sizeof(InetAddress)); }
|
||||
ZT_ALWAYS_INLINE InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
|
||||
ZT_ALWAYS_INLINE InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr &sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr *sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in &sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in *sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
|
||||
ZT_ALWAYS_INLINE InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
|
||||
ZT_ALWAYS_INLINE InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
|
||||
ZT_ALWAYS_INLINE InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
|
||||
|
||||
inline void clear() { memset(this,0,sizeof(InetAddress)); }
|
||||
ZT_ALWAYS_INLINE void clear() { memset(this,0,sizeof(InetAddress)); }
|
||||
|
||||
inline InetAddress &operator=(const InetAddress &a)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const InetAddress &a)
|
||||
{
|
||||
if (&a != this)
|
||||
memcpy(this,&a,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const InetAddress *a)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const InetAddress *a)
|
||||
{
|
||||
if (a != this)
|
||||
memcpy(this,a,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_storage &ss)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_storage &ss)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(&ss) != this)
|
||||
memcpy(this,&ss,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_storage *ss)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_storage *ss)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(ss) != this)
|
||||
memcpy(this,ss,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in &sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in &sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -136,7 +132,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in *sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in *sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -145,7 +141,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in6 &sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in6 &sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -154,7 +150,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in6 *sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in6 *sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -163,7 +159,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr &sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr &sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -179,7 +175,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr *sa)
|
||||
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr *sa)
|
||||
{
|
||||
if (reinterpret_cast<const InetAddress *>(sa) != this) {
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
|
@ -214,7 +210,7 @@ struct InetAddress : public sockaddr_storage
|
|||
*
|
||||
* @param port Port, 0 to 65535
|
||||
*/
|
||||
inline void setPort(unsigned int port)
|
||||
ZT_ALWAYS_INLINE void setPort(unsigned int port)
|
||||
{
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -229,7 +225,7 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return True if this network/netmask route describes a default route (e.g. 0.0.0.0/0)
|
||||
*/
|
||||
inline bool isDefaultRoute() const
|
||||
ZT_ALWAYS_INLINE bool isDefaultRoute() const
|
||||
{
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -264,7 +260,7 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return Port or 0 if no port component defined
|
||||
*/
|
||||
inline unsigned int port() const
|
||||
ZT_ALWAYS_INLINE unsigned int port() const
|
||||
{
|
||||
switch(ss_family) {
|
||||
case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port));
|
||||
|
@ -282,12 +278,12 @@ struct InetAddress : public sockaddr_storage
|
|||
*
|
||||
* @return Netmask bits
|
||||
*/
|
||||
inline unsigned int netmaskBits() const { return port(); }
|
||||
ZT_ALWAYS_INLINE unsigned int netmaskBits() const { return port(); }
|
||||
|
||||
/**
|
||||
* @return True if netmask bits is valid for the address type
|
||||
*/
|
||||
inline bool netmaskBitsValid() const
|
||||
ZT_ALWAYS_INLINE bool netmaskBitsValid() const
|
||||
{
|
||||
const unsigned int n = port();
|
||||
switch(ss_family) {
|
||||
|
@ -305,7 +301,7 @@ struct InetAddress : public sockaddr_storage
|
|||
*
|
||||
* @return Gateway metric
|
||||
*/
|
||||
inline unsigned int metric() const { return port(); }
|
||||
ZT_ALWAYS_INLINE unsigned int metric() const { return port(); }
|
||||
|
||||
/**
|
||||
* Construct a full netmask as an InetAddress
|
||||
|
@ -350,17 +346,17 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return True if this is an IPv4 address
|
||||
*/
|
||||
inline bool isV4() const { return (ss_family == AF_INET); }
|
||||
ZT_ALWAYS_INLINE bool isV4() const { return (ss_family == AF_INET); }
|
||||
|
||||
/**
|
||||
* @return True if this is an IPv6 address
|
||||
*/
|
||||
inline bool isV6() const { return (ss_family == AF_INET6); }
|
||||
ZT_ALWAYS_INLINE bool isV6() const { return (ss_family == AF_INET6); }
|
||||
|
||||
/**
|
||||
* @return pointer to raw address bytes or NULL if not available
|
||||
*/
|
||||
inline const void *rawIpData() const
|
||||
ZT_ALWAYS_INLINE const void *rawIpData() const
|
||||
{
|
||||
switch(ss_family) {
|
||||
case AF_INET: return (const void *)&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
|
@ -372,7 +368,7 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return InetAddress containing only the IP portion of this address and a zero port, or NULL if not IPv4 or IPv6
|
||||
*/
|
||||
inline InetAddress ipOnly() const
|
||||
ZT_ALWAYS_INLINE InetAddress ipOnly() const
|
||||
{
|
||||
InetAddress r;
|
||||
switch(ss_family) {
|
||||
|
@ -394,7 +390,7 @@ struct InetAddress : public sockaddr_storage
|
|||
* @param a InetAddress to compare again
|
||||
* @return True if only IP portions are equal (false for non-IP or null addresses)
|
||||
*/
|
||||
inline bool ipsEqual(const InetAddress &a) const
|
||||
ZT_ALWAYS_INLINE bool ipsEqual(const InetAddress &a) const
|
||||
{
|
||||
if (ss_family == a.ss_family) {
|
||||
if (ss_family == AF_INET)
|
||||
|
@ -414,7 +410,7 @@ struct InetAddress : public sockaddr_storage
|
|||
* @param a InetAddress to compare again
|
||||
* @return True if only IP portions are equal (false for non-IP or null addresses)
|
||||
*/
|
||||
inline bool ipsEqual2(const InetAddress &a) const
|
||||
ZT_ALWAYS_INLINE bool ipsEqual2(const InetAddress &a) const
|
||||
{
|
||||
if (ss_family == a.ss_family) {
|
||||
if (ss_family == AF_INET)
|
||||
|
@ -426,7 +422,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return false;
|
||||
}
|
||||
|
||||
inline unsigned long hashCode() const
|
||||
ZT_ALWAYS_INLINE unsigned long hashCode() const
|
||||
{
|
||||
if (ss_family == AF_INET) {
|
||||
return ((unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr + (unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_port);
|
||||
|
@ -448,7 +444,7 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* Set to null/zero
|
||||
*/
|
||||
inline void zero() { memset(this,0,sizeof(InetAddress)); }
|
||||
ZT_ALWAYS_INLINE void zero() { memset(this,0,sizeof(InetAddress)); }
|
||||
|
||||
/**
|
||||
* Check whether this is a network/route rather than an IP assignment
|
||||
|
@ -463,7 +459,7 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return 14-bit (0-16383) hash of this IP's first 24 or 48 bits (for V4 or V6) for rate limiting code, or 0 if non-IP
|
||||
*/
|
||||
inline unsigned long rateGateHash() const
|
||||
ZT_ALWAYS_INLINE unsigned long rateGateHash() const
|
||||
{
|
||||
unsigned long h = 0;
|
||||
switch(ss_family) {
|
||||
|
@ -487,10 +483,10 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return True if address family is non-zero
|
||||
*/
|
||||
inline operator bool() const { return (ss_family != 0); }
|
||||
ZT_ALWAYS_INLINE operator bool() const { return (ss_family != 0); }
|
||||
|
||||
// Marshal interface ///////////////////////////////////////////////////////
|
||||
static inline int marshalSizeMax() { return 19; }
|
||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return 19; }
|
||||
inline int marshal(uint8_t restrict data[19]) const
|
||||
{
|
||||
switch(ss_family) {
|
||||
|
@ -608,10 +604,10 @@ struct InetAddress : public sockaddr_storage
|
|||
|
||||
bool operator==(const InetAddress &a) const;
|
||||
bool operator<(const InetAddress &a) const;
|
||||
inline bool operator!=(const InetAddress &a) const { return !(*this == a); }
|
||||
inline bool operator>(const InetAddress &a) const { return (a < *this); }
|
||||
inline bool operator<=(const InetAddress &a) const { return !(a < *this); }
|
||||
inline bool operator>=(const InetAddress &a) const { return !(*this < a); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const InetAddress &a) const { return !(*this == a); }
|
||||
ZT_ALWAYS_INLINE bool operator>(const InetAddress &a) const { return (a < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator<=(const InetAddress &a) const { return !(a < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator>=(const InetAddress &a) const { return !(*this < a); }
|
||||
|
||||
/**
|
||||
* @param mac MAC address seed
|
||||
|
|
|
@ -35,12 +35,12 @@ namespace ZeroTier {
|
|||
class Locator
|
||||
{
|
||||
public:
|
||||
inline Locator() : _ts(0),_endpointCount(0),_signatureLength(0) {}
|
||||
ZT_ALWAYS_INLINE Locator() : _ts(0),_endpointCount(0),_signatureLength(0) {}
|
||||
|
||||
/**
|
||||
* @return Timestamp (a.k.a. revision number) set by Location signer
|
||||
*/
|
||||
inline int64_t timestamp() const { return _ts; }
|
||||
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
|
||||
|
||||
/**
|
||||
* Create and sign a Locator
|
||||
|
@ -85,10 +85,10 @@ public:
|
|||
return id.verify(signData,signLen,_signature,_signatureLength);
|
||||
}
|
||||
|
||||
inline operator bool() const { return (_ts != 0); }
|
||||
ZT_ALWAYS_INLINE operator bool() const { return (_ts != 0); }
|
||||
|
||||
// Marshal interface ///////////////////////////////////////////////////////
|
||||
static inline int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
||||
inline int marshal(uint8_t restrict data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature = false) const
|
||||
{
|
||||
if ((_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
|
||||
|
|
|
@ -187,7 +187,7 @@ public:
|
|||
|
||||
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)_m; }
|
||||
|
||||
ZT_ALWAYS_INLINE char *toString(char buf[18]) const
|
||||
inline char *toString(char buf[18]) const
|
||||
{
|
||||
buf[0] = Utils::HEXCHARS[(_m >> 44) & 0xf];
|
||||
buf[1] = Utils::HEXCHARS[(_m >> 40) & 0xf];
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace ZeroTier {
|
|||
class Meter
|
||||
{
|
||||
public:
|
||||
inline Meter()
|
||||
ZT_ALWAYS_INLINE Meter()
|
||||
{
|
||||
for(int i=0;i<ZT_METER_HISTORY_LENGTH;++i)
|
||||
_history[i] = 0.0;
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename I>
|
||||
inline void log(const int64_t now,I count)
|
||||
ZT_ALWAYS_INLINE void log(const int64_t now,I count)
|
||||
{
|
||||
const int64_t since = now - _ts;
|
||||
if (since >= ZT_METER_HISTORY_TICK_DURATION) {
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline double perSecond(const int64_t now) const
|
||||
ZT_ALWAYS_INLINE double perSecond(const int64_t now) const
|
||||
{
|
||||
double r = 0.0,n = 0.0;
|
||||
const int64_t since = (now - _ts);
|
||||
|
|
|
@ -41,8 +41,8 @@ namespace ZeroTier {
|
|||
class MulticastGroup
|
||||
{
|
||||
public:
|
||||
inline MulticastGroup() : _mac(),_adi(0) {}
|
||||
inline MulticastGroup(const MAC &m,uint32_t a) : _mac(m),_adi(a) {}
|
||||
ZT_ALWAYS_INLINE MulticastGroup() : _mac(),_adi(0) {}
|
||||
ZT_ALWAYS_INLINE MulticastGroup(const MAC &m,uint32_t a) : _mac(m),_adi(a) {}
|
||||
|
||||
/**
|
||||
* Derive the multicast group used for address resolution (ARP/NDP) for an IP
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
* @param ip IP address (port field is ignored)
|
||||
* @return Multicast group for ARP/NDP
|
||||
*/
|
||||
static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
|
||||
static ZT_ALWAYS_INLINE MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
|
||||
{
|
||||
if (ip.isV4()) {
|
||||
// IPv4 wants broadcast MACs, so we shove the V4 address itself into
|
||||
|
@ -72,37 +72,16 @@ public:
|
|||
/**
|
||||
* @return Ethernet MAC portion of multicast group
|
||||
*/
|
||||
inline const MAC &mac() const { return _mac; }
|
||||
ZT_ALWAYS_INLINE const MAC &mac() const { return _mac; }
|
||||
|
||||
/**
|
||||
* @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4 address
|
||||
*/
|
||||
inline uint32_t adi() const { return _adi; }
|
||||
ZT_ALWAYS_INLINE uint32_t adi() const { return _adi; }
|
||||
|
||||
/**
|
||||
* @return 32-bit non-cryptographic hash ID of this multicast group
|
||||
*/
|
||||
inline uint32_t id() const
|
||||
{
|
||||
uint64_t m = _mac.toInt();
|
||||
uint32_t x1 = _adi;
|
||||
uint32_t x2 = (uint32_t)(m >> 32);
|
||||
uint32_t x3 = (uint32_t)m;
|
||||
x1 = ((x1 >> 16) ^ x1) * 0x45d9f3b;
|
||||
x2 = ((x2 >> 16) ^ x2) * 0x45d9f3b;
|
||||
x3 = ((x3 >> 16) ^ x3) * 0x45d9f3b;
|
||||
x1 = ((x1 >> 16) ^ x1) * 0x45d9f3b;
|
||||
x2 = ((x2 >> 16) ^ x2) * 0x45d9f3b;
|
||||
x3 = ((x3 >> 16) ^ x3) * 0x45d9f3b;
|
||||
x1 = (x1 >> 16) ^ x1;
|
||||
x2 = (x2 >> 16) ^ x2;
|
||||
x3 = (x3 >> 16) ^ x3;
|
||||
return (x1 ^ x2 ^ x3);
|
||||
}
|
||||
|
||||
inline bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); }
|
||||
inline bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); }
|
||||
inline bool operator<(const MulticastGroup &g) const
|
||||
ZT_ALWAYS_INLINE bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); }
|
||||
ZT_ALWAYS_INLINE bool operator<(const MulticastGroup &g) const
|
||||
{
|
||||
if (_mac < g._mac)
|
||||
return true;
|
||||
|
@ -110,11 +89,11 @@ public:
|
|||
return (_adi < g._adi);
|
||||
return false;
|
||||
}
|
||||
inline bool operator>(const MulticastGroup &g) const { return (g < *this); }
|
||||
inline bool operator<=(const MulticastGroup &g) const { return !(g < *this); }
|
||||
inline bool operator>=(const MulticastGroup &g) const { return !(*this < g); }
|
||||
ZT_ALWAYS_INLINE bool operator>(const MulticastGroup &g) const { return (g < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator<=(const MulticastGroup &g) const { return !(g < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator>=(const MulticastGroup &g) const { return !(*this < g); }
|
||||
|
||||
inline unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); }
|
||||
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); }
|
||||
|
||||
private:
|
||||
MAC _mac;
|
||||
|
|
|
@ -125,6 +125,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
return;
|
||||
|
||||
if (destination != RR->identity.address()) {
|
||||
// This packet is not for this node, so possibly relay it ----------
|
||||
|
||||
Packet packet(data,len);
|
||||
if (packet.hops() < ZT_RELAY_MAX_HOPS) {
|
||||
packet.incrementHops();
|
||||
|
@ -146,8 +148,9 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((reinterpret_cast<const uint8_t *>(data)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0) {
|
||||
// Packet is the head of a fragmented packet series
|
||||
// Packet is the head of a fragmented packet series ----------------
|
||||
|
||||
const uint64_t packetId = (
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[0]) << 56) |
|
||||
|
@ -172,10 +175,10 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
rq->haveFragments = 1;
|
||||
rq->complete = false;
|
||||
} else if (!(rq->haveFragments & 1)) {
|
||||
// If we have other fragments but no head, see if we are complete with the head
|
||||
// Check if packet is complete -----------------------------------
|
||||
|
||||
if ((rq->totalFragments > 1)&&(Utils::countBits(rq->haveFragments |= 1) == rq->totalFragments)) {
|
||||
// We have all fragments -- assemble and process full Packet
|
||||
// We have all fragments -- assemble and process full Packet ---
|
||||
|
||||
rq->frag0.init(data,len,path,now);
|
||||
for(unsigned int f=1;f<rq->totalFragments;++f)
|
||||
|
@ -186,13 +189,17 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
} else {
|
||||
rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something
|
||||
}
|
||||
|
||||
} else {
|
||||
// Still waiting on more fragments, but keep the head
|
||||
// Still waiting on more fragments, but keep the head ----------
|
||||
|
||||
rq->frag0.init(data,len,path,now);
|
||||
|
||||
}
|
||||
} // else this is a duplicate head, ignore
|
||||
} else {
|
||||
// Packet is unfragmented, so just process it
|
||||
|
||||
// Packet is unfragmented, so just process it ----------------------
|
||||
IncomingPacket packet(data,len,path,now);
|
||||
if (!packet.tryDecode(RR,tPtr)) {
|
||||
RXQueueEntry *const rq = _nextRXQueueEntry();
|
||||
|
@ -204,6 +211,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
rq->haveFragments = 1;
|
||||
rq->complete = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -364,10 +372,12 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
len);
|
||||
*/
|
||||
} else if (to == network->mac()) {
|
||||
// Destination is this node, so just reinject it
|
||||
// Destination is this node, so just reinject it -------------------------
|
||||
|
||||
RR->node->putFrame(tPtr,network->id(),network->userPtr(),from,to,etherType,vlanId,data,len);
|
||||
|
||||
} else if (to[0] == MAC::firstOctetForNetwork(network->id())) {
|
||||
// Destination is another ZeroTier peer on the same network
|
||||
// Destination is another ZeroTier peer on the same network --------------
|
||||
|
||||
Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this
|
||||
SharedPtr<Peer> toPeer(RR->topology->get(toZT));
|
||||
|
@ -400,7 +410,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
aqm_enqueue(tPtr,network,outp,true,qosBucket);
|
||||
}
|
||||
} else {
|
||||
// Destination is bridged behind a remote peer
|
||||
// Destination is bridged behind a remote peer ---------------------------
|
||||
|
||||
// We filter with a NULL destination ZeroTier address first. Filtrations
|
||||
// for each ZT destination are also done below. This is the same rationale
|
||||
|
|
|
@ -31,16 +31,6 @@
|
|||
#include "IncomingPacket.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
|
||||
/* Ethernet frame types that might be relevant to us */
|
||||
#define ZT_ETHERTYPE_IPV4 0x0800
|
||||
#define ZT_ETHERTYPE_ARP 0x0806
|
||||
#define ZT_ETHERTYPE_RARP 0x8035
|
||||
#define ZT_ETHERTYPE_ATALK 0x809b
|
||||
#define ZT_ETHERTYPE_AARP 0x80f3
|
||||
#define ZT_ETHERTYPE_IPX_A 0x8137
|
||||
#define ZT_ETHERTYPE_IPX_B 0x8138
|
||||
#define ZT_ETHERTYPE_IPV6 0x86dd
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
|
|
@ -161,7 +161,7 @@ public:
|
|||
* @tparam F Function or function object type
|
||||
*/
|
||||
template<typename F>
|
||||
inline void eachPeer(F f)
|
||||
ZT_ALWAYS_INLINE void eachPeer(F f)
|
||||
{
|
||||
Mutex::Lock l(_peers_l);
|
||||
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
|
||||
|
@ -191,7 +191,7 @@ public:
|
|||
/**
|
||||
* @param allPeers vector to fill with all current peers
|
||||
*/
|
||||
inline void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
|
||||
ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
|
||||
{
|
||||
Mutex::Lock l(_peers_l);
|
||||
allPeers.clear();
|
||||
|
|
|
@ -107,40 +107,7 @@ char *decimal(unsigned long n,char s[24])
|
|||
|
||||
unsigned short crc16(const void *buf,unsigned int len)
|
||||
{
|
||||
static const uint16_t crc16tab[256]= {
|
||||
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
|
||||
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
|
||||
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
|
||||
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
|
||||
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
|
||||
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
|
||||
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
|
||||
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
|
||||
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
|
||||
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
|
||||
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
|
||||
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
|
||||
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
|
||||
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
|
||||
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
|
||||
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
|
||||
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
|
||||
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
|
||||
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
|
||||
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
|
||||
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
|
||||
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
|
||||
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
|
||||
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
|
||||
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
|
||||
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
|
||||
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
|
||||
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
|
||||
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
|
||||
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
|
||||
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
|
||||
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
||||
};
|
||||
static const uint16_t crc16tab[256]= { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 };
|
||||
uint16_t crc = 0;
|
||||
const uint8_t *p = (const uint8_t *)buf;
|
||||
for(unsigned int i=0;i<len;++i)
|
||||
|
@ -148,35 +115,32 @@ unsigned short crc16(const void *buf,unsigned int len)
|
|||
return crc;
|
||||
}
|
||||
|
||||
unsigned int unhex(const char *h,void *buf,unsigned int buflen)
|
||||
char *hex10(uint64_t i,char s[11])
|
||||
{
|
||||
unsigned int l = 0;
|
||||
while (l < buflen) {
|
||||
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
s[0] = HEXCHARS[(i >> 36) & 0xf];
|
||||
s[1] = HEXCHARS[(i >> 32) & 0xf];
|
||||
s[2] = HEXCHARS[(i >> 28) & 0xf];
|
||||
s[3] = HEXCHARS[(i >> 24) & 0xf];
|
||||
s[4] = HEXCHARS[(i >> 20) & 0xf];
|
||||
s[5] = HEXCHARS[(i >> 16) & 0xf];
|
||||
s[6] = HEXCHARS[(i >> 12) & 0xf];
|
||||
s[7] = HEXCHARS[(i >> 8) & 0xf];
|
||||
s[8] = HEXCHARS[(i >> 4) & 0xf];
|
||||
s[9] = HEXCHARS[i & 0xf];
|
||||
s[10] = (char)0;
|
||||
return s;
|
||||
}
|
||||
|
||||
uint8_t c = 0;
|
||||
if ((hc >= 48)&&(hc <= 57)) // 0..9
|
||||
c = hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102)) // a..f
|
||||
c = hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70)) // A..F
|
||||
c = hc - 55;
|
||||
|
||||
hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
c <<= 4;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c |= hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c |= hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c |= hc - 55;
|
||||
|
||||
reinterpret_cast<uint8_t *>(buf)[l++] = c;
|
||||
char *hex(const void *d,unsigned int l,char *s)
|
||||
{
|
||||
char *const save = s;
|
||||
for(unsigned int i=0;i<l;++i) {
|
||||
const unsigned int b = reinterpret_cast<const uint8_t *>(d)[i];
|
||||
*(s++) = HEXCHARS[b >> 4];
|
||||
*(s++) = HEXCHARS[b & 0xf];
|
||||
}
|
||||
return l;
|
||||
*s = (char)0;
|
||||
return save;
|
||||
}
|
||||
|
||||
unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen)
|
||||
|
|
|
@ -89,21 +89,7 @@ static inline char *hex(I x,char *s)
|
|||
* @param s Buffer of size [11] to receive 10 hex characters
|
||||
* @return Pointer to buffer
|
||||
*/
|
||||
static inline char *hex10(uint64_t i,char s[11])
|
||||
{
|
||||
s[0] = HEXCHARS[(i >> 36) & 0xf];
|
||||
s[1] = HEXCHARS[(i >> 32) & 0xf];
|
||||
s[2] = HEXCHARS[(i >> 28) & 0xf];
|
||||
s[3] = HEXCHARS[(i >> 24) & 0xf];
|
||||
s[4] = HEXCHARS[(i >> 20) & 0xf];
|
||||
s[5] = HEXCHARS[(i >> 16) & 0xf];
|
||||
s[6] = HEXCHARS[(i >> 12) & 0xf];
|
||||
s[7] = HEXCHARS[(i >> 8) & 0xf];
|
||||
s[8] = HEXCHARS[(i >> 4) & 0xf];
|
||||
s[9] = HEXCHARS[i & 0xf];
|
||||
s[10] = (char)0;
|
||||
return s;
|
||||
}
|
||||
char *hex10(uint64_t i,char s[11]);
|
||||
|
||||
/**
|
||||
* Convert a byte array into hex
|
||||
|
@ -113,19 +99,17 @@ static inline char *hex10(uint64_t i,char s[11])
|
|||
* @param s String buffer, must be at least (l*2)+1 in size or overflow will occur
|
||||
* @return Pointer to filled string buffer
|
||||
*/
|
||||
static inline char *hex(const void *d,unsigned int l,char *s)
|
||||
{
|
||||
char *const save = s;
|
||||
for(unsigned int i=0;i<l;++i) {
|
||||
const unsigned int b = reinterpret_cast<const uint8_t *>(d)[i];
|
||||
*(s++) = HEXCHARS[b >> 4];
|
||||
*(s++) = HEXCHARS[b & 0xf];
|
||||
}
|
||||
*s = (char)0;
|
||||
return save;
|
||||
}
|
||||
char *hex(const void *d,unsigned int l,char *s);
|
||||
|
||||
unsigned int unhex(const char *h,void *buf,unsigned int buflen);
|
||||
/**
|
||||
* Decode a hex string
|
||||
*
|
||||
* @param h Hex C-string (non hex chars are ignored)
|
||||
* @param hlen Maximum length of string (will stop at terminating zero)
|
||||
* @param buf Output buffer
|
||||
* @param buflen Length of output buffer
|
||||
* @return Number of written bytes
|
||||
*/
|
||||
unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen);
|
||||
|
||||
/**
|
||||
|
@ -165,6 +149,19 @@ int b32d(const char *encoded, uint8_t *result, int bufSize);
|
|||
*/
|
||||
uint64_t random();
|
||||
|
||||
/**
|
||||
* Perform a safe C string copy, ALWAYS null-terminating the result
|
||||
*
|
||||
* This will never ever EVER result in dest[] not being null-terminated
|
||||
* regardless of any input parameter (other than len==0 which is invalid).
|
||||
*
|
||||
* @param dest Destination buffer (must not be NULL)
|
||||
* @param len Length of dest[] (if zero, false is returned and nothing happens)
|
||||
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
|
||||
* @return True on success, false on overflow (buffer will still be 0-terminated)
|
||||
*/
|
||||
bool scopy(char *dest,unsigned int len,const char *src);
|
||||
|
||||
static ZT_ALWAYS_INLINE float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
|
||||
{
|
||||
int64_t bigSpan = bigMax - bigMin;
|
||||
|
@ -230,19 +227,6 @@ static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a safe C string copy, ALWAYS null-terminating the result
|
||||
*
|
||||
* This will never ever EVER result in dest[] not being null-terminated
|
||||
* regardless of any input parameter (other than len==0 which is invalid).
|
||||
*
|
||||
* @param dest Destination buffer (must not be NULL)
|
||||
* @param len Length of dest[] (if zero, false is returned and nothing happens)
|
||||
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
|
||||
* @return True on success, false on overflow (buffer will still be 0-terminated)
|
||||
*/
|
||||
bool scopy(char *dest,unsigned int len,const char *src);
|
||||
|
||||
/**
|
||||
* Calculate a non-cryptographic hash of a byte string
|
||||
*
|
||||
|
@ -281,11 +265,21 @@ static ZT_ALWAYS_INLINE unsigned int countBits(T v)
|
|||
}
|
||||
#endif
|
||||
|
||||
// Byte swappers for big/little endian conversion
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n) { return htons(n); }
|
||||
static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
return htons(n);
|
||||
#elif (!defined(__OpenBSD__))
|
||||
return __builtin_bswap16(n);
|
||||
#endif
|
||||
#else
|
||||
return htons(n);
|
||||
#endif
|
||||
}
|
||||
static ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
|
||||
{
|
||||
|
@ -330,7 +324,18 @@ static ZT_ALWAYS_INLINE T hton(T n) { return n; }
|
|||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n) { return ntohs(n); }
|
||||
static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
return htons(n);
|
||||
#elif (!defined(__OpenBSD__))
|
||||
return __builtin_bswap16(n);
|
||||
#endif
|
||||
#else
|
||||
return htons(n);
|
||||
#endif
|
||||
}
|
||||
static ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue