Clang-format!!!
This commit is contained in:
parent
f190df8621
commit
96ba1079b2
122 changed files with 41245 additions and 39820 deletions
|
@ -57,7 +57,7 @@ SpacesInCStyleCastParentheses: 'false'
|
|||
SpacesInContainerLiterals: 'true'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
UseTab: 'Always'
|
||||
UseTab: 'Never'
|
||||
|
||||
---
|
||||
Language: Cpp
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#define ZT_DEBUG_H
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#include <sys/syscall.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -79,16 +79,13 @@
|
|||
#if defined(ZT_DEBUG_TRACE)
|
||||
#if ZT_MSG_INFO == true
|
||||
#if defined(__ANDROID__)
|
||||
#define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
|
||||
"INFO : %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
|
||||
#define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, "INFO : %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
#define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \
|
||||
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#endif
|
||||
#if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__)
|
||||
#define DEBUG_INFO(fmt, args ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \
|
||||
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
|
||||
#define DEBUG_INFO(fmt, args...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
|
||||
#endif
|
||||
#else
|
||||
#define DEBUG_INFO(fmt, args...)
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
|
||||
// For the struct sockaddr_storage structure
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#else /* not Windows */
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#endif /* Windows or not */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -372,8 +372,7 @@ extern "C" {
|
|||
* indicate serious problems like an inaccessible data store or a compile
|
||||
* problem.
|
||||
*/
|
||||
enum ZT_ResultCode
|
||||
{
|
||||
enum ZT_ResultCode {
|
||||
/**
|
||||
* Operation completed normally
|
||||
*/
|
||||
|
@ -428,8 +427,7 @@ enum ZT_ResultCode
|
|||
/**
|
||||
* Status codes sent to status update callback when things happen
|
||||
*/
|
||||
enum ZT_Event
|
||||
{
|
||||
enum ZT_Event {
|
||||
/**
|
||||
* Node has been initialized
|
||||
*
|
||||
|
@ -534,8 +532,7 @@ enum ZT_Event
|
|||
/**
|
||||
* Payload of REMOTE_TRACE event
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* ZeroTier address of sender
|
||||
*/
|
||||
|
@ -570,8 +567,7 @@ typedef struct
|
|||
* in the world can send you a user message! (Unless your network is air
|
||||
* gapped.)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* ZeroTier address of sender (least significant 40 bits)
|
||||
*/
|
||||
|
@ -596,8 +592,7 @@ typedef struct
|
|||
/**
|
||||
* Current node status
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* 40-bit ZeroTier address of this node
|
||||
*/
|
||||
|
@ -628,8 +623,7 @@ typedef struct
|
|||
*
|
||||
* This structure is subject to change between versions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* Number of each protocol verb (possible verbs 0..31) received
|
||||
*/
|
||||
|
@ -644,8 +638,7 @@ typedef struct
|
|||
/**
|
||||
* Virtual network status codes
|
||||
*/
|
||||
enum ZT_VirtualNetworkStatus
|
||||
{
|
||||
enum ZT_VirtualNetworkStatus {
|
||||
/**
|
||||
* Waiting for network configuration (also means revision == 0)
|
||||
*/
|
||||
|
@ -685,8 +678,7 @@ enum ZT_VirtualNetworkStatus
|
|||
/**
|
||||
* Virtual network type codes
|
||||
*/
|
||||
enum ZT_VirtualNetworkType
|
||||
{
|
||||
enum ZT_VirtualNetworkType {
|
||||
/**
|
||||
* Private networks are authorized via certificates of membership
|
||||
*/
|
||||
|
@ -707,8 +699,7 @@ enum ZT_VirtualNetworkType
|
|||
* Each rule is composed of zero or more MATCHes followed by an ACTION.
|
||||
* An ACTION with no MATCHes is always taken.
|
||||
*/
|
||||
enum ZT_VirtualNetworkRuleType
|
||||
{
|
||||
enum ZT_VirtualNetworkRuleType {
|
||||
// 0 to 15 reserved for actions
|
||||
|
||||
/**
|
||||
|
@ -799,8 +790,7 @@ enum ZT_VirtualNetworkRuleType
|
|||
* This is designed to be a more memory-efficient way of storing rules than
|
||||
* a wide table, yet still fast and simple to access in code.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* Type and flags
|
||||
*
|
||||
|
@ -947,8 +937,7 @@ typedef struct
|
|||
/**
|
||||
* A route to be pushed on a virtual network
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default
|
||||
*/
|
||||
|
@ -973,8 +962,7 @@ typedef struct
|
|||
/**
|
||||
* DNS configuration to be pushed on a virtual network
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
char domain[128];
|
||||
struct sockaddr_storage server_addr[ZT_MAX_DNS_SERVERS];
|
||||
} ZT_VirtualNetworkDNS;
|
||||
|
@ -982,8 +970,7 @@ typedef struct
|
|||
/**
|
||||
* An Ethernet multicast group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* MAC address (least significant 48 bits)
|
||||
*/
|
||||
|
@ -998,8 +985,7 @@ typedef struct
|
|||
/**
|
||||
* Virtual network configuration update type
|
||||
*/
|
||||
enum ZT_VirtualNetworkConfigOperation
|
||||
{
|
||||
enum ZT_VirtualNetworkConfigOperation {
|
||||
/**
|
||||
* Network is coming up (either for the first time or after service restart)
|
||||
*/
|
||||
|
@ -1024,8 +1010,7 @@ enum ZT_VirtualNetworkConfigOperation
|
|||
/**
|
||||
* What trust hierarchy role does this peer have?
|
||||
*/
|
||||
enum ZT_PeerRole
|
||||
{
|
||||
enum ZT_PeerRole {
|
||||
ZT_PEER_ROLE_LEAF = 0, // ordinary node
|
||||
ZT_PEER_ROLE_MOON = 1, // moon root
|
||||
ZT_PEER_ROLE_PLANET = 2 // planetary root
|
||||
|
@ -1034,17 +1019,12 @@ enum ZT_PeerRole
|
|||
/**
|
||||
* Vendor ID
|
||||
*/
|
||||
enum ZT_Vendor
|
||||
{
|
||||
ZT_VENDOR_UNSPECIFIED = 0,
|
||||
ZT_VENDOR_ZEROTIER = 1
|
||||
};
|
||||
enum ZT_Vendor { ZT_VENDOR_UNSPECIFIED = 0, ZT_VENDOR_ZEROTIER = 1 };
|
||||
|
||||
/**
|
||||
* Platform type
|
||||
*/
|
||||
enum ZT_Platform
|
||||
{
|
||||
enum ZT_Platform {
|
||||
ZT_PLATFORM_UNSPECIFIED = 0,
|
||||
ZT_PLATFORM_LINUX = 1,
|
||||
ZT_PLATFORM_WINDOWS = 2,
|
||||
|
@ -1066,8 +1046,7 @@ enum ZT_Platform
|
|||
/**
|
||||
* Architecture type
|
||||
*/
|
||||
enum ZT_Architecture
|
||||
{
|
||||
enum ZT_Architecture {
|
||||
ZT_ARCHITECTURE_UNSPECIFIED = 0,
|
||||
ZT_ARCHITECTURE_X86 = 1,
|
||||
ZT_ARCHITECTURE_X64 = 2,
|
||||
|
@ -1091,8 +1070,7 @@ enum ZT_Architecture
|
|||
/**
|
||||
* Virtual network configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* 64-bit ZeroTier network ID
|
||||
*/
|
||||
|
@ -1200,8 +1178,6 @@ typedef struct
|
|||
*/
|
||||
ZT_VirtualNetworkDNS dns;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* sso enabled
|
||||
*/
|
||||
|
@ -1256,8 +1232,7 @@ typedef struct
|
|||
/**
|
||||
* A list of networks
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
ZT_VirtualNetworkConfig* networks;
|
||||
unsigned long networkCount;
|
||||
} ZT_VirtualNetworkList;
|
||||
|
@ -1280,8 +1255,7 @@ typedef struct {
|
|||
/**
|
||||
* Physical network path to a peer
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* Address of endpoint
|
||||
*/
|
||||
|
@ -1386,8 +1360,7 @@ typedef struct
|
|||
/**
|
||||
* Peer status result buffer
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/**
|
||||
* ZeroTier address (40 bits)
|
||||
*/
|
||||
|
@ -1457,8 +1430,7 @@ typedef struct
|
|||
/**
|
||||
* List of peers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
ZT_Peer* peers;
|
||||
unsigned long peerCount;
|
||||
} ZT_PeerList;
|
||||
|
@ -1466,8 +1438,7 @@ typedef struct
|
|||
/**
|
||||
* ZeroTier core state objects
|
||||
*/
|
||||
enum ZT_StateObjectType
|
||||
{
|
||||
enum ZT_StateObjectType {
|
||||
/**
|
||||
* Null object -- ignored
|
||||
*/
|
||||
|
@ -1730,8 +1701,7 @@ typedef int (*ZT_PathLookupFunction)(
|
|||
/**
|
||||
* Structure for configuring ZeroTier core callback functions
|
||||
*/
|
||||
struct ZT_Node_Callbacks
|
||||
{
|
||||
struct ZT_Node_Callbacks {
|
||||
/**
|
||||
* Struct version -- must currently be 0
|
||||
*/
|
||||
|
@ -1818,15 +1788,8 @@ ZT_SDK_API void ZT_Node_delete(ZT_Node *node);
|
|||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
volatile int64_t *nextBackgroundTaskDeadline);
|
||||
ZT_SDK_API enum ZT_ResultCode
|
||||
ZT_Node_processWirePacket(ZT_Node* node, void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline);
|
||||
|
||||
/**
|
||||
* Process a frame from a virtual network port (tap)
|
||||
|
|
90
node/AES.cpp
90
node/AES.cpp
|
@ -11,9 +11,10 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "AES.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
|
@ -343,7 +344,8 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept
|
|||
*reinterpret_cast<uint64_t*>(out + 8) = in1 ^ Utils::hton(((uint64_t)s2 << 32U) | (uint64_t)s3);
|
||||
out += 16;
|
||||
} while ((len -= 16) >= 16);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
do {
|
||||
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
s0 = ctr0rk0;
|
||||
|
@ -454,34 +456,62 @@ void AES::CTR::finish() noexcept
|
|||
|
||||
// Software AES and AES key expansion ---------------------------------------------------------------------------------
|
||||
|
||||
const uint32_t AES::Te0[256] = {0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153,
|
||||
0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
|
||||
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba,
|
||||
0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
|
||||
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437,
|
||||
0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
|
||||
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878,
|
||||
0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a};
|
||||
const uint32_t AES::Te4[256] = {0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171, 0xd8d8d8d8, 0x31313131,
|
||||
0x15151515, 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
|
||||
0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f,
|
||||
0xa8a8a8a8, 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
|
||||
0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4,
|
||||
0x79797979, 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
|
||||
0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828,
|
||||
0xdfdfdfdf, 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616};
|
||||
const uint32_t AES::Td0[256] = {0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c,
|
||||
0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
|
||||
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1,
|
||||
0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
|
||||
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e,
|
||||
0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
|
||||
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14,
|
||||
0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742};
|
||||
const uint8_t AES::Td4[256] = {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d,
|
||||
0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c,
|
||||
0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
|
||||
const uint32_t AES::Te0[256] = { 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
|
||||
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
|
||||
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
|
||||
0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
|
||||
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
|
||||
0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
|
||||
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
|
||||
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
|
||||
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
|
||||
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
|
||||
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
|
||||
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
|
||||
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
|
||||
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
|
||||
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
|
||||
0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a };
|
||||
const uint32_t AES::Te4[256] = { 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
|
||||
0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
|
||||
0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
|
||||
0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
|
||||
0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
|
||||
0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
|
||||
0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
|
||||
0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
|
||||
0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
|
||||
0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
|
||||
0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
|
||||
0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
|
||||
0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
|
||||
0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
|
||||
0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
|
||||
0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616 };
|
||||
const uint32_t AES::Td0[256] = { 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
|
||||
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
|
||||
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
|
||||
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
|
||||
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
|
||||
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
|
||||
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
|
||||
0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
|
||||
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
|
||||
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
|
||||
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
|
||||
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
|
||||
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
|
||||
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
|
||||
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
|
||||
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 };
|
||||
const uint8_t AES::Td4[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
const uint32_t AES::rcon[15] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000 };
|
||||
|
||||
void AES::p_initSW(const uint8_t* key) noexcept
|
||||
|
|
72
node/AES.hpp
72
node/AES.hpp
|
@ -15,8 +15,8 @@
|
|||
#define ZT_AES_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
// Uncomment to disable all hardware acceleration (usually for testing)
|
||||
// #define ZT_AES_NO_ACCEL
|
||||
|
@ -40,8 +40,7 @@ namespace ZeroTier {
|
|||
* This includes hardware acceleration for certain processors. The software
|
||||
* mode is fallback and is significantly slower.
|
||||
*/
|
||||
class AES
|
||||
{
|
||||
class AES {
|
||||
public:
|
||||
/**
|
||||
* @return True if this system has hardware AES acceleration
|
||||
|
@ -63,7 +62,8 @@ public:
|
|||
* Create an un-initialized AES instance (must call init() before use)
|
||||
*/
|
||||
ZT_INLINE AES() noexcept
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AES instance with the given key
|
||||
|
@ -71,10 +71,14 @@ public:
|
|||
* @param key 256-bit key
|
||||
*/
|
||||
explicit ZT_INLINE AES(const void* const key) noexcept
|
||||
{ this->init(key); }
|
||||
{
|
||||
this->init(key);
|
||||
}
|
||||
|
||||
ZT_INLINE ~AES()
|
||||
{ Utils::burn(&p_k, sizeof(p_k)); }
|
||||
{
|
||||
Utils::burn(&p_k, sizeof(p_k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set (or re-set) this AES256 cipher's key
|
||||
|
@ -150,8 +154,7 @@ public:
|
|||
/**
|
||||
* Streaming GMAC calculator
|
||||
*/
|
||||
class GMAC
|
||||
{
|
||||
class GMAC {
|
||||
friend class GMACSIVEncryptor;
|
||||
friend class GMACSIVDecryptor;
|
||||
|
||||
|
@ -178,7 +181,8 @@ public:
|
|||
* @param aes Keyed AES instance to use
|
||||
*/
|
||||
ZT_INLINE GMAC(const AES& aes) : _aes(aes)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset and initialize for a new GMAC calculation
|
||||
|
@ -249,14 +253,14 @@ public:
|
|||
* NOTE: this doesn't support overflow of the counter in the least significant 32 bits.
|
||||
* AES-GMAC-CTR doesn't need this, so we don't support it as an optimization.
|
||||
*/
|
||||
class CTR
|
||||
{
|
||||
class CTR {
|
||||
friend class GMACSIVEncryptor;
|
||||
friend class GMACSIVDecryptor;
|
||||
|
||||
public:
|
||||
ZT_INLINE CTR(const AES& aes) noexcept : _aes(aes)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this CTR instance to encrypt a new stream
|
||||
|
@ -325,8 +329,7 @@ public:
|
|||
* This supports encryption of a maximum of 2^31 bytes of data per
|
||||
* call to init().
|
||||
*/
|
||||
class GMACSIVEncryptor
|
||||
{
|
||||
class GMACSIVEncryptor {
|
||||
public:
|
||||
/**
|
||||
* Create a new AES-GMAC-SIV encryptor keyed with the provided AES instances
|
||||
|
@ -334,10 +337,11 @@ public:
|
|||
* @param k0 First of two AES instances keyed with K0
|
||||
* @param k1 Second of two AES instances keyed with K1
|
||||
*/
|
||||
ZT_INLINE GMACSIVEncryptor(const AES &k0, const AES &k1) noexcept :
|
||||
_gmac(k0),
|
||||
_ctr(k1)
|
||||
{}
|
||||
ZT_INLINE GMACSIVEncryptor(const AES& k0, const AES& k1) noexcept
|
||||
: _gmac(k0)
|
||||
, _ctr(k1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize AES-GMAC-SIV
|
||||
|
@ -386,7 +390,9 @@ public:
|
|||
* @param len Length of plaintext chunk
|
||||
*/
|
||||
ZT_INLINE void update1(const void* const input, const unsigned int len) noexcept
|
||||
{ _gmac.update(input, len); }
|
||||
{
|
||||
_gmac.update(input, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish first pass, compute CTR IV, initialize second pass.
|
||||
|
@ -428,7 +434,9 @@ public:
|
|||
* @param len Length of plaintext chunk
|
||||
*/
|
||||
ZT_INLINE void update2(const void* const input, const unsigned int len) noexcept
|
||||
{ _ctr.crypt(input, len); }
|
||||
{
|
||||
_ctr.crypt(input, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish second pass and return a pointer to the opaque 128-bit IV+MAC block
|
||||
|
@ -456,13 +464,13 @@ public:
|
|||
*
|
||||
* GMAC-SIV decryption is single-pass. AAD (if any) must be processed first.
|
||||
*/
|
||||
class GMACSIVDecryptor
|
||||
{
|
||||
class GMACSIVDecryptor {
|
||||
public:
|
||||
ZT_INLINE GMACSIVDecryptor(const AES &k0, const AES &k1) noexcept:
|
||||
_ctr(k1),
|
||||
_gmac(k0)
|
||||
{}
|
||||
ZT_INLINE GMACSIVDecryptor(const AES& k0, const AES& k1) noexcept
|
||||
: _ctr(k1)
|
||||
, _gmac(k0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize decryptor for a new message
|
||||
|
@ -550,11 +558,9 @@ private:
|
|||
void p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept;
|
||||
void p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept;
|
||||
|
||||
union
|
||||
{
|
||||
union {
|
||||
#ifdef ZT_AES_AESNI
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
__m128i k[28];
|
||||
__m128i h[4]; // h, hh, hhh, hhhh
|
||||
__m128i h2[4]; // _mm_xor_si128(_mm_shuffle_epi32(h, 78), h), etc.
|
||||
|
@ -562,8 +568,7 @@ private:
|
|||
#endif
|
||||
|
||||
#ifdef ZT_AES_NEON
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
uint64_t hsw[2]; // in case it has AES but not PMULL, not sure if that ever happens
|
||||
uint8x16_t ek[15];
|
||||
uint8x16_t dk[15];
|
||||
|
@ -571,8 +576,7 @@ private:
|
|||
} neon;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
uint64_t h[2];
|
||||
uint32_t ek[60];
|
||||
uint32_t dk[60];
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "AES.hpp"
|
||||
#include "Constants.hpp"
|
||||
|
||||
#ifdef ZT_AES_AESNI
|
||||
|
||||
|
@ -29,7 +29,8 @@ const __m128i s_sseSwapBytes = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
|
|||
#ifdef __GNUC__
|
||||
__attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul")))
|
||||
#endif
|
||||
__m128i p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept
|
||||
__m128i
|
||||
p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept
|
||||
{
|
||||
y = _mm_shuffle_epi8(y, s_sseSwapBytes);
|
||||
__m128i t1 = _mm_clmulepi64_si128(h, y, 0x00);
|
||||
|
@ -81,11 +82,7 @@ void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, co
|
|||
const __m512i kk14 = _mm512_broadcast_i32x4(k[14]);
|
||||
do {
|
||||
__m512i p0 = _mm512_loadu_si512(reinterpret_cast<const __m512i*>(in));
|
||||
__m512i d0 = _mm512_set_epi64(
|
||||
(long long)Utils::hton(c1 + 3ULL), (long long)c0,
|
||||
(long long)Utils::hton(c1 + 2ULL), (long long)c0,
|
||||
(long long)Utils::hton(c1 + 1ULL), (long long)c0,
|
||||
(long long)Utils::hton(c1), (long long)c0);
|
||||
__m512i d0 = _mm512_set_epi64((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0, (long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
|
||||
c1 += 4;
|
||||
in += 64;
|
||||
len -= 64;
|
||||
|
@ -134,12 +131,8 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co
|
|||
do {
|
||||
__m256i p0 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(in));
|
||||
__m256i p1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(in + 32));
|
||||
__m256i d0 = _mm256_set_epi64x(
|
||||
(long long)Utils::hton(c1 + 1ULL), (long long)c0,
|
||||
(long long)Utils::hton(c1), (long long)c0);
|
||||
__m256i d1 = _mm256_set_epi64x(
|
||||
(long long)Utils::hton(c1 + 3ULL), (long long)c0,
|
||||
(long long)Utils::hton(c1 + 2ULL), (long long)c0);
|
||||
__m256i d0 = _mm256_set_epi64x((long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
|
||||
__m256i d1 = _mm256_set_epi64x((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0);
|
||||
c1 += 4;
|
||||
in += 64;
|
||||
len -= 64;
|
||||
|
@ -184,7 +177,8 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co
|
|||
#ifdef __GNUC__
|
||||
__attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul")))
|
||||
#endif
|
||||
__m128i p_init256_1_aesni(__m128i a, __m128i b) noexcept
|
||||
__m128i
|
||||
p_init256_1_aesni(__m128i a, __m128i b) noexcept
|
||||
{
|
||||
__m128i x, y;
|
||||
b = _mm_shuffle_epi32(b, 0xff);
|
||||
|
@ -201,7 +195,8 @@ __m128i p_init256_1_aesni(__m128i a, __m128i b) noexcept
|
|||
#ifdef __GNUC__
|
||||
__attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul")))
|
||||
#endif
|
||||
__m128i p_init256_2_aesni(__m128i a, __m128i b) noexcept
|
||||
__m128i
|
||||
p_init256_2_aesni(__m128i a, __m128i b) noexcept
|
||||
{
|
||||
__m128i x, y, z;
|
||||
y = _mm_aeskeygenassist_si128(a, 0x00);
|
||||
|
@ -260,7 +255,11 @@ void AES::GMAC::p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept
|
|||
in += 64;
|
||||
__m128i a = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x00), _mm_clmulepi64_si128(hhh, d2, 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x00), _mm_clmulepi64_si128(h, d4, 0x00)));
|
||||
__m128i b = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x11), _mm_clmulepi64_si128(hhh, d2, 0x11)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x11), _mm_clmulepi64_si128(h, d4, 0x11)));
|
||||
__m128i c = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))), _mm_xor_si128(a, b));
|
||||
__m128i c = _mm_xor_si128(
|
||||
_mm_xor_si128(
|
||||
_mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)),
|
||||
_mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))),
|
||||
_mm_xor_si128(a, b));
|
||||
a = _mm_xor_si128(_mm_slli_si128(c, 8), a);
|
||||
b = _mm_xor_si128(_mm_srli_si128(c, 8), b);
|
||||
c = _mm_srli_epi32(a, 31);
|
||||
|
@ -427,12 +426,12 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
|
|||
_len = totalLen + len;
|
||||
|
||||
if (likely(len >= 64)) {
|
||||
|
||||
#if defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
|
||||
if (Utils::CPUID.vaes && (len >= 256)) {
|
||||
if (Utils::CPUID.avx512f) {
|
||||
p_aesCtrInnerVAES512(len, _ctr[0], c1, in, out, k);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p_aesCtrInnerVAES256(len, _ctr[0], c1, in, out, k);
|
||||
}
|
||||
goto skip_conventional_aesni_64;
|
||||
|
@ -526,7 +525,6 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
|
|||
_mm_storeu_si128(reinterpret_cast<__m128i*>(out + 48), d3);
|
||||
out += 64;
|
||||
} while (likely(in != eof64));
|
||||
|
||||
}
|
||||
|
||||
skip_conventional_aesni_64:
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "AES.hpp"
|
||||
#include "Constants.hpp"
|
||||
|
||||
#ifdef ZT_AES_NEON
|
||||
|
||||
|
@ -309,9 +309,14 @@ void AES::CTR::p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noe
|
|||
|
||||
void AES::p_init_armneon_crypto(const uint8_t* key) noexcept
|
||||
{
|
||||
static const uint8_t s_sbox[256] = {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c,
|
||||
0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea,
|
||||
0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
|
||||
static const uint8_t s_sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
|
||||
|
||||
uint64_t h[2];
|
||||
uint32_t* const w = reinterpret_cast<uint32_t*>(p_k.neon.ek);
|
||||
|
@ -326,7 +331,8 @@ void AES::p_init_armneon_crypto(const uint8_t *key) noexcept
|
|||
const unsigned int imod = i & (ZT_INIT_ARMNEON_CRYPTO_NK - 1);
|
||||
if (imod == 0) {
|
||||
t = ZT_INIT_ARMNEON_CRYPTO_SUBWORD(ZT_INIT_ARMNEON_CRYPTO_ROTWORD(t)) ^ rcon[(i - 1) / ZT_INIT_ARMNEON_CRYPTO_NK];
|
||||
} else if (imod == 4) {
|
||||
}
|
||||
else if (imod == 4) {
|
||||
t = ZT_INIT_ARMNEON_CRYPTO_SUBWORD(t);
|
||||
}
|
||||
w[i] = w[i - ZT_INIT_ARMNEON_CRYPTO_NK] ^ t;
|
||||
|
|
145
node/Address.hpp
145
node/Address.hpp
|
@ -14,37 +14,52 @@
|
|||
#ifndef ZT_ADDRESS_HPP
|
||||
#define ZT_ADDRESS_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A ZeroTier address
|
||||
*/
|
||||
class Address
|
||||
{
|
||||
class Address {
|
||||
public:
|
||||
Address() : _a(0) {}
|
||||
Address(const Address &a) : _a(a._a) {}
|
||||
Address(uint64_t a) : _a(a & 0xffffffffffULL) {}
|
||||
Address() : _a(0)
|
||||
{
|
||||
}
|
||||
Address(const Address& a) : _a(a._a)
|
||||
{
|
||||
}
|
||||
Address(uint64_t a) : _a(a & 0xffffffffffULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bits Raw address -- 5 bytes, big-endian byte order
|
||||
* @param len Length of array
|
||||
*/
|
||||
Address(const void *bits,unsigned int len) { setTo(bits,len); }
|
||||
Address(const void* bits, unsigned int len)
|
||||
{
|
||||
setTo(bits, len);
|
||||
}
|
||||
|
||||
inline Address &operator=(const Address &a) { _a = a._a; return *this; }
|
||||
inline Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; }
|
||||
inline Address& operator=(const Address& a)
|
||||
{
|
||||
_a = a._a;
|
||||
return *this;
|
||||
}
|
||||
inline Address& operator=(const uint64_t a)
|
||||
{
|
||||
_a = (a & 0xffffffffffULL);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bits Raw address -- 5 bytes, big-endian byte order
|
||||
|
@ -87,8 +102,7 @@ public:
|
|||
*
|
||||
* @param b Buffer to append to
|
||||
*/
|
||||
template<unsigned int C>
|
||||
inline void appendTo(Buffer<C> &b) const
|
||||
template <unsigned int C> inline void appendTo(Buffer<C>& b) const
|
||||
{
|
||||
unsigned char* p = (unsigned char*)b.appendField(ZT_ADDRESS_LENGTH);
|
||||
*(p++) = (unsigned char)((_a >> 32) & 0xff);
|
||||
|
@ -101,22 +115,34 @@ public:
|
|||
/**
|
||||
* @return Integer containing address (0 to 2^40)
|
||||
*/
|
||||
inline uint64_t toInt() const { return _a; }
|
||||
inline uint64_t toInt() const
|
||||
{
|
||||
return _a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Hash code for use with Hashtable
|
||||
*/
|
||||
inline unsigned long hashCode() const { return (unsigned long)_a; }
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (unsigned long)_a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Hexadecimal string
|
||||
*/
|
||||
inline char *toString(char buf[11]) const { return Utils::hex10(_a,buf); }
|
||||
inline char* toString(char buf[11]) const
|
||||
{
|
||||
return Utils::hex10(_a, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this address is not zero
|
||||
*/
|
||||
inline operator bool() const { return (_a != 0); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_a != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this address is reserved
|
||||
|
@ -127,29 +153,74 @@ public:
|
|||
*
|
||||
* @return True if address is reserved and may not be used
|
||||
*/
|
||||
inline bool isReserved() const { return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX)); }
|
||||
inline bool isReserved() const
|
||||
{
|
||||
return ((! _a) || ((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i Value from 0 to 4 (inclusive)
|
||||
* @return Byte at said position (address interpreted in big-endian order)
|
||||
*/
|
||||
inline uint8_t operator[](unsigned int i) const { return (uint8_t)(_a >> (32 - (i * 8))); }
|
||||
inline uint8_t operator[](unsigned int i) const
|
||||
{
|
||||
return (uint8_t)(_a >> (32 - (i * 8)));
|
||||
}
|
||||
|
||||
inline void zero() { _a = 0; }
|
||||
inline void zero()
|
||||
{
|
||||
_a = 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const uint64_t &a) const { return (_a == (a & 0xffffffffffULL)); }
|
||||
inline bool operator!=(const uint64_t &a) const { return (_a != (a & 0xffffffffffULL)); }
|
||||
inline bool operator>(const uint64_t &a) const { return (_a > (a & 0xffffffffffULL)); }
|
||||
inline bool operator<(const uint64_t &a) const { return (_a < (a & 0xffffffffffULL)); }
|
||||
inline bool operator>=(const uint64_t &a) const { return (_a >= (a & 0xffffffffffULL)); }
|
||||
inline bool operator<=(const uint64_t &a) const { return (_a <= (a & 0xffffffffffULL)); }
|
||||
inline bool operator==(const uint64_t& a) const
|
||||
{
|
||||
return (_a == (a & 0xffffffffffULL));
|
||||
}
|
||||
inline bool operator!=(const uint64_t& a) const
|
||||
{
|
||||
return (_a != (a & 0xffffffffffULL));
|
||||
}
|
||||
inline bool operator>(const uint64_t& a) const
|
||||
{
|
||||
return (_a > (a & 0xffffffffffULL));
|
||||
}
|
||||
inline bool operator<(const uint64_t& a) const
|
||||
{
|
||||
return (_a < (a & 0xffffffffffULL));
|
||||
}
|
||||
inline bool operator>=(const uint64_t& a) const
|
||||
{
|
||||
return (_a >= (a & 0xffffffffffULL));
|
||||
}
|
||||
inline bool operator<=(const uint64_t& a) const
|
||||
{
|
||||
return (_a <= (a & 0xffffffffffULL));
|
||||
}
|
||||
|
||||
inline bool operator==(const Address &a) const { return (_a == a._a); }
|
||||
inline bool operator!=(const Address &a) const { return (_a != a._a); }
|
||||
inline bool operator>(const Address &a) const { return (_a > a._a); }
|
||||
inline bool operator<(const Address &a) const { return (_a < a._a); }
|
||||
inline bool operator>=(const Address &a) const { return (_a >= a._a); }
|
||||
inline bool operator<=(const Address &a) const { return (_a <= a._a); }
|
||||
inline bool operator==(const Address& a) const
|
||||
{
|
||||
return (_a == a._a);
|
||||
}
|
||||
inline bool operator!=(const Address& a) const
|
||||
{
|
||||
return (_a != a._a);
|
||||
}
|
||||
inline bool operator>(const Address& a) const
|
||||
{
|
||||
return (_a > a._a);
|
||||
}
|
||||
inline bool operator<(const Address& a) const
|
||||
{
|
||||
return (_a < a._a);
|
||||
}
|
||||
inline bool operator>=(const Address& a) const
|
||||
{
|
||||
return (_a >= a._a);
|
||||
}
|
||||
inline bool operator<=(const Address& a) const
|
||||
{
|
||||
return (_a <= a._a);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _a;
|
||||
|
|
|
@ -25,10 +25,12 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Simple atomic counter supporting increment and decrement
|
||||
*/
|
||||
class AtomicCounter
|
||||
{
|
||||
class AtomicCounter {
|
||||
public:
|
||||
AtomicCounter() { _v = 0; }
|
||||
AtomicCounter()
|
||||
{
|
||||
_v = 0;
|
||||
}
|
||||
|
||||
inline int load() const
|
||||
{
|
||||
|
@ -58,8 +60,13 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
AtomicCounter(const AtomicCounter &) {}
|
||||
const AtomicCounter &operator=(const AtomicCounter &) { return *this; }
|
||||
AtomicCounter(const AtomicCounter&)
|
||||
{
|
||||
}
|
||||
const AtomicCounter& operator=(const AtomicCounter&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
int _v;
|
||||
|
|
141
node/Buffer.hpp
141
node/Buffer.hpp
|
@ -14,17 +14,16 @@
|
|||
#ifndef ZT_BUFFER_HPP
|
||||
#define ZT_BUFFER_HPP
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#if defined(__GNUC__) && (! defined(ZT_NO_TYPE_PUNNING))
|
||||
#define ZT_VAR_MAY_ALIAS __attribute__((__may_alias__))
|
||||
#else
|
||||
|
@ -46,9 +45,7 @@ namespace ZeroTier {
|
|||
*
|
||||
* @tparam C Total capacity
|
||||
*/
|
||||
template<unsigned int C>
|
||||
class Buffer
|
||||
{
|
||||
template <unsigned int C> class Buffer {
|
||||
// I love me!
|
||||
template <unsigned int C2> friend class Buffer;
|
||||
|
||||
|
@ -65,17 +62,40 @@ public:
|
|||
typedef int difference_type;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
inline iterator begin() { return _b; }
|
||||
inline iterator end() { return (_b + _l); }
|
||||
inline const_iterator begin() const { return _b; }
|
||||
inline const_iterator end() const { return (_b + _l); }
|
||||
inline reverse_iterator rbegin() { return reverse_iterator(begin()); }
|
||||
inline reverse_iterator rend() { return reverse_iterator(end()); }
|
||||
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
|
||||
inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
||||
inline iterator begin()
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
inline iterator end()
|
||||
{
|
||||
return (_b + _l);
|
||||
}
|
||||
inline const_iterator begin() const
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
inline const_iterator end() const
|
||||
{
|
||||
return (_b + _l);
|
||||
}
|
||||
inline reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
inline reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
inline const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
inline const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
Buffer() :
|
||||
_l(0)
|
||||
Buffer() : _l(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -87,8 +107,7 @@ public:
|
|||
_l = l;
|
||||
}
|
||||
|
||||
template<unsigned int C2>
|
||||
Buffer(const Buffer<C2> &b)
|
||||
template <unsigned int C2> Buffer(const Buffer<C2>& b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
@ -98,15 +117,15 @@ public:
|
|||
copyFrom(b, l);
|
||||
}
|
||||
|
||||
template<unsigned int C2>
|
||||
inline Buffer &operator=(const Buffer<C2> &b)
|
||||
template <unsigned int C2> inline Buffer& operator=(const Buffer<C2>& b)
|
||||
{
|
||||
if (unlikely(b._l > C)) {
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
}
|
||||
if (C2 == C) {
|
||||
memcpy(this, &b, sizeof(Buffer<C>));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(_b, b._b, _l = b._l);
|
||||
}
|
||||
return *this;
|
||||
|
@ -172,8 +191,7 @@ public:
|
|||
* @param v Value
|
||||
* @tparam T Integer type (e.g. uint16_t, int64_t)
|
||||
*/
|
||||
template<typename T>
|
||||
inline void setAt(unsigned int i,const T v)
|
||||
template <typename T> inline void setAt(unsigned int i, const T v)
|
||||
{
|
||||
if (unlikely((i + sizeof(T)) > _l)) {
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
|
@ -196,8 +214,7 @@ public:
|
|||
* @tparam T Integer type (e.g. uint16_t, int64_t)
|
||||
* @return Integer value
|
||||
*/
|
||||
template<typename T>
|
||||
inline T at(unsigned int i) const
|
||||
template <typename T> inline T at(unsigned int i) const
|
||||
{
|
||||
if (unlikely((i + sizeof(T)) > _l)) {
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
|
@ -223,8 +240,7 @@ public:
|
|||
* @tparam T Integer type (e.g. uint16_t, int64_t)
|
||||
* @throws std::out_of_range Attempt to append beyond capacity
|
||||
*/
|
||||
template<typename T>
|
||||
inline void append(const T v)
|
||||
template <typename T> inline void append(const T v)
|
||||
{
|
||||
if (unlikely((_l + sizeof(T)) > C)) {
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
|
@ -313,8 +329,7 @@ public:
|
|||
* @tparam C2 Capacity of second buffer (typically inferred)
|
||||
* @throws std::out_of_range Attempt to append beyond capacity
|
||||
*/
|
||||
template<unsigned int C2>
|
||||
inline void append(const Buffer<C2> &b)
|
||||
template <unsigned int C2> inline void append(const Buffer<C2>& b)
|
||||
{
|
||||
append(b._b, b._l);
|
||||
}
|
||||
|
@ -408,70 +423,88 @@ public:
|
|||
/**
|
||||
* Set buffer data length to zero
|
||||
*/
|
||||
inline void clear() { _l = 0; }
|
||||
inline void clear()
|
||||
{
|
||||
_l = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero buffer up to size()
|
||||
*/
|
||||
inline void zero() { memset(_b,0,_l); }
|
||||
inline void zero()
|
||||
{
|
||||
memset(_b, 0, _l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero unused capacity area
|
||||
*/
|
||||
inline void zeroUnused() { memset(_b + _l,0,C - _l); }
|
||||
inline void zeroUnused()
|
||||
{
|
||||
memset(_b + _l, 0, C - _l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unconditionally and securely zero buffer's underlying memory
|
||||
*/
|
||||
inline void burn() { Utils::burn(_b,sizeof(_b)); }
|
||||
inline void burn()
|
||||
{
|
||||
Utils::burn(_b, sizeof(_b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Constant pointer to data in buffer
|
||||
*/
|
||||
inline const void *data() const { return _b; }
|
||||
inline const void* data() const
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Non-constant pointer to data in buffer
|
||||
*/
|
||||
inline void *unsafeData() { return _b; }
|
||||
inline void* unsafeData()
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Size of data in buffer
|
||||
*/
|
||||
inline unsigned int size() const { return _l; }
|
||||
inline unsigned int size() const
|
||||
{
|
||||
return _l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Capacity of buffer
|
||||
*/
|
||||
inline unsigned int capacity() const { return C; }
|
||||
inline unsigned int capacity() const
|
||||
{
|
||||
return C;
|
||||
}
|
||||
|
||||
template<unsigned int C2>
|
||||
inline bool operator==(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator==(const Buffer<C2>& b) const
|
||||
{
|
||||
return ((_l == b._l) && (! memcmp(_b, b._b, _l)));
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator!=(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator!=(const Buffer<C2>& b) const
|
||||
{
|
||||
return ((_l != b._l) || (memcmp(_b, b._b, _l)));
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator<(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator<(const Buffer<C2>& b) const
|
||||
{
|
||||
return (memcmp(_b, b._b, std::min(_l, b._l)) < 0);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator>(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator>(const Buffer<C2>& b) const
|
||||
{
|
||||
return (b < *this);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator<=(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator<=(const Buffer<C2>& b) const
|
||||
{
|
||||
return ! (b < *this);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator>=(const Buffer<C2> &b) const
|
||||
template <unsigned int C2> inline bool operator>=(const Buffer<C2>& b) const
|
||||
{
|
||||
return ! (*this < b);
|
||||
}
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
/****/
|
||||
|
||||
#include "Capability.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
#include "Identity.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -37,10 +38,12 @@ int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const
|
|||
if ((! _custody[c].to) || (! _custody[c].from) || (_custody[c].from != Network::controllerFor(_nwid))) {
|
||||
return -1; // the first entry must be present and from the network's controller
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (! _custody[c].to) {
|
||||
return 0; // all previous entries were valid, so we are valid
|
||||
} else if ((!_custody[c].from)||(_custody[c].from != _custody[c-1].to)) {
|
||||
}
|
||||
else if ((! _custody[c].from) || (_custody[c].from != _custody[c - 1].to)) {
|
||||
return -1; // otherwise if we have another entry it must be from the previous holder in the chain
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +53,8 @@ int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const
|
|||
if (! id.verify(tmp.data(), tmp.size(), _custody[c].signature)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->sw->requestWhois(tPtr, RR->node->now(), _custody[c].from);
|
||||
return 1;
|
||||
}
|
||||
|
@ -58,7 +62,9 @@ int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const
|
|||
|
||||
// We reached max custody chain length and everything was valid
|
||||
return 0;
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
#ifndef ZT_CAPABILITY_HPP
|
||||
#define ZT_CAPABILITY_HPP
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
@ -54,17 +54,14 @@ class RuntimeEnvironment;
|
|||
* handed off between nodes. Limited transferability of capabilities is
|
||||
* a feature of true capability based security.
|
||||
*/
|
||||
class Capability : public Credential
|
||||
{
|
||||
class Capability : public Credential {
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
|
||||
static inline Credential::Type credentialType()
|
||||
{
|
||||
return Credential::CREDENTIAL_TYPE_CAPABILITY;
|
||||
}
|
||||
|
||||
Capability() :
|
||||
_nwid(0),
|
||||
_ts(0),
|
||||
_id(0),
|
||||
_maxCustodyChainLength(0),
|
||||
_ruleCount(0)
|
||||
Capability() : _nwid(0), _ts(0), _id(0), _maxCustodyChainLength(0), _ruleCount(0)
|
||||
{
|
||||
memset(_rules, 0, sizeof(_rules));
|
||||
memset(_custody, 0, sizeof(_custody));
|
||||
|
@ -78,12 +75,12 @@ public:
|
|||
* @param rules Network flow rules for this capability
|
||||
* @param ruleCount Number of flow rules
|
||||
*/
|
||||
Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) :
|
||||
_nwid(nwid),
|
||||
_ts(ts),
|
||||
_id(id),
|
||||
_maxCustodyChainLength((mccl > 0) ? ((mccl < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) ? mccl : (unsigned int)ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) : 1),
|
||||
_ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES)
|
||||
Capability(uint32_t id, uint64_t nwid, int64_t ts, unsigned int mccl, const ZT_VirtualNetworkRule* rules, unsigned int ruleCount)
|
||||
: _nwid(nwid)
|
||||
, _ts(ts)
|
||||
, _id(id)
|
||||
, _maxCustodyChainLength((mccl > 0) ? ((mccl < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) ? mccl : (unsigned int)ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) : 1)
|
||||
, _ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES)
|
||||
{
|
||||
if (_ruleCount > 0) {
|
||||
memcpy(_rules, rules, sizeof(ZT_VirtualNetworkRule) * _ruleCount);
|
||||
|
@ -93,27 +90,42 @@ public:
|
|||
/**
|
||||
* @return Rules -- see ruleCount() for size of array
|
||||
*/
|
||||
inline const ZT_VirtualNetworkRule *rules() const { return _rules; }
|
||||
inline const ZT_VirtualNetworkRule* rules() const
|
||||
{
|
||||
return _rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Number of rules in rules()
|
||||
*/
|
||||
inline unsigned int ruleCount() const { return _ruleCount; }
|
||||
inline unsigned int ruleCount() const
|
||||
{
|
||||
return _ruleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID and evaluation order of this capability in network
|
||||
*/
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline uint32_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Network ID for which this capability was issued
|
||||
*/
|
||||
inline uint64_t networkId() const { return _nwid; }
|
||||
inline uint64_t networkId() const
|
||||
{
|
||||
return _nwid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Timestamp
|
||||
*/
|
||||
inline int64_t timestamp() const { return _ts; }
|
||||
inline int64_t timestamp() const
|
||||
{
|
||||
return _ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last 'to' address in chain of custody
|
||||
|
@ -124,7 +136,8 @@ public:
|
|||
for (unsigned int i = 0; i < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH; ++i) {
|
||||
if (! _custody[i].to) {
|
||||
return i2;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
i2 = _custody[i].to;
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +170,9 @@ public:
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -169,8 +184,7 @@ public:
|
|||
*/
|
||||
int verify(const RuntimeEnvironment* RR, void* tPtr) const;
|
||||
|
||||
template<unsigned int C>
|
||||
static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount)
|
||||
template <unsigned int C> static inline void serializeRules(Buffer<C>& b, const ZT_VirtualNetworkRule* rules, unsigned int ruleCount)
|
||||
{
|
||||
for (unsigned int i = 0; i < ruleCount; ++i) {
|
||||
// Each rule consists of its 8-bit type followed by the size of that type's
|
||||
|
@ -284,8 +298,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
static inline void deserializeRules(const Buffer<C> &b,unsigned int &p,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,const unsigned int maxRuleCount)
|
||||
template <unsigned int C> static inline void deserializeRules(const Buffer<C>& b, unsigned int& p, ZT_VirtualNetworkRule* rules, unsigned int& ruleCount, const unsigned int maxRuleCount)
|
||||
{
|
||||
while ((ruleCount < maxRuleCount) && (p < b.size())) {
|
||||
rules[ruleCount].t = (uint8_t)b[p++];
|
||||
|
@ -380,8 +393,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, const bool forSign = false) const
|
||||
{
|
||||
if (forSign) {
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
@ -404,7 +416,8 @@ public:
|
|||
b.append((uint8_t)1); // 1 == Ed25519 signature
|
||||
b.append((uint16_t)ZT_ECC_SIGNATURE_LEN); // length of signature
|
||||
b.append(_custody[i].signature.data, ZT_ECC_SIGNATURE_LEN);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
b.append((unsigned char)0, ZT_ADDRESS_LENGTH); // zero 'to' terminates chain
|
||||
break;
|
||||
}
|
||||
|
@ -419,8 +432,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
*this = Capability();
|
||||
|
||||
|
@ -464,7 +476,8 @@ public:
|
|||
p += 2;
|
||||
memcpy(_custody[i].signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN);
|
||||
p += ZT_ECC_SIGNATURE_LEN;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p += 2 + b.template at<uint16_t>(p);
|
||||
}
|
||||
}
|
||||
|
@ -478,10 +491,19 @@ public:
|
|||
}
|
||||
|
||||
// Provides natural sort order by ID
|
||||
inline bool operator<(const Capability &c) const { return (_id < c._id); }
|
||||
inline bool operator<(const Capability& c) const
|
||||
{
|
||||
return (_id < c._id);
|
||||
}
|
||||
|
||||
inline bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
|
||||
inline bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
|
||||
inline bool operator==(const Capability& c) const
|
||||
{
|
||||
return (memcmp(this, &c, sizeof(Capability)) == 0);
|
||||
}
|
||||
inline bool operator!=(const Capability& c) const
|
||||
{
|
||||
return (memcmp(this, &c, sizeof(Capability)) != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _nwid;
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
/****/
|
||||
|
||||
#include "CertificateOfMembership.hpp"
|
||||
|
||||
#include "ECC.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -108,7 +109,8 @@ bool CertificateOfMembership::sign(const Identity &with)
|
|||
_signature = with.sign(buf, ptr * sizeof(uint64_t));
|
||||
_signedBy = with.address();
|
||||
return true;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
_signedBy.zero();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,21 +14,20 @@
|
|||
#ifndef ZT_CERTIFICATEOFMEMBERSHIP_HPP
|
||||
#define ZT_CERTIFICATEOFMEMBERSHIP_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Maximum number of qualifiers allowed in a COM (absolute max: 65535)
|
||||
*/
|
||||
|
@ -64,10 +63,12 @@ class RuntimeEnvironment;
|
|||
* This is a memcpy()'able structure and is safe (in a crash sense) to modify
|
||||
* without locks.
|
||||
*/
|
||||
class CertificateOfMembership : public Credential
|
||||
{
|
||||
class CertificateOfMembership : public Credential {
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; }
|
||||
static inline Credential::Type credentialType()
|
||||
{
|
||||
return Credential::CREDENTIAL_TYPE_COM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserved qualifier IDs
|
||||
|
@ -78,8 +79,7 @@ public:
|
|||
* Addition of new required fields requires that code in hasRequiredFields
|
||||
* be updated as well.
|
||||
*/
|
||||
enum ReservedId
|
||||
{
|
||||
enum ReservedId {
|
||||
/**
|
||||
* Timestamp of certificate
|
||||
*/
|
||||
|
@ -101,8 +101,9 @@ public:
|
|||
/**
|
||||
* Create an empty certificate of membership
|
||||
*/
|
||||
CertificateOfMembership() :
|
||||
_qualifierCount(0) {}
|
||||
CertificateOfMembership() : _qualifierCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from required fields common to all networks
|
||||
|
@ -120,8 +121,7 @@ public:
|
|||
* @param b Buffer to deserialize from
|
||||
* @param startAt Position to start in buffer
|
||||
*/
|
||||
template<unsigned int C>
|
||||
CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> CertificateOfMembership(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
deserialize(b, startAt);
|
||||
}
|
||||
|
@ -129,12 +129,18 @@ public:
|
|||
/**
|
||||
* @return True if there's something here
|
||||
*/
|
||||
inline operator bool() const { return (_qualifierCount != 0); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_qualifierCount != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Credential ID, always 0 for COMs
|
||||
*/
|
||||
inline uint32_t id() const { return 0; }
|
||||
inline uint32_t id() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Timestamp for this cert and maximum delta for timestamp
|
||||
|
@ -211,15 +217,20 @@ public:
|
|||
/**
|
||||
* @return True if signed
|
||||
*/
|
||||
inline bool isSigned() const { return (_signedBy); }
|
||||
inline bool isSigned() const
|
||||
{
|
||||
return (_signedBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Address that signed this certificate or null address if none
|
||||
*/
|
||||
inline const Address &signedBy() const { return _signedBy; }
|
||||
inline const Address& signedBy() const
|
||||
{
|
||||
return _signedBy;
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b) const
|
||||
{
|
||||
b.append((uint8_t)1);
|
||||
b.append((uint16_t)_qualifierCount);
|
||||
|
@ -234,8 +245,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
|
||||
|
@ -253,7 +263,8 @@ public:
|
|||
const uint64_t qid = b.template at<uint64_t>(p);
|
||||
if (qid < lastId) {
|
||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
lastId = qid;
|
||||
}
|
||||
if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) {
|
||||
|
@ -262,7 +273,8 @@ public:
|
|||
_qualifiers[_qualifierCount].maxDelta = b.template at<uint64_t>(p + 16);
|
||||
p += 24;
|
||||
++_qualifierCount;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
@ -295,16 +307,23 @@ public:
|
|||
}
|
||||
return (memcmp(_signature.data, c._signature.data, ZT_ECC_SIGNATURE_LEN) == 0);
|
||||
}
|
||||
inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
|
||||
inline bool operator!=(const CertificateOfMembership& c) const
|
||||
{
|
||||
return (! (*this == c));
|
||||
}
|
||||
|
||||
private:
|
||||
struct _Qualifier
|
||||
struct _Qualifier {
|
||||
_Qualifier() : id(0), value(0), maxDelta(0)
|
||||
{
|
||||
_Qualifier() : id(0),value(0),maxDelta(0) {}
|
||||
}
|
||||
uint64_t id;
|
||||
uint64_t value;
|
||||
uint64_t maxDelta;
|
||||
inline bool operator<(const _Qualifier &q) const { return (id < q.id); } // sort order
|
||||
inline bool operator<(const _Qualifier& q) const
|
||||
{
|
||||
return (id < q.id);
|
||||
} // sort order
|
||||
};
|
||||
|
||||
Address _signedBy;
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
/****/
|
||||
|
||||
#include "CertificateOfOwnership.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
#include "Identity.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -35,7 +36,8 @@ int CertificateOfOwnership::verify(const RuntimeEnvironment *RR,void *tPtr) cons
|
|||
Buffer<(sizeof(CertificateOfOwnership) + 64)> tmp;
|
||||
this->serialize(tmp, true);
|
||||
return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,20 @@
|
|||
#ifndef ZT_CERTIFICATEOFOWNERSHIP_HPP
|
||||
#define ZT_CERTIFICATEOFOWNERSHIP_HPP
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
|
||||
// Max things per CertificateOfOwnership
|
||||
#define ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS 16
|
||||
|
||||
|
@ -41,18 +41,14 @@ class RuntimeEnvironment;
|
|||
/**
|
||||
* Certificate indicating ownership of a network identifier
|
||||
*/
|
||||
class CertificateOfOwnership : public Credential
|
||||
{
|
||||
class CertificateOfOwnership : public Credential {
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; }
|
||||
|
||||
enum Thing
|
||||
static inline Credential::Type credentialType()
|
||||
{
|
||||
THING_NULL = 0,
|
||||
THING_MAC_ADDRESS = 1,
|
||||
THING_IPV4_ADDRESS = 2,
|
||||
THING_IPV6_ADDRESS = 3
|
||||
};
|
||||
return Credential::CREDENTIAL_TYPE_COO;
|
||||
}
|
||||
|
||||
enum Thing { THING_NULL = 0, THING_MAC_ADDRESS = 1, THING_IPV4_ADDRESS = 2, THING_IPV6_ADDRESS = 3 };
|
||||
|
||||
CertificateOfOwnership()
|
||||
{
|
||||
|
@ -68,15 +64,36 @@ public:
|
|||
_issuedTo = issuedTo;
|
||||
}
|
||||
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline int64_t timestamp() const { return _ts; }
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline unsigned int thingCount() const { return (unsigned int)_thingCount; }
|
||||
inline uint64_t networkId() const
|
||||
{
|
||||
return _networkId;
|
||||
}
|
||||
inline int64_t timestamp() const
|
||||
{
|
||||
return _ts;
|
||||
}
|
||||
inline uint32_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
inline unsigned int thingCount() const
|
||||
{
|
||||
return (unsigned int)_thingCount;
|
||||
}
|
||||
|
||||
inline Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; }
|
||||
inline const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; }
|
||||
inline Thing thingType(const unsigned int i) const
|
||||
{
|
||||
return (Thing)_thingTypes[i];
|
||||
}
|
||||
inline const uint8_t* thingValue(const unsigned int i) const
|
||||
{
|
||||
return _thingValues[i];
|
||||
}
|
||||
|
||||
inline const Address &issuedTo() const { return _issuedTo; }
|
||||
inline const Address& issuedTo() const
|
||||
{
|
||||
return _issuedTo;
|
||||
}
|
||||
|
||||
inline bool owns(const InetAddress& ip) const
|
||||
{
|
||||
|
@ -105,7 +122,8 @@ public:
|
|||
_thingTypes[_thingCount] = THING_IPV4_ADDRESS;
|
||||
memcpy(_thingValues[_thingCount], &(reinterpret_cast<const struct sockaddr_in*>(&ip)->sin_addr.s_addr), 4);
|
||||
++_thingCount;
|
||||
} else if (ip.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (ip.ss_family == AF_INET6) {
|
||||
_thingTypes[_thingCount] = THING_IPV6_ADDRESS;
|
||||
memcpy(_thingValues[_thingCount], reinterpret_cast<const struct sockaddr_in6*>(&ip)->sin6_addr.s6_addr, 16);
|
||||
++_thingCount;
|
||||
|
@ -145,8 +163,7 @@ public:
|
|||
*/
|
||||
int verify(const RuntimeEnvironment* RR, void* tPtr) const;
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, const bool forSign = false) const
|
||||
{
|
||||
if (forSign) {
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
@ -177,8 +194,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
|
||||
|
@ -213,7 +229,8 @@ public:
|
|||
p += 2;
|
||||
memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN);
|
||||
p += ZT_ECC_SIGNATURE_LEN;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p += 2 + b.template at<uint16_t>(p);
|
||||
}
|
||||
|
||||
|
@ -226,10 +243,19 @@ public:
|
|||
}
|
||||
|
||||
// Provides natural sort order by ID
|
||||
inline bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); }
|
||||
inline bool operator<(const CertificateOfOwnership& coo) const
|
||||
{
|
||||
return (_id < coo._id);
|
||||
}
|
||||
|
||||
inline bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); }
|
||||
inline bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); }
|
||||
inline bool operator==(const CertificateOfOwnership& coo) const
|
||||
{
|
||||
return (memcmp(this, &coo, sizeof(CertificateOfOwnership)) == 0);
|
||||
}
|
||||
inline bool operator!=(const CertificateOfOwnership& coo) const
|
||||
{
|
||||
return (memcmp(this, &coo, sizeof(CertificateOfOwnership)) != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _owns(const Thing& t, const void* v, unsigned int l) const;
|
||||
|
|
|
@ -106,8 +106,8 @@
|
|||
#pragma warning(disable : 4101)
|
||||
#undef __UNIX_LIKE__
|
||||
#undef __BSD__
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef __NetBSD__
|
||||
|
@ -118,9 +118,9 @@
|
|||
|
||||
#if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
|
||||
#define ZT_ARCH_X64 1
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <immintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON))
|
||||
|
@ -145,7 +145,8 @@
|
|||
#endif
|
||||
|
||||
// Define ZT_NO_TYPE_PUNNING to disable reckless casts on anything other than x86/x64.
|
||||
#if (!(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
|
||||
#if (! (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) \
|
||||
|| defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
|
||||
#ifndef ZT_NO_TYPE_PUNNING
|
||||
#define ZT_NO_TYPE_PUNNING 1
|
||||
#endif
|
||||
|
@ -632,7 +633,6 @@
|
|||
*/
|
||||
#define ZT_PEER_GENERAL_RATE_LIMIT 1000
|
||||
|
||||
|
||||
/**
|
||||
* Minimum allowed amount of time between flow/path optimizations (anti-flapping)
|
||||
*/
|
||||
|
|
|
@ -19,14 +19,12 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Base class for credentials
|
||||
*/
|
||||
class Credential
|
||||
{
|
||||
class Credential {
|
||||
public:
|
||||
/**
|
||||
* Do not change type code IDs -- these are used in Revocation objects and elsewhere
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
enum Type {
|
||||
CREDENTIAL_TYPE_NULL = 0,
|
||||
CREDENTIAL_TYPE_COM = 1, // CertificateOfMembership
|
||||
CREDENTIAL_TYPE_CAPABILITY = 2,
|
||||
|
|
16
node/DNS.hpp
16
node/DNS.hpp
|
@ -13,14 +13,14 @@
|
|||
|
||||
#ifndef ZT_DNS_HPP
|
||||
#define ZT_DNS_HPP
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Buffer.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
|
@ -28,8 +28,7 @@ namespace ZeroTier {
|
|||
*/
|
||||
class DNS {
|
||||
public:
|
||||
template<unsigned int C>
|
||||
static inline void serializeDNS(Buffer<C> &b, const ZT_VirtualNetworkDNS *dns)
|
||||
template <unsigned int C> static inline void serializeDNS(Buffer<C>& b, const ZT_VirtualNetworkDNS* dns)
|
||||
{
|
||||
b.append(dns->domain, 128);
|
||||
for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) {
|
||||
|
@ -38,8 +37,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
static inline void deserializeDNS(const Buffer<C> &b, unsigned int &p, ZT_VirtualNetworkDNS *dns)
|
||||
template <unsigned int C> static inline void deserializeDNS(const Buffer<C>& b, unsigned int& p, ZT_VirtualNetworkDNS* dns)
|
||||
{
|
||||
char* d = (char*)b.data() + p;
|
||||
memset(dns, 0, sizeof(ZT_VirtualNetworkDNS));
|
||||
|
@ -52,6 +50,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // ZT_DNS_HPP
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#ifndef ZT_DICTIONARY_HPP
|
||||
#define ZT_DICTIONARY_HPP
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Address.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -45,28 +45,37 @@ namespace ZeroTier {
|
|||
*
|
||||
* @tparam C Dictionary max capacity in bytes
|
||||
*/
|
||||
template<unsigned int C>
|
||||
class Dictionary
|
||||
{
|
||||
template <unsigned int C> class Dictionary {
|
||||
public:
|
||||
Dictionary() { memset(_d,0,sizeof(_d)); }
|
||||
Dictionary(const char *s) { this->load(s); }
|
||||
Dictionary()
|
||||
{
|
||||
memset(_d, 0, sizeof(_d));
|
||||
}
|
||||
Dictionary(const char* s)
|
||||
{
|
||||
this->load(s);
|
||||
}
|
||||
Dictionary(const char* s, unsigned int len)
|
||||
{
|
||||
for (unsigned int i = 0; i < C; ++i) {
|
||||
if ((s) && (i < len)) {
|
||||
if (! (_d[i] = *s)) {
|
||||
s = (const char*)0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++s;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_d[i] = (char)0;
|
||||
}
|
||||
}
|
||||
_d[C - 1] = (char)0;
|
||||
}
|
||||
Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
|
||||
Dictionary(const Dictionary& d)
|
||||
{
|
||||
memcpy(_d, d._d, C);
|
||||
}
|
||||
|
||||
inline Dictionary& operator=(const Dictionary& d)
|
||||
{
|
||||
|
@ -74,7 +83,10 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline operator bool() const { return (_d[0] != 0); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_d[0] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a dictionary from a C-string
|
||||
|
@ -88,10 +100,12 @@ public:
|
|||
if (s) {
|
||||
if (! (_d[i] = *s)) {
|
||||
s = (const char*)0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++s;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_d[i] = (char)0;
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +209,11 @@ public:
|
|||
dest[j - 1] = (char)0;
|
||||
return j - 1;
|
||||
}
|
||||
} else if (*p == '\\') {
|
||||
}
|
||||
else if (*p == '\\') {
|
||||
esc = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dest[j++] = *p;
|
||||
if (j == (int)destlen) {
|
||||
dest[j - 1] = (char)0;
|
||||
|
@ -211,7 +227,8 @@ public:
|
|||
}
|
||||
dest[j] = (char)0;
|
||||
return j;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
while ((*p) && (*p != 13) && (*p != 10)) {
|
||||
if (++p == eof) {
|
||||
dest[0] = (char)0;
|
||||
|
@ -223,7 +240,8 @@ public:
|
|||
dest[0] = (char)0;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -241,14 +259,14 @@ public:
|
|||
* @return True if key was found (if false, dest will be empty)
|
||||
* @tparam BC Buffer capacity (usually inferred)
|
||||
*/
|
||||
template<unsigned int BC>
|
||||
inline bool get(const char *key,Buffer<BC> &dest) const
|
||||
template <unsigned int BC> inline bool get(const char* key, Buffer<BC>& dest) const
|
||||
{
|
||||
const int r = this->get(key, const_cast<char*>(reinterpret_cast<const char*>(dest.data())), BC);
|
||||
if (r >= 0) {
|
||||
dest.setSize((unsigned int)r);
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dest.clear();
|
||||
return false;
|
||||
}
|
||||
|
@ -426,7 +444,8 @@ public:
|
|||
char tmp[32];
|
||||
if (value >= 0) {
|
||||
return this->add(key, Utils::hex((uint64_t)value, tmp), -1);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
tmp[0] = '-';
|
||||
return this->add(key, Utils::hex((uint64_t)(value * -1), tmp + 1), -1);
|
||||
}
|
||||
|
@ -446,8 +465,7 @@ public:
|
|||
*
|
||||
* @tparam BC Buffer capacity (usually inferred)
|
||||
*/
|
||||
template<unsigned int BC>
|
||||
inline bool add(const char *key,const Buffer<BC> &value)
|
||||
template <unsigned int BC> inline bool add(const char* key, const Buffer<BC>& value)
|
||||
{
|
||||
return this->add(key, (const char*)value.data(), (int)value.size());
|
||||
}
|
||||
|
@ -465,10 +483,19 @@ public:
|
|||
/**
|
||||
* @return Value of C template parameter
|
||||
*/
|
||||
inline unsigned int capacity() const { return C; }
|
||||
inline unsigned int capacity() const
|
||||
{
|
||||
return C;
|
||||
}
|
||||
|
||||
inline const char *data() const { return _d; }
|
||||
inline char *unsafeData() { return _d; }
|
||||
inline const char* data() const
|
||||
{
|
||||
return _d;
|
||||
}
|
||||
inline char* unsafeData()
|
||||
{
|
||||
return _d;
|
||||
}
|
||||
|
||||
private:
|
||||
char _d[C];
|
||||
|
|
444
node/ECC.cpp
444
node/ECC.cpp
|
@ -7,12 +7,13 @@ Derived from public domain code by D. J. Bernstein.
|
|||
// Modified very slightly for ZeroTier One by Adam Ierymenko
|
||||
// This code remains in the public domain.
|
||||
|
||||
#include "ECC.hpp"
|
||||
|
||||
#include "SHA512.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ECC.hpp"
|
||||
#include "SHA512.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#pragma warning(disable : 4146)
|
||||
#endif
|
||||
|
@ -36,7 +37,8 @@ typedef uint8_t u8;
|
|||
typedef int32_t s32;
|
||||
typedef int64_t limb;
|
||||
|
||||
static inline void fsum(limb *output, const limb *in) {
|
||||
static inline void fsum(limb* output, const limb* in)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
output[0 + i] = output[0 + i] + in[0 + i];
|
||||
|
@ -44,124 +46,56 @@ static inline void fsum(limb *output, const limb *in) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void fdifference(limb *output, const limb *in) {
|
||||
static inline void fdifference(limb* output, const limb* in)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] - output[i];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
||||
static inline void fscalar_product(limb* output, const limb* in, const limb scalar)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fproduct(limb *output, const limb *in2, const limb *in) {
|
||||
static inline void fproduct(limb* output, const limb* in2, const limb* in)
|
||||
{
|
||||
output[0] = ((limb)((s32)in2[0])) * ((s32)in[0]);
|
||||
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
||||
output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[0]);
|
||||
output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[0]);
|
||||
output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
|
||||
2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[0]);
|
||||
output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[0]);
|
||||
output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[0]);
|
||||
output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[0]);
|
||||
output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[0]);
|
||||
output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[0]);
|
||||
output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[2]);
|
||||
output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[2]);
|
||||
output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[3])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[4]);
|
||||
output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[4]);
|
||||
output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[5])) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[6]);
|
||||
output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[6]);
|
||||
output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[7]));
|
||||
output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[8]);
|
||||
output[1] = ((limb)((s32)in2[0])) * ((s32)in[1]) + ((limb)((s32)in2[1])) * ((s32)in[0]);
|
||||
output[2] = 2 * ((limb)((s32)in2[1])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[2]) + ((limb)((s32)in2[2])) * ((s32)in[0]);
|
||||
output[3] = ((limb)((s32)in2[1])) * ((s32)in[2]) + ((limb)((s32)in2[2])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[0]);
|
||||
output[4] = ((limb)((s32)in2[2])) * ((s32)in[2]) + 2 * (((limb)((s32)in2[1])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[1])) + ((limb)((s32)in2[0])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[0]);
|
||||
output[5] =
|
||||
((limb)((s32)in2[2])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[0]);
|
||||
output[6] = 2 * (((limb)((s32)in2[3])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[1])) + ((limb)((s32)in2[2])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[2])
|
||||
+ ((limb)((s32)in2[0])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[0]);
|
||||
output[7] = ((limb)((s32)in2[3])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[6])
|
||||
+ ((limb)((s32)in2[6])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[0]);
|
||||
output[8] = ((limb)((s32)in2[4])) * ((s32)in[4]) + 2 * (((limb)((s32)in2[3])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[1]))
|
||||
+ ((limb)((s32)in2[2])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[2]) + ((limb)((s32)in2[0])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[0]);
|
||||
output[9] = ((limb)((s32)in2[4])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[4]) + ((limb)((s32)in2[3])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[7])
|
||||
+ ((limb)((s32)in2[7])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[0]);
|
||||
output[10] = 2 * (((limb)((s32)in2[5])) * ((s32)in[5]) + ((limb)((s32)in2[3])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[1]))
|
||||
+ ((limb)((s32)in2[4])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[4]) + ((limb)((s32)in2[2])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[2]);
|
||||
output[11] = ((limb)((s32)in2[5])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[5]) + ((limb)((s32)in2[4])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[4]) + ((limb)((s32)in2[3])) * ((s32)in[8])
|
||||
+ ((limb)((s32)in2[8])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[2]);
|
||||
output[12] = ((limb)((s32)in2[6])) * ((s32)in[6]) + 2 * (((limb)((s32)in2[5])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[5]) + ((limb)((s32)in2[3])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[3]))
|
||||
+ ((limb)((s32)in2[4])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[4]);
|
||||
output[13] =
|
||||
((limb)((s32)in2[6])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[6]) + ((limb)((s32)in2[5])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[5]) + ((limb)((s32)in2[4])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[4]);
|
||||
output[14] = 2 * (((limb)((s32)in2[7])) * ((s32)in[7]) + ((limb)((s32)in2[5])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[5])) + ((limb)((s32)in2[6])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[6]);
|
||||
output[15] = ((limb)((s32)in2[7])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[7]) + ((limb)((s32)in2[6])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[6]);
|
||||
output[16] = ((limb)((s32)in2[8])) * ((s32)in[8]) + 2 * (((limb)((s32)in2[7])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[7]));
|
||||
output[17] = ((limb)((s32)in2[8])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[8]);
|
||||
output[18] = 2 * ((limb)((s32)in2[9])) * ((s32)in[9]);
|
||||
}
|
||||
|
||||
static inline void freduce_degree(limb *output) {
|
||||
static inline void freduce_degree(limb* output)
|
||||
{
|
||||
output[8] += output[18] << 4;
|
||||
output[8] += output[18] << 1;
|
||||
output[8] += output[18];
|
||||
|
@ -219,7 +153,8 @@ static inline limb div_by_2_25(const limb v)
|
|||
return (v + roundoff) >> 25;
|
||||
}
|
||||
|
||||
static inline void freduce_coefficients(limb *output) {
|
||||
static inline void freduce_coefficients(limb* output)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
output[10] = 0;
|
||||
|
@ -262,7 +197,8 @@ static inline void freduce_coefficients(limb *output) {
|
|||
* bound on |output[1]| is sufficient to meet our needs. */
|
||||
}
|
||||
|
||||
static inline void fmul(limb *output, const limb *in, const limb *in2) {
|
||||
static inline void fmul(limb* output, const limb* in, const limb* in2)
|
||||
{
|
||||
limb t[19];
|
||||
fproduct(t, in, in2);
|
||||
/* |t[i]| < 14*2^54 */
|
||||
|
@ -272,65 +208,31 @@ static inline void fmul(limb *output, const limb *in, const limb *in2) {
|
|||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
static inline void fsquare_inner(limb *output, const limb *in) {
|
||||
static inline void fsquare_inner(limb* output, const limb* in)
|
||||
{
|
||||
output[0] = ((limb)((s32)in[0])) * ((s32)in[0]);
|
||||
output[1] = 2 * ((limb)((s32)in[0])) * ((s32)in[1]);
|
||||
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[2]));
|
||||
output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[3]));
|
||||
output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
|
||||
4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
|
||||
2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
|
||||
output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[5]));
|
||||
output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[6]) +
|
||||
2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
|
||||
output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[7]));
|
||||
output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[5])));
|
||||
output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[9]));
|
||||
output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[9])));
|
||||
output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[9]));
|
||||
output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[9])));
|
||||
output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[9]));
|
||||
output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[8]) +
|
||||
2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
|
||||
output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[9]));
|
||||
output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
|
||||
4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
|
||||
output[2] = 2 * (((limb)((s32)in[1])) * ((s32)in[1]) + ((limb)((s32)in[0])) * ((s32)in[2]));
|
||||
output[3] = 2 * (((limb)((s32)in[1])) * ((s32)in[2]) + ((limb)((s32)in[0])) * ((s32)in[3]));
|
||||
output[4] = ((limb)((s32)in[2])) * ((s32)in[2]) + 4 * ((limb)((s32)in[1])) * ((s32)in[3]) + 2 * ((limb)((s32)in[0])) * ((s32)in[4]);
|
||||
output[5] = 2 * (((limb)((s32)in[2])) * ((s32)in[3]) + ((limb)((s32)in[1])) * ((s32)in[4]) + ((limb)((s32)in[0])) * ((s32)in[5]));
|
||||
output[6] = 2 * (((limb)((s32)in[3])) * ((s32)in[3]) + ((limb)((s32)in[2])) * ((s32)in[4]) + ((limb)((s32)in[0])) * ((s32)in[6]) + 2 * ((limb)((s32)in[1])) * ((s32)in[5]));
|
||||
output[7] = 2 * (((limb)((s32)in[3])) * ((s32)in[4]) + ((limb)((s32)in[2])) * ((s32)in[5]) + ((limb)((s32)in[1])) * ((s32)in[6]) + ((limb)((s32)in[0])) * ((s32)in[7]));
|
||||
output[8] = ((limb)((s32)in[4])) * ((s32)in[4]) + 2 * (((limb)((s32)in[2])) * ((s32)in[6]) + ((limb)((s32)in[0])) * ((s32)in[8]) + 2 * (((limb)((s32)in[1])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[5])));
|
||||
output[9] = 2 * (((limb)((s32)in[4])) * ((s32)in[5]) + ((limb)((s32)in[3])) * ((s32)in[6]) + ((limb)((s32)in[2])) * ((s32)in[7]) + ((limb)((s32)in[1])) * ((s32)in[8]) + ((limb)((s32)in[0])) * ((s32)in[9]));
|
||||
output[10] = 2 * (((limb)((s32)in[5])) * ((s32)in[5]) + ((limb)((s32)in[4])) * ((s32)in[6]) + ((limb)((s32)in[2])) * ((s32)in[8]) + 2 * (((limb)((s32)in[3])) * ((s32)in[7]) + ((limb)((s32)in[1])) * ((s32)in[9])));
|
||||
output[11] = 2 * (((limb)((s32)in[5])) * ((s32)in[6]) + ((limb)((s32)in[4])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[8]) + ((limb)((s32)in[2])) * ((s32)in[9]));
|
||||
output[12] = ((limb)((s32)in[6])) * ((s32)in[6]) + 2 * (((limb)((s32)in[4])) * ((s32)in[8]) + 2 * (((limb)((s32)in[5])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[9])));
|
||||
output[13] = 2 * (((limb)((s32)in[6])) * ((s32)in[7]) + ((limb)((s32)in[5])) * ((s32)in[8]) + ((limb)((s32)in[4])) * ((s32)in[9]));
|
||||
output[14] = 2 * (((limb)((s32)in[7])) * ((s32)in[7]) + ((limb)((s32)in[6])) * ((s32)in[8]) + 2 * ((limb)((s32)in[5])) * ((s32)in[9]));
|
||||
output[15] = 2 * (((limb)((s32)in[7])) * ((s32)in[8]) + ((limb)((s32)in[6])) * ((s32)in[9]));
|
||||
output[16] = ((limb)((s32)in[8])) * ((s32)in[8]) + 4 * ((limb)((s32)in[7])) * ((s32)in[9]);
|
||||
output[17] = 2 * ((limb)((s32)in[8])) * ((s32)in[9]);
|
||||
output[18] = 2 * ((limb)((s32)in[9])) * ((s32)in[9]);
|
||||
}
|
||||
|
||||
static void fsquare(limb *output, const limb *in) {
|
||||
static void fsquare(limb* output, const limb* in)
|
||||
{
|
||||
limb t[19];
|
||||
fsquare_inner(t, in);
|
||||
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
||||
|
@ -342,12 +244,9 @@ static void fsquare(limb *output, const limb *in) {
|
|||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
static inline void fexpand(limb *output, const u8 *input) {
|
||||
#define F(n,start,shift,mask) \
|
||||
output[n] = ((((limb) input[start + 0]) | \
|
||||
((limb) input[start + 1]) << 8 | \
|
||||
((limb) input[start + 2]) << 16 | \
|
||||
((limb) input[start + 3]) << 24) >> shift) & mask;
|
||||
static inline void fexpand(limb* output, const u8* input)
|
||||
{
|
||||
#define F(n, start, shift, mask) output[n] = ((((limb)input[start + 0]) | ((limb)input[start + 1]) << 8 | ((limb)input[start + 2]) << 16 | ((limb)input[start + 3]) << 24) >> shift) & mask;
|
||||
F(0, 0, 0, 0x3ffffff);
|
||||
F(1, 3, 2, 0x1ffffff);
|
||||
F(2, 6, 3, 0x3ffffff);
|
||||
|
@ -365,7 +264,8 @@ static inline void fexpand(limb *output, const u8 *input) {
|
|||
#error "This code only works when >> does sign-extension on negative numbers"
|
||||
#endif
|
||||
|
||||
static inline s32 s32_eq(s32 a, s32 b) {
|
||||
static inline s32 s32_eq(s32 a, s32 b)
|
||||
{
|
||||
a = ~(a ^ b);
|
||||
a &= a << 16;
|
||||
a &= a << 8;
|
||||
|
@ -375,13 +275,15 @@ static inline s32 s32_eq(s32 a, s32 b) {
|
|||
return a >> 31;
|
||||
}
|
||||
|
||||
static inline s32 s32_gte(s32 a, s32 b) {
|
||||
static inline s32 s32_gte(s32 a, s32 b)
|
||||
{
|
||||
a -= b;
|
||||
/* a >= 0 iff a >= b. */
|
||||
return ~(a >> 31);
|
||||
}
|
||||
|
||||
static inline void fcontract(u8 *output, limb *input_limbs) {
|
||||
static inline void fcontract(u8* output, limb* input_limbs)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
s32 input[10];
|
||||
|
@ -401,7 +303,8 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|||
const s32 carry = -((input[i] & mask) >> 25);
|
||||
input[i] = input[i] + (carry << 25);
|
||||
input[i + 1] = input[i + 1] - carry;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 26);
|
||||
input[i] = input[i] + (carry << 26);
|
||||
|
@ -450,7 +353,8 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|||
const s32 carry = input[i] >> 25;
|
||||
input[i] &= 0x1ffffff;
|
||||
input[i + 1] += carry;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const s32 carry = input[i] >> 26;
|
||||
input[i] &= 0x3ffffff;
|
||||
input[i + 1] += carry;
|
||||
|
@ -478,7 +382,8 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
mask &= s32_eq(input[i], 0x1ffffff);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mask &= s32_eq(input[i], 0x3ffffff);
|
||||
}
|
||||
}
|
||||
|
@ -490,7 +395,8 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
input[i] -= mask & 0x1ffffff;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
input[i] -= mask & 0x3ffffff;
|
||||
}
|
||||
}
|
||||
|
@ -523,13 +429,18 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|||
#undef F
|
||||
}
|
||||
|
||||
static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
|
||||
limb *x3, limb *z3, /* output Q + Q' */
|
||||
limb *x, limb *z, /* input Q */
|
||||
limb *xprime, limb *zprime, /* input Q' */
|
||||
const limb *qmqp /* input Q - Q' */) {
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
|
||||
zzprime[19], zzzprime[19], xxxprime[19];
|
||||
static inline void fmonty(
|
||||
limb* x2,
|
||||
limb* z2, /* output 2Q */
|
||||
limb* x3,
|
||||
limb* z3, /* output Q + Q' */
|
||||
limb* x,
|
||||
limb* z, /* input Q */
|
||||
limb* xprime,
|
||||
limb* zprime, /* input Q' */
|
||||
const limb* qmqp /* input Q - Q' */)
|
||||
{
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], zzprime[19], zzzprime[19], xxxprime[19];
|
||||
|
||||
memcpy(origx, x, 10 * sizeof(limb));
|
||||
fsum(x, z);
|
||||
|
@ -598,7 +509,8 @@ static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
|
|||
/* |z2|i| < 2^26 */
|
||||
}
|
||||
|
||||
static inline void swap_conditional(limb a[19], limb b[19], limb iswap) {
|
||||
static inline void swap_conditional(limb a[19], limb b[19], limb iswap)
|
||||
{
|
||||
unsigned i;
|
||||
const s32 swap = (s32)-iswap;
|
||||
|
||||
|
@ -609,7 +521,8 @@ static inline void swap_conditional(limb a[19], limb b[19], limb iswap) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
||||
static inline void cmult(limb* resultx, limb* resultz, const u8* n, const limb* q)
|
||||
{
|
||||
limb a[19] = { 0 }, b[19] = { 1 }, c[19] = { 1 }, d[19] = { 0 };
|
||||
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
||||
limb e[19] = { 0 }, f[19] = { 1 }, g[19] = { 0 }, h[19] = { 1 };
|
||||
|
@ -626,11 +539,7 @@ static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *
|
|||
|
||||
swap_conditional(nqx, nqpqx, bit);
|
||||
swap_conditional(nqz, nqpqz, bit);
|
||||
fmonty(nqx2, nqz2,
|
||||
nqpqx2, nqpqz2,
|
||||
nqx, nqz,
|
||||
nqpqx, nqpqz,
|
||||
q);
|
||||
fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q);
|
||||
swap_conditional(nqx2, nqpqx2, bit);
|
||||
swap_conditional(nqz2, nqpqz2, bit);
|
||||
|
||||
|
@ -655,7 +564,8 @@ static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *
|
|||
memcpy(resultz, nqz, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
static inline void crecip(limb *out, const limb *z) {
|
||||
static inline void crecip(limb* out, const limb* z)
|
||||
{
|
||||
limb z2[10];
|
||||
limb z9[10];
|
||||
limb z11[10];
|
||||
|
@ -685,32 +595,50 @@ static inline void crecip(limb *out, const limb *z) {
|
|||
|
||||
/* 2^11 - 2^1 */ fsquare(t0, z2_10_0);
|
||||
/* 2^12 - 2^2 */ fsquare(t1, t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) {
|
||||
fsquare(t0, t1);
|
||||
fsquare(t1, t0);
|
||||
}
|
||||
/* 2^20 - 2^0 */ fmul(z2_20_0, t1, z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fsquare(t0, z2_20_0);
|
||||
/* 2^22 - 2^2 */ fsquare(t1, t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) {
|
||||
fsquare(t0, t1);
|
||||
fsquare(t1, t0);
|
||||
}
|
||||
/* 2^40 - 2^0 */ fmul(t0, t1, z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fsquare(t1, t0);
|
||||
/* 2^42 - 2^2 */ fsquare(t0, t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) {
|
||||
fsquare(t1, t0);
|
||||
fsquare(t0, t1);
|
||||
}
|
||||
/* 2^50 - 2^0 */ fmul(z2_50_0, t0, z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fsquare(t0, z2_50_0);
|
||||
/* 2^52 - 2^2 */ fsquare(t1, t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) {
|
||||
fsquare(t0, t1);
|
||||
fsquare(t1, t0);
|
||||
}
|
||||
/* 2^100 - 2^0 */ fmul(z2_100_0, t1, z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fsquare(t1, z2_100_0);
|
||||
/* 2^102 - 2^2 */ fsquare(t0, t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) {
|
||||
fsquare(t1, t0);
|
||||
fsquare(t0, t1);
|
||||
}
|
||||
/* 2^200 - 2^0 */ fmul(t1, t0, z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fsquare(t0, t1);
|
||||
/* 2^202 - 2^2 */ fsquare(t1, t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) {
|
||||
fsquare(t0, t1);
|
||||
fsquare(t1, t0);
|
||||
}
|
||||
/* 2^250 - 2^0 */ fmul(t0, t1, z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fsquare(t1, t0);
|
||||
|
@ -721,7 +649,8 @@ static inline void crecip(limb *out, const limb *z) {
|
|||
/* 2^255 - 21 */ fmul(out, t1, z11);
|
||||
}
|
||||
|
||||
static void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
||||
static void crypto_scalarmult(u8* mypublic, const u8* secret, const u8* basepoint)
|
||||
{
|
||||
limb bp[10], x[10], z[11], zmone[10];
|
||||
uint8_t e[32];
|
||||
int i;
|
||||
|
@ -751,26 +680,19 @@ static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char *
|
|||
|
||||
// Ed25519 ref from: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
crypto_uint32 v[32];
|
||||
}
|
||||
fe25519;
|
||||
} fe25519;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
crypto_uint32 v[32];
|
||||
}
|
||||
sc25519;
|
||||
} sc25519;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
crypto_uint32 v[16];
|
||||
}
|
||||
shortsc25519;
|
||||
} shortsc25519;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
fe25519 z;
|
||||
|
@ -779,23 +701,20 @@ typedef struct
|
|||
|
||||
#define ge25519_p3 ge25519
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 z;
|
||||
fe25519 y;
|
||||
fe25519 t;
|
||||
} ge25519_p1p1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
fe25519 z;
|
||||
} ge25519_p2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
} ge25519_aff;
|
||||
|
@ -1046,32 +965,50 @@ static inline void fe25519_invert(fe25519 *r, const fe25519 *x)
|
|||
|
||||
/* 2^11 - 2^1 */ fe25519_square(&t0, &z2_10_0);
|
||||
/* 2^12 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
|
||||
/* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1, &t0);
|
||||
}
|
||||
/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t1, &z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fe25519_square(&t0, &z2_20_0);
|
||||
/* 2^22 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
|
||||
/* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1, &t0);
|
||||
}
|
||||
/* 2^40 - 2^0 */ fe25519_mul(&t0, &t1, &z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fe25519_square(&t1, &t0);
|
||||
/* 2^42 - 2^2 */ fe25519_square(&t0, &t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
|
||||
/* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) {
|
||||
fe25519_square(&t1, &t0);
|
||||
fe25519_square(&t0, &t1);
|
||||
}
|
||||
/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t0, &z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fe25519_square(&t0, &z2_50_0);
|
||||
/* 2^52 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
|
||||
/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1, &t0);
|
||||
}
|
||||
/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t1, &z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fe25519_square(&t1, &z2_100_0);
|
||||
/* 2^102 - 2^2 */ fe25519_square(&t0, &t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
|
||||
/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) {
|
||||
fe25519_square(&t1, &t0);
|
||||
fe25519_square(&t0, &t1);
|
||||
}
|
||||
/* 2^200 - 2^0 */ fe25519_mul(&t1, &t0, &z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fe25519_square(&t0, &t1);
|
||||
/* 2^202 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
|
||||
/* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1, &t0);
|
||||
}
|
||||
/* 2^250 - 2^0 */ fe25519_mul(&t0, &t1, &z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fe25519_square(&t1, &t0);
|
||||
|
@ -1350,24 +1287,17 @@ static inline void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1,
|
|||
}
|
||||
|
||||
/* d */
|
||||
static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
|
||||
0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};
|
||||
static const fe25519 ge25519_ecd = { { 0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52 } };
|
||||
/* 2*d */
|
||||
static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
|
||||
0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};
|
||||
static const fe25519 ge25519_ec2d = { { 0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24 } };
|
||||
/* sqrt(-1) */
|
||||
static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
|
||||
0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};
|
||||
static const fe25519 ge25519_sqrtm1 = { { 0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B } };
|
||||
|
||||
/* Packed coordinates of the base point */
|
||||
static const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
|
||||
0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
|
||||
{{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
|
||||
0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};
|
||||
static const ge25519 ge25519_base = { { { 0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21 } },
|
||||
{ { 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 } },
|
||||
{ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ { 0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67 } } };
|
||||
|
||||
/* Multiples of the base point in affine representation */
|
||||
static const ge25519_aff ge25519_base_multiples_affine[425] = {
|
||||
|
@ -2424,20 +2354,33 @@ static inline void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge2551
|
|||
/* precomputation s2 s1 */
|
||||
setneutral(pre); /* 00 00 */
|
||||
pre[1] = *p1; /* 00 01 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
|
||||
dbl_p1p1(&tp1p1, (ge25519_p2*)p1);
|
||||
p1p1_to_p3(&pre[2], &tp1p1); /* 00 10 */
|
||||
add_p1p1(&tp1p1, &pre[1], &pre[2]);
|
||||
p1p1_to_p3(&pre[3], &tp1p1); /* 00 11 */
|
||||
pre[4] = *p2; /* 01 00 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
|
||||
add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
|
||||
add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)pre5); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
|
||||
add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
|
||||
add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
|
||||
add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
|
||||
add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
|
||||
add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
|
||||
add_p1p1(&tp1p1, &pre[1], &pre[4]);
|
||||
p1p1_to_p3(&pre[5], &tp1p1); /* 01 01 */
|
||||
add_p1p1(&tp1p1, &pre[2], &pre[4]);
|
||||
p1p1_to_p3(&pre[6], &tp1p1); /* 01 10 */
|
||||
add_p1p1(&tp1p1, &pre[3], &pre[4]);
|
||||
p1p1_to_p3(&pre[7], &tp1p1); /* 01 11 */
|
||||
dbl_p1p1(&tp1p1, (ge25519_p2*)p2);
|
||||
p1p1_to_p3(&pre[8], &tp1p1); /* 10 00 */
|
||||
add_p1p1(&tp1p1, &pre[1], &pre[8]);
|
||||
p1p1_to_p3(&pre[9], &tp1p1); /* 10 01 */
|
||||
dbl_p1p1(&tp1p1, (ge25519_p2*)pre5);
|
||||
p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
|
||||
add_p1p1(&tp1p1, &pre[3], &pre[8]);
|
||||
p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
|
||||
add_p1p1(&tp1p1, &pre[4], &pre[8]);
|
||||
p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
|
||||
add_p1p1(&tp1p1, &pre[1], &pre[12]);
|
||||
p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
|
||||
add_p1p1(&tp1p1, &pre[2], &pre[12]);
|
||||
p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
|
||||
add_p1p1(&tp1p1, &pre[3], &pre[12]);
|
||||
p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
|
||||
|
||||
sc25519_2interleave2(b, s1, s2);
|
||||
|
||||
|
@ -2453,7 +2396,8 @@ static inline void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge2551
|
|||
}
|
||||
if (i != 0) {
|
||||
p1p1_to_p2((ge25519_p2*)r, &tp1p1);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p1p1_to_p3(r, &tp1p1);
|
||||
}
|
||||
}
|
||||
|
|
57
node/ECC.hpp
57
node/ECC.hpp
|
@ -29,24 +29,32 @@
|
|||
/* FIPS140/NIST ECC cryptography */
|
||||
/* Note that to be FIPS we also need to link against a FIPS-certified library. */
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#define ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN 97 /* Single ECC P-384 key */
|
||||
#define ZT_ECC_PUBLIC_KEY_SET_LEN (97 * 2) /* Two ECC P-384 keys */
|
||||
#define ZT_ECC_PRIVATE_KEY_SET_LEN (48 * 2) /* Two ECC P-384 secret keys */
|
||||
#define ZT_ECC_SIGNATURE_LEN 96 /* NIST P-384 ECDSA signature */
|
||||
|
||||
class ECC
|
||||
{
|
||||
class ECC {
|
||||
public:
|
||||
struct Public { uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; };
|
||||
struct Private { uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; };
|
||||
struct Signature { uint8_t data[ZT_ECC_SIGNATURE_LEN]; };
|
||||
struct Pair { Public pub; Private priv; };
|
||||
struct Public {
|
||||
uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN];
|
||||
};
|
||||
struct Private {
|
||||
uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN];
|
||||
};
|
||||
struct Signature {
|
||||
uint8_t data[ZT_ECC_SIGNATURE_LEN];
|
||||
};
|
||||
struct Pair {
|
||||
Public pub;
|
||||
Private priv;
|
||||
};
|
||||
};
|
||||
|
||||
#else // Curve25519 / Ed25519
|
||||
|
@ -58,13 +66,21 @@ namespace ZeroTier {
|
|||
#define ZT_ECC_PRIVATE_KEY_SET_LEN 64 /* C25519 and Ed25519 secret keys */
|
||||
#define ZT_ECC_SIGNATURE_LEN 96 /* Ed25519 signature plus (not necessary) hash */
|
||||
|
||||
class ECC
|
||||
{
|
||||
class ECC {
|
||||
public:
|
||||
struct Public { uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; };
|
||||
struct Private { uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; };
|
||||
struct Signature { uint8_t data[ZT_ECC_SIGNATURE_LEN]; };
|
||||
struct Pair { Public pub; Private priv; };
|
||||
struct Public {
|
||||
uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN];
|
||||
};
|
||||
struct Private {
|
||||
uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN];
|
||||
};
|
||||
struct Signature {
|
||||
uint8_t data[ZT_ECC_SIGNATURE_LEN];
|
||||
};
|
||||
struct Pair {
|
||||
Public pub;
|
||||
Private priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate an elliptic curve key pair
|
||||
|
@ -91,8 +107,7 @@ public:
|
|||
* @return Key pair where cond(kp) returns true
|
||||
* @tparam F Type of 'cond'
|
||||
*/
|
||||
template<typename F>
|
||||
static inline Pair generateSatisfying(F cond)
|
||||
template <typename F> static inline Pair generateSatisfying(F cond)
|
||||
{
|
||||
Pair kp;
|
||||
void* const priv = (void*)kp.priv.data;
|
||||
|
@ -118,7 +133,10 @@ public:
|
|||
* @param keylen Number of key bytes to generate
|
||||
*/
|
||||
static void agree(const Private& mine, const Public& their, void* keybuf, unsigned int keylen);
|
||||
static inline void agree(const Pair &mine,const Public &their,void *keybuf,unsigned int keylen) { agree(mine.priv,their,keybuf,keylen); }
|
||||
static inline void agree(const Pair& mine, const Public& their, void* keybuf, unsigned int keylen)
|
||||
{
|
||||
agree(mine.priv, their, keybuf, keylen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a message with a sender's key pair
|
||||
|
@ -140,7 +158,10 @@ public:
|
|||
* @param signature Buffer to fill with signature -- MUST be 96 bytes in length
|
||||
*/
|
||||
static void sign(const Private& myPrivate, const Public& myPublic, const void* msg, unsigned int len, void* signature);
|
||||
static inline void sign(const Pair &mine,const void *msg,unsigned int len,void *signature) { sign(mine.priv,mine.pub,msg,len,signature); }
|
||||
static inline void sign(const Pair& mine, const void* msg, unsigned int len, void* signature)
|
||||
{
|
||||
sign(mine.priv, mine.pub, msg, len, signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a message with a sender's key pair
|
||||
|
|
|
@ -16,30 +16,37 @@
|
|||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A minimal hash table implementation for the ZeroTier core
|
||||
*/
|
||||
template<typename K,typename V>
|
||||
class Hashtable
|
||||
{
|
||||
template <typename K, typename V> class Hashtable {
|
||||
private:
|
||||
struct _Bucket
|
||||
struct _Bucket {
|
||||
_Bucket(const K& k, const V& v) : k(k), v(v)
|
||||
{
|
||||
_Bucket(const K &k,const V &v) : k(k),v(v) {}
|
||||
_Bucket(const K &k) : k(k),v() {}
|
||||
_Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
|
||||
inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
|
||||
}
|
||||
_Bucket(const K& k) : k(k), v()
|
||||
{
|
||||
}
|
||||
_Bucket(const _Bucket& b) : k(b.k), v(b.v)
|
||||
{
|
||||
}
|
||||
inline _Bucket& operator=(const _Bucket& b)
|
||||
{
|
||||
k = b.k;
|
||||
v = b.v;
|
||||
return *this;
|
||||
}
|
||||
K k;
|
||||
V v;
|
||||
_Bucket* next; // must be set manually for each _Bucket
|
||||
|
@ -53,16 +60,12 @@ public:
|
|||
* may rehash and invalidate the iterator. Note the erasing the key will destroy
|
||||
* the targets of the pointers returned by next().
|
||||
*/
|
||||
class Iterator
|
||||
{
|
||||
class Iterator {
|
||||
public:
|
||||
/**
|
||||
* @param ht Hash table to iterate over
|
||||
*/
|
||||
Iterator(Hashtable &ht) :
|
||||
_idx(0),
|
||||
_ht(&ht),
|
||||
_b(ht._t[0])
|
||||
Iterator(Hashtable& ht) : _idx(0), _ht(&ht), _b(ht._t[0])
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -98,10 +101,7 @@ public:
|
|||
/**
|
||||
* @param bc Initial capacity in buckets (default: 64, must be nonzero)
|
||||
*/
|
||||
Hashtable(unsigned long bc = 64) :
|
||||
_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))),
|
||||
_bc(bc),
|
||||
_s(0)
|
||||
Hashtable(unsigned long bc = 64) : _t(reinterpret_cast<_Bucket**>(::malloc(sizeof(_Bucket*) * bc))), _bc(bc), _s(0)
|
||||
{
|
||||
if (! _t) {
|
||||
throw ZT_EXCEPTION_OUT_OF_MEMORY;
|
||||
|
@ -111,10 +111,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
Hashtable(const Hashtable<K,V> &ht) :
|
||||
_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * ht._bc))),
|
||||
_bc(ht._bc),
|
||||
_s(ht._s)
|
||||
Hashtable(const Hashtable<K, V>& ht) : _t(reinterpret_cast<_Bucket**>(::malloc(sizeof(_Bucket*) * ht._bc))), _bc(ht._bc), _s(ht._s)
|
||||
{
|
||||
if (! _t) {
|
||||
throw ZT_EXCEPTION_OUT_OF_MEMORY;
|
||||
|
@ -198,8 +195,7 @@ public:
|
|||
* @param v Vector, list, or other compliant container
|
||||
* @tparam Type of V (generally inferred)
|
||||
*/
|
||||
template<typename C>
|
||||
inline void appendKeys(C &v) const
|
||||
template <typename C> inline void appendKeys(C& v) const
|
||||
{
|
||||
if (_s) {
|
||||
for (unsigned long i = 0; i < _bc; ++i) {
|
||||
|
@ -246,7 +242,10 @@ public:
|
|||
}
|
||||
return (V*)0;
|
||||
}
|
||||
inline const V *get(const K &k) const { return const_cast<Hashtable *>(this)->get(k); }
|
||||
inline const V* get(const K& k) const
|
||||
{
|
||||
return const_cast<Hashtable*>(this)->get(k);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param k Key
|
||||
|
@ -295,7 +294,8 @@ public:
|
|||
if (b->k == k) {
|
||||
if (lastb) {
|
||||
lastb->next = b->next;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_t[bidx] = b->next;
|
||||
}
|
||||
delete b;
|
||||
|
@ -371,16 +371,21 @@ public:
|
|||
/**
|
||||
* @return Number of entries
|
||||
*/
|
||||
inline unsigned long size() const { return _s; }
|
||||
inline unsigned long size() const
|
||||
{
|
||||
return _s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if table is empty
|
||||
*/
|
||||
inline bool empty() const { return (_s == 0); }
|
||||
inline bool empty() const
|
||||
{
|
||||
return (_s == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename O>
|
||||
static inline unsigned long _hc(const O &obj)
|
||||
template <typename O> static inline unsigned long _hc(const O& obj)
|
||||
{
|
||||
return (unsigned long)obj.hashCode();
|
||||
}
|
||||
|
|
|
@ -11,18 +11,19 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ECC.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Identity.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// These can't be changed without a new identity type. They define the
|
||||
// parameters of the hashcash hashing/searching algorithm.
|
||||
|
||||
|
@ -69,10 +70,13 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
|
|||
|
||||
// Hashcash generation halting condition -- halt when first byte is less than
|
||||
// threshold value.
|
||||
struct _Identity_generate_cond
|
||||
struct _Identity_generate_cond {
|
||||
_Identity_generate_cond()
|
||||
{
|
||||
_Identity_generate_cond() {}
|
||||
_Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
|
||||
}
|
||||
_Identity_generate_cond(unsigned char* sb, char* gm) : digest(sb), genmem(gm)
|
||||
{
|
||||
}
|
||||
inline bool operator()(const ECC::Pair& kp) const
|
||||
{
|
||||
_computeMemoryHardHash(kp.pub.data, ZT_ECC_PUBLIC_KEY_SET_LEN, digest, genmem);
|
||||
|
@ -116,13 +120,7 @@ bool Identity::locallyValidate() const
|
|||
unsigned char addrb[5];
|
||||
_address.copyTo(addrb, 5);
|
||||
|
||||
return (
|
||||
(digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN)&&
|
||||
(digest[59] == addrb[0])&&
|
||||
(digest[60] == addrb[1])&&
|
||||
(digest[61] == addrb[2])&&
|
||||
(digest[62] == addrb[3])&&
|
||||
(digest[63] == addrb[4]));
|
||||
return ((digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN) && (digest[59] == addrb[0]) && (digest[60] == addrb[1]) && (digest[61] == addrb[2]) && (digest[62] == addrb[3]) && (digest[63] == addrb[4]));
|
||||
}
|
||||
|
||||
char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
|
||||
|
|
|
@ -14,16 +14,16 @@
|
|||
#ifndef ZT_IDENTITY_HPP
|
||||
#define ZT_IDENTITY_HPP
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "SHA512.hpp"
|
||||
|
||||
#define ZT_IDENTITY_STRING_BUFFER_LENGTH 384
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -38,32 +38,24 @@ namespace ZeroTier {
|
|||
* search for a different public key that duplicates an existing address. (See
|
||||
* code for deriveAddress() for this algorithm.)
|
||||
*/
|
||||
class Identity
|
||||
{
|
||||
class Identity {
|
||||
public:
|
||||
Identity() :
|
||||
_privateKey((ECC::Private *)0)
|
||||
Identity() : _privateKey((ECC::Private*)0)
|
||||
{
|
||||
}
|
||||
|
||||
Identity(const Identity &id) :
|
||||
_address(id._address),
|
||||
_publicKey(id._publicKey),
|
||||
_privateKey((id._privateKey) ? new ECC::Private(*(id._privateKey)) : (ECC::Private *)0)
|
||||
Identity(const Identity& id) : _address(id._address), _publicKey(id._publicKey), _privateKey((id._privateKey) ? new ECC::Private(*(id._privateKey)) : (ECC::Private*)0)
|
||||
{
|
||||
}
|
||||
|
||||
Identity(const char *str) :
|
||||
_privateKey((ECC::Private *)0)
|
||||
Identity(const char* str) : _privateKey((ECC::Private*)0)
|
||||
{
|
||||
if (! fromString(str)) {
|
||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
Identity(const Buffer<C> &b,unsigned int startAt = 0) :
|
||||
_privateKey((ECC::Private *)0)
|
||||
template <unsigned int C> Identity(const Buffer<C>& b, unsigned int startAt = 0) : _privateKey((ECC::Private*)0)
|
||||
{
|
||||
deserialize(b, startAt);
|
||||
}
|
||||
|
@ -85,7 +77,8 @@ public:
|
|||
_privateKey = new ECC::Private();
|
||||
}
|
||||
*_privateKey = *(id._privateKey);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
delete _privateKey;
|
||||
_privateKey = (ECC::Private*)0;
|
||||
}
|
||||
|
@ -109,7 +102,10 @@ public:
|
|||
/**
|
||||
* @return True if this identity contains a private key
|
||||
*/
|
||||
inline bool hasPrivate() const { return (_privateKey != (ECC::Private *)0); }
|
||||
inline bool hasPrivate() const
|
||||
{
|
||||
return (_privateKey != (ECC::Private*)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a SHA384 hash of this identity's address and public key(s).
|
||||
|
@ -203,7 +199,10 @@ public:
|
|||
/**
|
||||
* @return This identity's address
|
||||
*/
|
||||
inline const Address &address() const { return _address; }
|
||||
inline const Address& address() const
|
||||
{
|
||||
return _address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize this identity (binary)
|
||||
|
@ -212,8 +211,7 @@ public:
|
|||
* @param includePrivate If true, include private key component (if present) (default: false)
|
||||
* @throws std::out_of_range Buffer too small
|
||||
*/
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,bool includePrivate = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, bool includePrivate = false) const
|
||||
{
|
||||
_address.appendTo(b);
|
||||
b.append((uint8_t)0); // C25519/Ed25519 identity type
|
||||
|
@ -221,7 +219,8 @@ public:
|
|||
if ((_privateKey) && (includePrivate)) {
|
||||
b.append((unsigned char)ZT_ECC_PRIVATE_KEY_SET_LEN);
|
||||
b.append(_privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
b.append((unsigned char)0);
|
||||
}
|
||||
}
|
||||
|
@ -238,8 +237,7 @@ public:
|
|||
* @throws std::out_of_range Serialized data invalid
|
||||
* @throws std::invalid_argument Serialized data invalid
|
||||
*/
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
delete _privateKey;
|
||||
_privateKey = (ECC::Private*)0;
|
||||
|
@ -292,7 +290,10 @@ public:
|
|||
/**
|
||||
* @return C25519 public key
|
||||
*/
|
||||
inline const ECC::Public &publicKey() const { return _publicKey; }
|
||||
inline const ECC::Public& publicKey() const
|
||||
{
|
||||
return _publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return C25519 key pair (only returns valid pair if private key is present in this Identity object)
|
||||
|
@ -303,7 +304,8 @@ public:
|
|||
pair.pub = _publicKey;
|
||||
if (_privateKey) {
|
||||
pair.priv = *_privateKey;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memset(pair.priv.data, 0, ZT_ECC_PRIVATE_KEY_SET_LEN);
|
||||
}
|
||||
return pair;
|
||||
|
@ -312,14 +314,35 @@ public:
|
|||
/**
|
||||
* @return True if this identity contains something
|
||||
*/
|
||||
inline operator bool() const { return (_address); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_address);
|
||||
}
|
||||
|
||||
inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_ECC_PUBLIC_KEY_SET_LEN) == 0)); }
|
||||
inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_ECC_PUBLIC_KEY_SET_LEN) < 0))); }
|
||||
inline bool operator!=(const Identity &id) const { return !(*this == id); }
|
||||
inline bool operator>(const Identity &id) const { return (id < *this); }
|
||||
inline bool operator<=(const Identity &id) const { return !(id < *this); }
|
||||
inline bool operator>=(const Identity &id) const { return !(*this < id); }
|
||||
inline bool operator==(const Identity& id) const
|
||||
{
|
||||
return ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) == 0));
|
||||
}
|
||||
inline bool operator<(const Identity& id) const
|
||||
{
|
||||
return ((_address < id._address) || ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) < 0)));
|
||||
}
|
||||
inline bool operator!=(const Identity& id) const
|
||||
{
|
||||
return ! (*this == id);
|
||||
}
|
||||
inline bool operator>(const Identity& id) const
|
||||
{
|
||||
return (id < *this);
|
||||
}
|
||||
inline bool operator<=(const Identity& id) const
|
||||
{
|
||||
return ! (id < *this);
|
||||
}
|
||||
inline bool operator>=(const Identity& id) const
|
||||
{
|
||||
return ! (*this < id);
|
||||
}
|
||||
|
||||
private:
|
||||
Address _address;
|
||||
|
|
|
@ -11,34 +11,34 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../version.h"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "IncomingPacket.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "World.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Path.hpp"
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "../version.h"
|
||||
#include "Bond.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "PacketMultiplexer.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -56,11 +56,13 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f
|
|||
const uint64_t tpid = trustedPathId();
|
||||
if (RR->topology->shouldInboundPathBeTrusted(_path->address(), tpid)) {
|
||||
_authenticated = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, packetId(), sourceAddress, hops(), "path not trusted");
|
||||
return true;
|
||||
}
|
||||
} else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) {
|
||||
}
|
||||
else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE) && (verb() == Packet::VERB_HELLO)) {
|
||||
// Only HELLO is allowed in the clear, but will still have a MAC
|
||||
return _doHELLO(RR, tPtr, false);
|
||||
}
|
||||
|
@ -156,11 +158,13 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->sw->requestWhois(tPtr, RR->node->now(), sourceAddress);
|
||||
return false;
|
||||
}
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
RR->t->incomingPacketInvalid(tPtr, _path, packetId(), sourceAddress, hops(), verb(), "unexpected exception in tryDecode()");
|
||||
return true;
|
||||
}
|
||||
|
@ -182,7 +186,6 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar
|
|||
* circumstances. */
|
||||
|
||||
switch (errorCode) {
|
||||
|
||||
case Packet::ERROR_OBJ_NOT_FOUND:
|
||||
// Object not found, currently only meaningful from network controllers.
|
||||
if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) {
|
||||
|
@ -267,7 +270,8 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar
|
|||
authenticationURL[sizeof(authenticationURL) - 1] = 0; // ensure always zero terminated
|
||||
network->setAuthenticationRequired(tPtr, authenticationURL);
|
||||
}
|
||||
} else if (authVer == 1) {
|
||||
}
|
||||
else if (authVer == 1) {
|
||||
char issuerURL[2048] = { 0 };
|
||||
char centralAuthURL[2048] = { 0 };
|
||||
char ssoNonce[64] = { 0 };
|
||||
|
@ -292,14 +296,16 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar
|
|||
}
|
||||
if (authInfo.get(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, ssoProvider, sizeof(ssoProvider)) > 0) {
|
||||
ssoProvider[sizeof(ssoProvider) - 1] = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
strncpy(ssoProvider, "default", sizeof(ssoProvider));
|
||||
}
|
||||
|
||||
network->setAuthenticationRequired(tPtr, issuerURL, centralAuthURL, ssoClientID, ssoProvider, ssoNonce, ssoState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
network->setAuthenticationRequired(tPtr, "");
|
||||
}
|
||||
}
|
||||
|
@ -408,15 +414,18 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
|
|||
Metrics::pkt_error_out++;
|
||||
Metrics::pkt_error_identity_collision_out++;
|
||||
_path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid identity");
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Identity is the same as the one we already have -- check packet integrity
|
||||
|
||||
if (! dearmor(peer->key(), peer->aesKeysIfSupported(), RR->identity)) {
|
||||
|
@ -427,7 +436,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
|
|||
// Continue at // VALID
|
||||
}
|
||||
} // else if alreadyAuthenticated then continue at // VALID
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// We don't already have an identity with this address -- validate and learn it
|
||||
|
||||
// Sanity check: this basically can't happen
|
||||
|
@ -554,7 +564,6 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP
|
|||
}
|
||||
|
||||
switch (inReVerb) {
|
||||
|
||||
case Packet::VERB_HELLO: {
|
||||
const uint64_t latency = RR->node->now() - at<uint64_t>(ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP);
|
||||
const unsigned int vProto = (*this)[ZT_PROTO_VERB_HELLO__OK__IDX_PROTOCOL_VERSION];
|
||||
|
@ -584,7 +593,8 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP
|
|||
ptr += w.deserialize(*this, ptr);
|
||||
RR->topology->addWorld(tPtr, w, false);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ptr += worldsLen;
|
||||
}
|
||||
}
|
||||
|
@ -685,7 +695,8 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const Shar
|
|||
if (id) {
|
||||
id.serialize(outp, false);
|
||||
++count;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Request unknown WHOIS from upstream from us (if we have one)
|
||||
RR->sw->requestWhois(tPtr, RR->node->now(), addr);
|
||||
}
|
||||
|
@ -840,7 +851,8 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar
|
|||
RR->pm->putFrame(tPtr, nwid, network->userPtr(), sourceMac, network->mac(), etherType, 0, (const void*)frameData, frameLen, _flowId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_sendErrorNeedCredentials(RR, tPtr, peer, nwid);
|
||||
return false;
|
||||
}
|
||||
|
@ -890,19 +902,22 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const
|
|||
if (from != MAC(peer->address(), nwid)) {
|
||||
if (network->config().permitsBridging(peer->address())) {
|
||||
network->learnBridgeRoute(from, peer->address());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "bridging not allowed (remote)");
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay
|
||||
return true;
|
||||
}
|
||||
} else if (to != network->mac()) {
|
||||
}
|
||||
else if (to != network->mac()) {
|
||||
if (to.isMulticast()) {
|
||||
if (network->config().multicastLimit == 0) {
|
||||
RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "multicast disabled");
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay
|
||||
return true;
|
||||
}
|
||||
} else if (!network->config().permitsBridging(RR->identity.address())) {
|
||||
}
|
||||
else if (! network->config().permitsBridging(RR->identity.address())) {
|
||||
RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "bridging not allowed (local)");
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay
|
||||
return true;
|
||||
|
@ -928,7 +943,8 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const
|
|||
}
|
||||
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, false, nwid, flowId);
|
||||
}
|
||||
|
||||
|
@ -1140,7 +1156,8 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void
|
|||
const char* metaDataBytes = (metaDataLength != 0) ? (const char*)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT, metaDataLength) : (const char*)0;
|
||||
const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> metaData(metaDataBytes, metaDataLength);
|
||||
RR->localNetworkController->request(nwid, (hopCount > 0) ? InetAddress() : _path->address(), requestPacketId, peer->identity(), metaData);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Packet outp(peer->address(), RR->identity.address(), Packet::VERB_ERROR);
|
||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append(requestPacketId);
|
||||
|
@ -1199,7 +1216,9 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr
|
|||
if ((com) && (network)) {
|
||||
network->addCredential(tPtr, com);
|
||||
}
|
||||
} catch ( ... ) {} // discard invalid COMs
|
||||
}
|
||||
catch (...) {
|
||||
} // discard invalid COMs
|
||||
}
|
||||
|
||||
const bool trustEstablished = (network) ? network->gate(tPtr, peer) : false;
|
||||
|
@ -1260,7 +1279,8 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
|
|||
if ((flags & 0x04) != 0) {
|
||||
from.setTo(field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC, 6), 6);
|
||||
offset += 6;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
from.fromAddress(peer->address(), nwid);
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1315,8 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
|
|||
if (from != MAC(peer->address(), nwid)) {
|
||||
if (network->config().permitsBridging(peer->address())) {
|
||||
network->learnBridgeRoute(from, peer->address());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_MULTICAST_FRAME, from, to.mac(), "bridging not allowed (remote)");
|
||||
peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, true, nwid, ZT_QOS_NO_FLOW); // trustEstablished because COM is okay
|
||||
return true;
|
||||
|
@ -1358,29 +1379,28 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
|
|||
switch (addrType) {
|
||||
case 4: {
|
||||
const InetAddress a(field(ptr, 4), 4, at<uint16_t>(ptr + 4));
|
||||
if (
|
||||
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
if (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
(! (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now, a)))) && // not already known
|
||||
(RR->node->shouldUsePathForZeroTierTraffic(tPtr, peer->address(), _path->localSocket(), a))) // should use path
|
||||
{
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) {
|
||||
peer->clusterRedirect(tPtr, _path, a, now);
|
||||
} else if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
}
|
||||
else if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
peer->attemptToContactAt(tPtr, InetAddress(), a, now, false);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
|
||||
const InetAddress a(field(ptr, 16), 16, at<uint16_t>(ptr + 16));
|
||||
if (
|
||||
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
if (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
(! (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now, a)))) && // not already known
|
||||
(RR->node->shouldUsePathForZeroTierTraffic(tPtr, peer->address(), _path->localSocket(), a))) // should use path
|
||||
{
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) {
|
||||
peer->clusterRedirect(tPtr, _path, a, now);
|
||||
} else if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
}
|
||||
else if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
peer->attemptToContactAt(tPtr, InetAddress(), a, now, false);
|
||||
}
|
||||
}
|
||||
|
@ -1426,7 +1446,8 @@ bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,con
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_REMOTE_TRACE, &rt);
|
||||
}
|
||||
rt.data = const_cast<char*>(++ptr); // start of next string, if any
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#ifndef ZT_INCOMINGPACKET_HPP
|
||||
#define ZT_INCOMINGPACKET_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
/*
|
||||
* The big picture:
|
||||
|
@ -46,14 +46,9 @@ class Network;
|
|||
/**
|
||||
* Subclass of packet that handles the decoding of it
|
||||
*/
|
||||
class IncomingPacket : public Packet
|
||||
{
|
||||
class IncomingPacket : public Packet {
|
||||
public:
|
||||
IncomingPacket() :
|
||||
Packet(),
|
||||
_receiveTime(0),
|
||||
_path(),
|
||||
_authenticated(false)
|
||||
IncomingPacket() : Packet(), _receiveTime(0), _path(), _authenticated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,11 +61,7 @@ public:
|
|||
* @param now Current time
|
||||
* @throws std::out_of_range Range error processing packet
|
||||
*/
|
||||
IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
|
||||
Packet(data,len),
|
||||
_receiveTime(now),
|
||||
_path(path),
|
||||
_authenticated(false)
|
||||
IncomingPacket(const void* data, unsigned int len, const SharedPtr<Path>& path, int64_t now) : Packet(data, len), _receiveTime(now), _path(path), _authenticated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -109,7 +100,10 @@ public:
|
|||
/**
|
||||
* @return Time of packet receipt / start of decode
|
||||
*/
|
||||
inline uint64_t receiveTime() const { return _receiveTime; }
|
||||
inline uint64_t receiveTime() const
|
||||
{
|
||||
return _receiveTime;
|
||||
}
|
||||
|
||||
private:
|
||||
// These are called internally to handle packet contents once it has
|
||||
|
|
|
@ -11,16 +11,16 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include "InetAddress.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
const InetAddress InetAddress::LO4((const void*)("\x7f\x00\x00\x01"), 4, 0);
|
||||
|
@ -29,7 +29,6 @@ const InetAddress InetAddress::LO6((const void *)("\x00\x00\x00\x00\x00\x00\x00\
|
|||
InetAddress::IpScope InetAddress::ipScope() const
|
||||
{
|
||||
switch (ss_family) {
|
||||
|
||||
case AF_INET: {
|
||||
const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in*>(this)->sin_addr.s_addr);
|
||||
switch (ip >> 24) {
|
||||
|
@ -124,7 +123,8 @@ InetAddress::IpScope InetAddress::ipScope() const
|
|||
}
|
||||
if ((k == 15) && (ip[15] == 0x01)) {
|
||||
return IP_SCOPE_LOOPBACK; // fe80::1/128
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return IP_SCOPE_LINK_LOCAL; // fe80::/10
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,6 @@ InetAddress::IpScope InetAddress::ipScope() const
|
|||
}
|
||||
return IP_SCOPE_GLOBAL;
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
return IP_SCOPE_NONE;
|
||||
|
@ -174,7 +173,8 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
|
|||
ss_family = AF_INET;
|
||||
reinterpret_cast<struct sockaddr_in*>(this)->sin_addr.s_addr = ipb[0];
|
||||
reinterpret_cast<struct sockaddr_in*>(this)->sin_port = Utils::hton((uint16_t)port);
|
||||
} else if (ipLen == 16) {
|
||||
}
|
||||
else if (ipLen == 16) {
|
||||
ss_family = AF_INET6;
|
||||
memcpy(reinterpret_cast<struct sockaddr_in6*>(this)->sin6_addr.s6_addr, ipBytes, 16);
|
||||
reinterpret_cast<struct sockaddr_in6*>(this)->sin6_port = Utils::hton((uint16_t)port);
|
||||
|
@ -246,13 +246,15 @@ bool InetAddress::fromString(const char *ipSlashPort)
|
|||
in6->sin6_family = AF_INET6;
|
||||
in6->sin6_port = Utils::hton((uint16_t)port);
|
||||
return true;
|
||||
} else if (strchr(buf,'.')) {
|
||||
}
|
||||
else if (strchr(buf, '.')) {
|
||||
struct sockaddr_in* const in = reinterpret_cast<struct sockaddr_in*>(this);
|
||||
inet_pton(AF_INET, buf, &in->sin_addr.s_addr);
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_port = Utils::hton((uint16_t)port);
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +272,8 @@ InetAddress InetAddress::netmask() const
|
|||
if (bits) {
|
||||
nm[0] = Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
|
||||
nm[1] = Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
nm[0] = 0;
|
||||
nm[1] = 0;
|
||||
}
|
||||
|
@ -341,7 +344,8 @@ bool InetAddress::containsAddress(const InetAddress &addr) const
|
|||
if (bits == 0) {
|
||||
return true;
|
||||
}
|
||||
return ( (Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr) >> (32 - bits)) );
|
||||
return (
|
||||
(Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in*>(this)->sin_addr.s_addr) >> (32 - bits)));
|
||||
}
|
||||
case AF_INET6: {
|
||||
const InetAddress mask(netmask());
|
||||
|
@ -404,15 +408,15 @@ bool InetAddress::operator==(const InetAddress &a) const
|
|||
switch (ss_family) {
|
||||
case AF_INET:
|
||||
return (
|
||||
(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_port)&&
|
||||
(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_addr.s_addr));
|
||||
(reinterpret_cast<const struct sockaddr_in*>(this)->sin_port == reinterpret_cast<const struct sockaddr_in*>(&a)->sin_port)
|
||||
&& (reinterpret_cast<const struct sockaddr_in*>(this)->sin_addr.s_addr == reinterpret_cast<const struct sockaddr_in*>(&a)->sin_addr.s_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
return (
|
||||
(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_port)&&
|
||||
(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_flowinfo == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_flowinfo)&&
|
||||
(memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0)&&
|
||||
(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_scope_id == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_scope_id));
|
||||
(reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_port == reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_port)
|
||||
&& (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_flowinfo == reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_flowinfo)
|
||||
&& (memcmp(reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_addr.s6_addr, reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_addr.s6_addr, 16) == 0)
|
||||
&& (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_scope_id == reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_scope_id));
|
||||
break;
|
||||
default:
|
||||
return (memcmp(this, &a, sizeof(InetAddress)) == 0);
|
||||
|
@ -425,12 +429,14 @@ bool InetAddress::operator<(const InetAddress &a) const
|
|||
{
|
||||
if (ss_family < a.ss_family) {
|
||||
return true;
|
||||
} else if (ss_family == a.ss_family) {
|
||||
}
|
||||
else if (ss_family == a.ss_family) {
|
||||
switch (ss_family) {
|
||||
case AF_INET:
|
||||
if (reinterpret_cast<const struct sockaddr_in*>(this)->sin_port < reinterpret_cast<const struct sockaddr_in*>(&a)->sin_port) {
|
||||
return true;
|
||||
} else if (reinterpret_cast<const struct sockaddr_in *>(this)->sin_port == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_port) {
|
||||
}
|
||||
else if (reinterpret_cast<const struct sockaddr_in*>(this)->sin_port == reinterpret_cast<const struct sockaddr_in*>(&a)->sin_port) {
|
||||
if (reinterpret_cast<const struct sockaddr_in*>(this)->sin_addr.s_addr < reinterpret_cast<const struct sockaddr_in*>(&a)->sin_addr.s_addr) {
|
||||
return true;
|
||||
}
|
||||
|
@ -439,13 +445,16 @@ bool InetAddress::operator<(const InetAddress &a) const
|
|||
case AF_INET6:
|
||||
if (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_port < reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_port) {
|
||||
return true;
|
||||
} else if (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_port) {
|
||||
}
|
||||
else if (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_port == reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_port) {
|
||||
if (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_flowinfo < reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_flowinfo) {
|
||||
return true;
|
||||
} else if (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_flowinfo == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_flowinfo) {
|
||||
}
|
||||
else if (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_flowinfo == reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_flowinfo) {
|
||||
if (memcmp(reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_addr.s6_addr, reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_addr.s6_addr, 16) < 0) {
|
||||
return true;
|
||||
} else if (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0) {
|
||||
}
|
||||
else if (memcmp(reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_addr.s6_addr, reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_addr.s6_addr, 16) == 0) {
|
||||
if (reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_scope_id < reinterpret_cast<const struct sockaddr_in6*>(&a)->sin6_scope_id) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
#ifndef ZT_INETADDRESS_HPP
|
||||
#define ZT_INETADDRESS_HPP
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Utils.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -39,8 +39,7 @@ namespace ZeroTier {
|
|||
* sockaddr_storage and used interchangeably. DO NOT change this by e.g.
|
||||
* adding non-static fields, since much code depends on this identity.
|
||||
*/
|
||||
struct InetAddress : public sockaddr_storage
|
||||
{
|
||||
struct InetAddress : public sockaddr_storage {
|
||||
/**
|
||||
* Loopback IPv4 address (no port)
|
||||
*/
|
||||
|
@ -58,8 +57,7 @@ struct InetAddress : public sockaddr_storage
|
|||
* MUST remain that way or Path must be changed to reflect. Also be sure
|
||||
* to change ZT_INETADDRESS_MAX_SCOPE if the max changes.
|
||||
*/
|
||||
enum IpScope
|
||||
{
|
||||
enum IpScope {
|
||||
IP_SCOPE_NONE = 0, // NULL or not an IP address
|
||||
IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other V4/V6 multicast IPs
|
||||
IP_SCOPE_LOOPBACK = 2, // 127.0.0.1, ::1, etc.
|
||||
|
@ -72,25 +70,69 @@ struct InetAddress : public sockaddr_storage
|
|||
|
||||
// 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
|
||||
struct Hasher {
|
||||
inline std::size_t operator()(const InetAddress& a) const
|
||||
{
|
||||
inline std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); }
|
||||
return (std::size_t)a.hashCode();
|
||||
}
|
||||
};
|
||||
|
||||
InetAddress() { memset(this,0,sizeof(InetAddress)); }
|
||||
InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
|
||||
InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
|
||||
InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
|
||||
InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
|
||||
InetAddress(const struct sockaddr &sa) { *this = sa; }
|
||||
InetAddress(const struct sockaddr *sa) { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in &sa) { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in *sa) { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
|
||||
InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
|
||||
InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
|
||||
InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
|
||||
InetAddress()
|
||||
{
|
||||
memset(this, 0, sizeof(InetAddress));
|
||||
}
|
||||
InetAddress(const InetAddress& a)
|
||||
{
|
||||
memcpy(this, &a, sizeof(InetAddress));
|
||||
}
|
||||
InetAddress(const InetAddress* a)
|
||||
{
|
||||
memcpy(this, a, sizeof(InetAddress));
|
||||
}
|
||||
InetAddress(const struct sockaddr_storage& ss)
|
||||
{
|
||||
*this = ss;
|
||||
}
|
||||
InetAddress(const struct sockaddr_storage* ss)
|
||||
{
|
||||
*this = ss;
|
||||
}
|
||||
InetAddress(const struct sockaddr& sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const struct sockaddr* sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const struct sockaddr_in& sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const struct sockaddr_in* sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const struct sockaddr_in6& sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const struct sockaddr_in6* sa)
|
||||
{
|
||||
*this = sa;
|
||||
}
|
||||
InetAddress(const void* ipBytes, unsigned int ipLen, unsigned int port)
|
||||
{
|
||||
this->set(ipBytes, ipLen, port);
|
||||
}
|
||||
InetAddress(const uint32_t ipv4, unsigned int port)
|
||||
{
|
||||
this->set(&ipv4, 4, port);
|
||||
}
|
||||
InetAddress(const char* ipSlashPort)
|
||||
{
|
||||
this->fromString(ipSlashPort);
|
||||
}
|
||||
|
||||
inline InetAddress& operator=(const InetAddress& a)
|
||||
{
|
||||
|
@ -283,7 +325,10 @@ struct InetAddress : public sockaddr_storage
|
|||
*
|
||||
* @return Netmask bits
|
||||
*/
|
||||
inline unsigned int netmaskBits() const { return port(); }
|
||||
inline unsigned int netmaskBits() const
|
||||
{
|
||||
return port();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if netmask bits is valid for the address type
|
||||
|
@ -308,7 +353,10 @@ struct InetAddress : public sockaddr_storage
|
|||
*
|
||||
* @return Gateway metric
|
||||
*/
|
||||
inline unsigned int metric() const { return port(); }
|
||||
inline unsigned int metric() const
|
||||
{
|
||||
return port();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a full netmask as an InetAddress
|
||||
|
@ -353,12 +401,18 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return True if this is an IPv4 address
|
||||
*/
|
||||
inline bool isV4() const { return (ss_family == AF_INET); }
|
||||
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); }
|
||||
inline bool isV6() const
|
||||
{
|
||||
return (ss_family == AF_INET6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to raw address bytes or NULL if not available
|
||||
|
@ -440,14 +494,16 @@ struct InetAddress : public sockaddr_storage
|
|||
{
|
||||
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);
|
||||
} else if (ss_family == AF_INET6) {
|
||||
}
|
||||
else if (ss_family == AF_INET6) {
|
||||
unsigned long tmp = reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_port;
|
||||
const uint8_t* a = reinterpret_cast<const uint8_t*>(reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_addr.s6_addr);
|
||||
for (long i = 0; i < 16; ++i) {
|
||||
reinterpret_cast<uint8_t*>(&tmp)[i % sizeof(tmp)] ^= a[i];
|
||||
}
|
||||
return tmp;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
unsigned long tmp = reinterpret_cast<const struct sockaddr_in6*>(this)->sin6_port;
|
||||
const uint8_t* a = reinterpret_cast<const uint8_t*>(this);
|
||||
for (long i = 0; i < (long)sizeof(InetAddress); ++i) {
|
||||
|
@ -460,7 +516,10 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* Set to null/zero
|
||||
*/
|
||||
inline void zero() { memset(this,0,sizeof(InetAddress)); }
|
||||
inline void zero()
|
||||
{
|
||||
memset(this, 0, sizeof(InetAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a network/route rather than an IP assignment
|
||||
|
@ -500,7 +559,8 @@ struct InetAddress : public sockaddr_storage
|
|||
for (unsigned int i = 0; i < 16; ++i) {
|
||||
if (ip0[i] == ip1[i]) {
|
||||
c += 8;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
uint8_t ip0b = ip0[i];
|
||||
uint8_t ip1b = ip1[i];
|
||||
uint8_t bit = 0x80;
|
||||
|
@ -552,10 +612,12 @@ struct InetAddress : public sockaddr_storage
|
|||
/**
|
||||
* @return True if address family is non-zero
|
||||
*/
|
||||
inline operator bool() const { return (ss_family != 0); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (ss_family != 0);
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b) const
|
||||
{
|
||||
// This is used in the protocol and must be the same as describe in places
|
||||
// like VERB_HELLO in Packet.hpp.
|
||||
|
@ -576,8 +638,7 @@ struct InetAddress : public sockaddr_storage
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
memset(this, 0, sizeof(InetAddress));
|
||||
unsigned int p = startAt;
|
||||
|
@ -616,10 +677,22 @@ 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); }
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mac MAC address seed
|
||||
|
|
126
node/MAC.hpp
126
node/MAC.hpp
|
@ -14,51 +14,68 @@
|
|||
#ifndef ZT_MAC_HPP
|
||||
#define ZT_MAC_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* 48-byte Ethernet MAC address
|
||||
*/
|
||||
class MAC
|
||||
{
|
||||
class MAC {
|
||||
public:
|
||||
MAC() : _m(0ULL) {}
|
||||
MAC(const MAC &m) : _m(m._m) {}
|
||||
MAC() : _m(0ULL)
|
||||
{
|
||||
}
|
||||
MAC(const MAC& m) : _m(m._m)
|
||||
{
|
||||
}
|
||||
|
||||
MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) :
|
||||
_m( ((((uint64_t)a) & 0xffULL) << 40) |
|
||||
((((uint64_t)b) & 0xffULL) << 32) |
|
||||
((((uint64_t)c) & 0xffULL) << 24) |
|
||||
((((uint64_t)d) & 0xffULL) << 16) |
|
||||
((((uint64_t)e) & 0xffULL) << 8) |
|
||||
(((uint64_t)f) & 0xffULL) ) {}
|
||||
MAC(const void *bits,unsigned int len) { setTo(bits,len); }
|
||||
MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
|
||||
MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
|
||||
MAC(const unsigned char a, const unsigned char b, const unsigned char c, const unsigned char d, const unsigned char e, const unsigned char f)
|
||||
: _m(((((uint64_t)a) & 0xffULL) << 40) | ((((uint64_t)b) & 0xffULL) << 32) | ((((uint64_t)c) & 0xffULL) << 24) | ((((uint64_t)d) & 0xffULL) << 16) | ((((uint64_t)e) & 0xffULL) << 8) | (((uint64_t)f) & 0xffULL))
|
||||
{
|
||||
}
|
||||
MAC(const void* bits, unsigned int len)
|
||||
{
|
||||
setTo(bits, len);
|
||||
}
|
||||
MAC(const Address& ztaddr, uint64_t nwid)
|
||||
{
|
||||
fromAddress(ztaddr, nwid);
|
||||
}
|
||||
MAC(const uint64_t m) : _m(m & 0xffffffffffffULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MAC in 64-bit integer
|
||||
*/
|
||||
inline uint64_t toInt() const { return _m; }
|
||||
inline uint64_t toInt() const
|
||||
{
|
||||
return _m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MAC to zero
|
||||
*/
|
||||
inline void zero() { _m = 0ULL; }
|
||||
inline void zero()
|
||||
{
|
||||
_m = 0ULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if MAC is non-zero
|
||||
*/
|
||||
inline operator bool() const { return (_m != 0ULL); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_m != 0ULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bits Raw MAC in big-endian byte order
|
||||
|
@ -107,8 +124,7 @@ public:
|
|||
*
|
||||
* @param b Buffer to append to
|
||||
*/
|
||||
template<unsigned int C>
|
||||
inline void appendTo(Buffer<C> &b) const
|
||||
template <unsigned int C> inline void appendTo(Buffer<C>& b) const
|
||||
{
|
||||
unsigned char* p = (unsigned char*)b.appendField(6);
|
||||
*(p++) = (unsigned char)((_m >> 40) & 0xff);
|
||||
|
@ -122,17 +138,26 @@ public:
|
|||
/**
|
||||
* @return True if this is broadcast (all 0xff)
|
||||
*/
|
||||
inline bool isBroadcast() const { return (_m == 0xffffffffffffULL); }
|
||||
inline bool isBroadcast() const
|
||||
{
|
||||
return (_m == 0xffffffffffffULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this is a multicast MAC
|
||||
*/
|
||||
inline bool isMulticast() const { return ((_m & 0x010000000000ULL) != 0ULL); }
|
||||
inline bool isMulticast() const
|
||||
{
|
||||
return ((_m & 0x010000000000ULL) != 0ULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param True if this is a locally-administered MAC
|
||||
*/
|
||||
inline bool isLocallyAdministered() const { return ((_m & 0x020000000000ULL) != 0ULL); }
|
||||
inline bool isLocallyAdministered() const
|
||||
{
|
||||
return ((_m & 0x020000000000ULL) != 0ULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this MAC to a MAC derived from an address and a network ID
|
||||
|
@ -184,14 +209,23 @@ public:
|
|||
* @param i Value from 0 to 5 (inclusive)
|
||||
* @return Byte at said position (address interpreted in big-endian order)
|
||||
*/
|
||||
inline unsigned char operator[](unsigned int i) const { return (unsigned char)((_m >> (40 - (i * 8))) & 0xff); }
|
||||
inline unsigned char operator[](unsigned int i) const
|
||||
{
|
||||
return (unsigned char)((_m >> (40 - (i * 8))) & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 6, which is the number of bytes in a MAC, for container compliance
|
||||
*/
|
||||
inline unsigned int size() const { return 6; }
|
||||
inline unsigned int size() const
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
inline unsigned long hashCode() const { return (unsigned long)_m; }
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (unsigned long)_m;
|
||||
}
|
||||
|
||||
inline char* toString(char buf[18]) const
|
||||
{
|
||||
|
@ -227,12 +261,30 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const MAC &m) const { return (_m == m._m); }
|
||||
inline bool operator!=(const MAC &m) const { return (_m != m._m); }
|
||||
inline bool operator<(const MAC &m) const { return (_m < m._m); }
|
||||
inline bool operator<=(const MAC &m) const { return (_m <= m._m); }
|
||||
inline bool operator>(const MAC &m) const { return (_m > m._m); }
|
||||
inline bool operator>=(const MAC &m) const { return (_m >= m._m); }
|
||||
inline bool operator==(const MAC& m) const
|
||||
{
|
||||
return (_m == m._m);
|
||||
}
|
||||
inline bool operator!=(const MAC& m) const
|
||||
{
|
||||
return (_m != m._m);
|
||||
}
|
||||
inline bool operator<(const MAC& m) const
|
||||
{
|
||||
return (_m < m._m);
|
||||
}
|
||||
inline bool operator<=(const MAC& m) const
|
||||
{
|
||||
return (_m <= m._m);
|
||||
}
|
||||
inline bool operator>(const MAC& m) const
|
||||
{
|
||||
return (_m > m._m);
|
||||
}
|
||||
inline bool operator>=(const MAC& m) const
|
||||
{
|
||||
return (_m >= m._m);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _m;
|
||||
|
|
|
@ -11,27 +11,21 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Membership.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Packet.hpp"
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Trace.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Membership::Membership() :
|
||||
_lastUpdatedMulticast(0),
|
||||
_comRevocationThreshold(0),
|
||||
_lastPushedCredentials(0),
|
||||
_revocations(4),
|
||||
_remoteTags(4),
|
||||
_remoteCaps(4),
|
||||
_remoteCoos(4)
|
||||
Membership::Membership() : _lastUpdatedMulticast(0), _comRevocationThreshold(0), _lastPushedCredentials(0), _revocations(4), _remoteTags(4), _remoteCaps(4), _remoteCoos(4)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -172,9 +166,18 @@ static Membership::AddCredentialResult _addCredImpl(Hashtable<uint32_t,C> &remot
|
|||
}
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag) { return _addCredImpl<Tag>(_remoteTags,_revocations,RR,tPtr,nconf,tag); }
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap) { return _addCredImpl<Capability>(_remoteCaps,_revocations,RR,tPtr,nconf,cap); }
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo) { return _addCredImpl<CertificateOfOwnership>(_remoteCoos,_revocations,RR,tPtr,nconf,coo); }
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Tag& tag)
|
||||
{
|
||||
return _addCredImpl<Tag>(_remoteTags, _revocations, RR, tPtr, nconf, tag);
|
||||
}
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Capability& cap)
|
||||
{
|
||||
return _addCredImpl<Capability>(_remoteCaps, _revocations, RR, tPtr, nconf, cap);
|
||||
}
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const CertificateOfOwnership& coo)
|
||||
{
|
||||
return _addCredImpl<CertificateOfOwnership>(_remoteCoos, _revocations, RR, tPtr, nconf, coo);
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Revocation& rev)
|
||||
{
|
||||
|
|
|
@ -14,17 +14,17 @@
|
|||
#ifndef ZT_MEMBERSHIP_HPP
|
||||
#define ZT_MEMBERSHIP_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Capability.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ZT_MEMBERSHIP_CRED_ID_UNUSED 0xffffffffffffffffULL
|
||||
|
||||
|
@ -40,16 +40,9 @@ class Network;
|
|||
*
|
||||
* This class is not thread safe. It must be locked externally.
|
||||
*/
|
||||
class Membership
|
||||
{
|
||||
class Membership {
|
||||
public:
|
||||
enum AddCredentialResult
|
||||
{
|
||||
ADD_REJECTED,
|
||||
ADD_ACCEPTED_NEW,
|
||||
ADD_ACCEPTED_REDUNDANT,
|
||||
ADD_DEFERRED_FOR_WHOIS
|
||||
};
|
||||
enum AddCredentialResult { ADD_REJECTED, ADD_ACCEPTED_NEW, ADD_ACCEPTED_REDUNDANT, ADD_DEFERRED_FOR_WHOIS };
|
||||
|
||||
Membership();
|
||||
|
||||
|
@ -64,9 +57,18 @@ public:
|
|||
*/
|
||||
void pushCredentials(const RuntimeEnvironment* RR, void* tPtr, const int64_t now, const Address& peerAddress, const NetworkConfig& nconf);
|
||||
|
||||
inline int64_t lastPushedCredentials() { return _lastPushedCredentials; }
|
||||
inline int64_t comTimestamp() { return _com.timestamp(); }
|
||||
inline int64_t comRevocationThreshold() { return _comRevocationThreshold; }
|
||||
inline int64_t lastPushedCredentials()
|
||||
{
|
||||
return _lastPushedCredentials;
|
||||
}
|
||||
inline int64_t comTimestamp()
|
||||
{
|
||||
return _com.timestamp();
|
||||
}
|
||||
inline int64_t comRevocationThreshold()
|
||||
{
|
||||
return _comRevocationThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true
|
||||
|
@ -108,8 +110,7 @@ public:
|
|||
* @param r Resource to check
|
||||
* @return True if this peer has a certificate of ownership for the given resource
|
||||
*/
|
||||
template<typename T>
|
||||
inline bool hasCertificateOfOwnershipFor(const NetworkConfig &nconf,const T &r) const
|
||||
template <typename T> inline bool hasCertificateOfOwnershipFor(const NetworkConfig& nconf, const T& r) const
|
||||
{
|
||||
uint32_t* k = (uint32_t*)0;
|
||||
CertificateOfOwnership* v = (CertificateOfOwnership*)0;
|
||||
|
@ -171,10 +172,16 @@ public:
|
|||
/**
|
||||
* Generates a key for the internal use in indexing credentials by type and credential ID
|
||||
*/
|
||||
static uint64_t credentialKey(const Credential::Type &t,const uint32_t i) { return (((uint64_t)t << 32) | (uint64_t)i); }
|
||||
static uint64_t credentialKey(const Credential::Type& t, const uint32_t i)
|
||||
{
|
||||
return (((uint64_t)t << 32) | (uint64_t)i);
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool _isV6NDPEmulated(const NetworkConfig &nconf,const MAC &m) const { return false; }
|
||||
inline bool _isV6NDPEmulated(const NetworkConfig& nconf, const MAC& m) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
inline bool _isV6NDPEmulated(const NetworkConfig& nconf, const InetAddress& ip) const
|
||||
{
|
||||
if ((ip.isV6()) && (nconf.ndpEmulation())) {
|
||||
|
@ -215,8 +222,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const C &remoteCredential) const
|
||||
template <typename C> inline bool _isCredentialTimestampValid(const NetworkConfig& nconf, const C& remoteCredential) const
|
||||
{
|
||||
const int64_t ts = remoteCredential.timestamp();
|
||||
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
|
||||
|
@ -226,8 +232,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
inline void _cleanCredImpl(const NetworkConfig &nconf,Hashtable<uint32_t,C> &remoteCreds)
|
||||
template <typename C> inline void _cleanCredImpl(const NetworkConfig& nconf, Hashtable<uint32_t, C>& remoteCreds)
|
||||
{
|
||||
uint32_t* k = (uint32_t*)0;
|
||||
C* v = (C*)0;
|
||||
|
@ -260,15 +265,9 @@ private:
|
|||
Hashtable<uint32_t, CertificateOfOwnership> _remoteCoos;
|
||||
|
||||
public:
|
||||
class CapabilityIterator
|
||||
{
|
||||
class CapabilityIterator {
|
||||
public:
|
||||
CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
|
||||
_hti(m._remoteCaps),
|
||||
_k((uint32_t *)0),
|
||||
_c((Capability *)0),
|
||||
_m(m),
|
||||
_nconf(nconf)
|
||||
CapabilityIterator(Membership& m, const NetworkConfig& nconf) : _hti(m._remoteCaps), _k((uint32_t*)0), _c((Capability*)0), _m(m), _nconf(nconf)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
326
node/Metrics.cpp
326
node/Metrics.cpp
|
@ -10,263 +10,155 @@
|
|||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
|
||||
#include <prometheus/simpleapi.h>
|
||||
#include <prometheus/histogram.h>
|
||||
#include <prometheus/simpleapi.h>
|
||||
|
||||
namespace prometheus {
|
||||
namespace simpleapi {
|
||||
std::shared_ptr<Registry> registry_ptr = std::make_shared<Registry>();
|
||||
Registry& registry = *registry_ptr;
|
||||
SaveToFile saver;
|
||||
}
|
||||
}
|
||||
} // namespace simpleapi
|
||||
} // namespace prometheus
|
||||
|
||||
namespace ZeroTier {
|
||||
namespace Metrics {
|
||||
// Packet Type Counts
|
||||
prometheus::simpleapi::counter_family_t packets
|
||||
{ "zt_packet", "ZeroTier packet type counts"};
|
||||
prometheus::simpleapi::counter_family_t packets { "zt_packet", "ZeroTier packet type counts" };
|
||||
|
||||
// Incoming packets
|
||||
prometheus::simpleapi::counter_metric_t pkt_nop_in
|
||||
{ packets.Add({{"packet_type", "nop"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_in
|
||||
{ packets.Add({{"packet_type", "error"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ack_in
|
||||
{ packets.Add({{"packet_type", "ack"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_qos_in
|
||||
{ packets.Add({{"packet_type", "qos"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_hello_in
|
||||
{ packets.Add({{"packet_type", "hello"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ok_in
|
||||
{ packets.Add({{"packet_type", "ok"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_whois_in
|
||||
{ packets.Add({{"packet_type", "whois"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_rendezvous_in
|
||||
{ packets.Add({{"packet_type", "rendezvous"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_frame_in
|
||||
{ packets.Add({{"packet_type", "frame"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ext_frame_in
|
||||
{ packets.Add({{"packet_type", "ext_frame"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_echo_in
|
||||
{ packets.Add({{"packet_type", "echo"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_like_in
|
||||
{ packets.Add({{"packet_type", "multicast_like"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_credentials_in
|
||||
{ packets.Add({{"packet_type", "network_credentials"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_request_in
|
||||
{ packets.Add({{"packet_type", "network_config_request"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_in
|
||||
{ packets.Add({{"packet_type", "network_config"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in
|
||||
{ packets.Add({{"packet_type", "multicast_gather"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in
|
||||
{ packets.Add({{"packet_type", "multicast_frame"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in
|
||||
{ packets.Add({{"packet_type", "push_direct_paths"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_user_message_in
|
||||
{ packets.Add({{"packet_type", "user_message"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_remote_trace_in
|
||||
{ packets.Add({{"packet_type", "remote_trace"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in
|
||||
{ packets.Add({{"packet_type", "path_negotiation_request"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_nop_in { packets.Add({ { "packet_type", "nop" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_in { packets.Add({ { "packet_type", "error" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ack_in { packets.Add({ { "packet_type", "ack" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_qos_in { packets.Add({ { "packet_type", "qos" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_hello_in { packets.Add({ { "packet_type", "hello" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ok_in { packets.Add({ { "packet_type", "ok" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_whois_in { packets.Add({ { "packet_type", "whois" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_rendezvous_in { packets.Add({ { "packet_type", "rendezvous" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_frame_in { packets.Add({ { "packet_type", "frame" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ext_frame_in { packets.Add({ { "packet_type", "ext_frame" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_echo_in { packets.Add({ { "packet_type", "echo" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_like_in { packets.Add({ { "packet_type", "multicast_like" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_credentials_in { packets.Add({ { "packet_type", "network_credentials" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_request_in { packets.Add({ { "packet_type", "network_config_request" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_in { packets.Add({ { "packet_type", "network_config" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in { packets.Add({ { "packet_type", "multicast_gather" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in { packets.Add({ { "packet_type", "multicast_frame" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in { packets.Add({ { "packet_type", "push_direct_paths" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_user_message_in { packets.Add({ { "packet_type", "user_message" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_remote_trace_in { packets.Add({ { "packet_type", "remote_trace" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in { packets.Add({ { "packet_type", "path_negotiation_request" }, { "direction", "rx" } }) };
|
||||
|
||||
// Outgoing packets
|
||||
prometheus::simpleapi::counter_metric_t pkt_nop_out
|
||||
{ packets.Add({{"packet_type", "nop"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_out
|
||||
{ packets.Add({{"packet_type", "error"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ack_out
|
||||
{ packets.Add({{"packet_type", "ack"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_qos_out
|
||||
{ packets.Add({{"packet_type", "qos"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_hello_out
|
||||
{ packets.Add({{"packet_type", "hello"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ok_out
|
||||
{ packets.Add({{"packet_type", "ok"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_whois_out
|
||||
{ packets.Add({{"packet_type", "whois"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_rendezvous_out
|
||||
{ packets.Add({{"packet_type", "rendezvous"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_frame_out
|
||||
{ packets.Add({{"packet_type", "frame"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ext_frame_out
|
||||
{ packets.Add({{"packet_type", "ext_frame"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_echo_out
|
||||
{ packets.Add({{"packet_type", "echo"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_like_out
|
||||
{ packets.Add({{"packet_type", "multicast_like"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_credentials_out
|
||||
{ packets.Add({{"packet_type", "network_credentials"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_request_out
|
||||
{ packets.Add({{"packet_type", "network_config_request"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_out
|
||||
{ packets.Add({{"packet_type", "network_config"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out
|
||||
{ packets.Add({{"packet_type", "multicast_gather"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out
|
||||
{ packets.Add({{"packet_type", "multicast_frame"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out
|
||||
{ packets.Add({{"packet_type", "push_direct_paths"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_user_message_out
|
||||
{ packets.Add({{"packet_type", "user_message"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_remote_trace_out
|
||||
{ packets.Add({{"packet_type", "remote_trace"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out
|
||||
{ packets.Add({{"packet_type", "path_negotiation_request"}, {"direction", "tx"}}) };
|
||||
|
||||
prometheus::simpleapi::counter_metric_t pkt_nop_out { packets.Add({ { "packet_type", "nop" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_out { packets.Add({ { "packet_type", "error" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ack_out { packets.Add({ { "packet_type", "ack" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_qos_out { packets.Add({ { "packet_type", "qos" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_hello_out { packets.Add({ { "packet_type", "hello" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ok_out { packets.Add({ { "packet_type", "ok" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_whois_out { packets.Add({ { "packet_type", "whois" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_rendezvous_out { packets.Add({ { "packet_type", "rendezvous" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_frame_out { packets.Add({ { "packet_type", "frame" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_ext_frame_out { packets.Add({ { "packet_type", "ext_frame" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_echo_out { packets.Add({ { "packet_type", "echo" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_like_out { packets.Add({ { "packet_type", "multicast_like" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_credentials_out { packets.Add({ { "packet_type", "network_credentials" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_request_out { packets.Add({ { "packet_type", "network_config_request" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_network_config_out { packets.Add({ { "packet_type", "network_config" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out { packets.Add({ { "packet_type", "multicast_gather" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out { packets.Add({ { "packet_type", "multicast_frame" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out { packets.Add({ { "packet_type", "push_direct_paths" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_user_message_out { packets.Add({ { "packet_type", "user_message" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_remote_trace_out { packets.Add({ { "packet_type", "remote_trace" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out { packets.Add({ { "packet_type", "path_negotiation_request" }, { "direction", "tx" } }) };
|
||||
|
||||
// Packet Error Counts
|
||||
prometheus::simpleapi::counter_family_t packet_errors
|
||||
{ "zt_packet_error", "ZeroTier packet errors"};
|
||||
prometheus::simpleapi::counter_family_t packet_errors { "zt_packet_error", "ZeroTier packet errors" };
|
||||
|
||||
// Incoming Error Counts
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in
|
||||
{ packet_errors.Add({{"error_type", "obj_not_found"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in
|
||||
{ packet_errors.Add({{"error_type", "unsupported_operation"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in
|
||||
{ packet_errors.Add({{"error_type", "identity_collision"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in
|
||||
{ packet_errors.Add({{"error_type", "need_membership_certificate"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in
|
||||
{ packet_errors.Add({{"error_type", "network_access_denied"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in
|
||||
{ packet_errors.Add({{"error_type", "unwanted_multicast"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in
|
||||
{ packet_errors.Add({{"error_type", "authentication_required"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in
|
||||
{ packet_errors.Add({{"error_type", "internal_server_error"}, {"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in { packet_errors.Add({ { "error_type", "obj_not_found" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in { packet_errors.Add({ { "error_type", "unsupported_operation" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in { packet_errors.Add({ { "error_type", "identity_collision" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in { packet_errors.Add({ { "error_type", "need_membership_certificate" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in { packet_errors.Add({ { "error_type", "network_access_denied" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in { packet_errors.Add({ { "error_type", "unwanted_multicast" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in { packet_errors.Add({ { "error_type", "authentication_required" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in { packet_errors.Add({ { "error_type", "internal_server_error" }, { "direction", "rx" } }) };
|
||||
|
||||
// Outgoing Error Counts
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out
|
||||
{ packet_errors.Add({{"error_type", "obj_not_found"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out
|
||||
{ packet_errors.Add({{"error_type", "unsupported_operation"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out
|
||||
{ packet_errors.Add({{"error_type", "identity_collision"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out
|
||||
{ packet_errors.Add({{"error_type", "need_membership_certificate"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out
|
||||
{ packet_errors.Add({{"error_type", "network_access_denied"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out
|
||||
{ packet_errors.Add({{"error_type", "unwanted_multicast"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out
|
||||
{ packet_errors.Add({{"error_type", "authentication_required"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out
|
||||
{ packet_errors.Add({{"error_type", "internal_server_error"}, {"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out { packet_errors.Add({ { "error_type", "obj_not_found" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out { packet_errors.Add({ { "error_type", "unsupported_operation" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out { packet_errors.Add({ { "error_type", "identity_collision" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out { packet_errors.Add({ { "error_type", "need_membership_certificate" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out { packet_errors.Add({ { "error_type", "network_access_denied" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out { packet_errors.Add({ { "error_type", "unwanted_multicast" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out { packet_errors.Add({ { "error_type", "authentication_required" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out { packet_errors.Add({ { "error_type", "internal_server_error" }, { "direction", "tx" } }) };
|
||||
|
||||
// Data Sent/Received Metrics
|
||||
prometheus::simpleapi::counter_family_t data
|
||||
{ "zt_data", "number of bytes ZeroTier has transmitted or received" };
|
||||
prometheus::simpleapi::counter_metric_t udp_recv
|
||||
{ data.Add({{"protocol","udp"},{"direction","rx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t udp_send
|
||||
{ data.Add({{"protocol","udp"},{"direction","tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t tcp_send
|
||||
{ data.Add({{"protocol","tcp"},{"direction", "tx"}}) };
|
||||
prometheus::simpleapi::counter_metric_t tcp_recv
|
||||
{ data.Add({{"protocol","tcp"},{"direction", "rx"}}) };
|
||||
prometheus::simpleapi::counter_family_t data { "zt_data", "number of bytes ZeroTier has transmitted or received" };
|
||||
prometheus::simpleapi::counter_metric_t udp_recv { data.Add({ { "protocol", "udp" }, { "direction", "rx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t udp_send { data.Add({ { "protocol", "udp" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t tcp_send { data.Add({ { "protocol", "tcp" }, { "direction", "tx" } }) };
|
||||
prometheus::simpleapi::counter_metric_t tcp_recv { data.Add({ { "protocol", "tcp" }, { "direction", "rx" } }) };
|
||||
|
||||
// Network Metrics
|
||||
prometheus::simpleapi::gauge_metric_t network_num_joined
|
||||
{ "zt_num_networks", "number of networks this instance is joined to" };
|
||||
prometheus::simpleapi::gauge_family_t network_num_multicast_groups
|
||||
{ "zt_network_multicast_groups_subscribed", "number of multicast groups networks are subscribed to" };
|
||||
prometheus::simpleapi::counter_family_t network_packets
|
||||
{ "zt_network_packets", "number of incoming/outgoing packets per network" };
|
||||
prometheus::simpleapi::gauge_metric_t network_num_joined { "zt_num_networks", "number of networks this instance is joined to" };
|
||||
prometheus::simpleapi::gauge_family_t network_num_multicast_groups { "zt_network_multicast_groups_subscribed", "number of multicast groups networks are subscribed to" };
|
||||
prometheus::simpleapi::counter_family_t network_packets { "zt_network_packets", "number of incoming/outgoing packets per network" };
|
||||
|
||||
#ifndef ZT_NO_PEER_METRICS
|
||||
// PeerMetrics
|
||||
prometheus::CustomFamily<prometheus::Histogram<uint64_t>> &peer_latency =
|
||||
prometheus::Builder<prometheus::Histogram<uint64_t>>()
|
||||
.Name("zt_peer_latency")
|
||||
.Help("peer latency (ms)")
|
||||
.Register(prometheus::simpleapi::registry);
|
||||
prometheus::CustomFamily<prometheus::Histogram<uint64_t> >& peer_latency = prometheus::Builder<prometheus::Histogram<uint64_t> >().Name("zt_peer_latency").Help("peer latency (ms)").Register(prometheus::simpleapi::registry);
|
||||
|
||||
prometheus::simpleapi::gauge_family_t peer_path_count
|
||||
{ "zt_peer_path_count", "number of paths to peer" };
|
||||
prometheus::simpleapi::counter_family_t peer_packets
|
||||
{ "zt_peer_packets", "number of packets to/from a peer" };
|
||||
prometheus::simpleapi::counter_family_t peer_packet_errors
|
||||
{ "zt_peer_packet_errors" , "number of incoming packet errors from a peer" };
|
||||
prometheus::simpleapi::gauge_family_t peer_path_count { "zt_peer_path_count", "number of paths to peer" };
|
||||
prometheus::simpleapi::counter_family_t peer_packets { "zt_peer_packets", "number of packets to/from a peer" };
|
||||
prometheus::simpleapi::counter_family_t peer_packet_errors { "zt_peer_packet_errors", "number of incoming packet errors from a peer" };
|
||||
#endif
|
||||
|
||||
// General Controller Metrics
|
||||
prometheus::simpleapi::gauge_metric_t network_count
|
||||
{"controller_network_count", "number of networks the controller is serving"};
|
||||
prometheus::simpleapi::gauge_metric_t member_count
|
||||
{"controller_member_count", "number of network members the controller is serving"};
|
||||
prometheus::simpleapi::counter_metric_t network_changes
|
||||
{"controller_network_change_count", "number of times a network configuration is changed"};
|
||||
prometheus::simpleapi::counter_metric_t member_changes
|
||||
{"controller_member_change_count", "number of times a network member configuration is changed"};
|
||||
prometheus::simpleapi::counter_metric_t member_auths
|
||||
{"controller_member_auth_count", "number of network member auths"};
|
||||
prometheus::simpleapi::counter_metric_t member_deauths
|
||||
{"controller_member_deauth_count", "number of network member deauths"};
|
||||
prometheus::simpleapi::gauge_metric_t network_count { "controller_network_count", "number of networks the controller is serving" };
|
||||
prometheus::simpleapi::gauge_metric_t member_count { "controller_member_count", "number of network members the controller is serving" };
|
||||
prometheus::simpleapi::counter_metric_t network_changes { "controller_network_change_count", "number of times a network configuration is changed" };
|
||||
prometheus::simpleapi::counter_metric_t member_changes { "controller_member_change_count", "number of times a network member configuration is changed" };
|
||||
prometheus::simpleapi::counter_metric_t member_auths { "controller_member_auth_count", "number of network member auths" };
|
||||
prometheus::simpleapi::counter_metric_t member_deauths { "controller_member_deauth_count", "number of network member deauths" };
|
||||
|
||||
prometheus::simpleapi::gauge_metric_t network_config_request_queue_size
|
||||
{ "controller_network_config_request_queue", "number of entries in the request queue for network configurations" };
|
||||
prometheus::simpleapi::gauge_metric_t network_config_request_queue_size { "controller_network_config_request_queue", "number of entries in the request queue for network configurations" };
|
||||
|
||||
prometheus::simpleapi::counter_metric_t sso_expiration_checks
|
||||
{ "controller_sso_expiration_checks", "number of sso expiration checks done" };
|
||||
prometheus::simpleapi::counter_metric_t sso_expiration_checks { "controller_sso_expiration_checks", "number of sso expiration checks done" };
|
||||
|
||||
prometheus::simpleapi::counter_metric_t sso_member_deauth
|
||||
{ "controller_sso_timeouts", "number of sso timeouts" };
|
||||
prometheus::simpleapi::counter_metric_t sso_member_deauth { "controller_sso_timeouts", "number of sso timeouts" };
|
||||
|
||||
prometheus::simpleapi::counter_metric_t network_config_request
|
||||
{ "controller_network_config_request", "count of config requests handled" };
|
||||
prometheus::simpleapi::gauge_metric_t network_config_request_threads
|
||||
{ "controller_network_config_request_threads", "number of active network config handling threads" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network
|
||||
{ "controller_db_get_network", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_and_member
|
||||
{ "controller_db_get_network_and_member", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary
|
||||
{ "controller_db_get_networK_and_member_summary", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_member_list
|
||||
{ "controller_db_get_member_list", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_list
|
||||
{ "controller_db_get_network_list", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_member_change
|
||||
{ "controller_db_member_change", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_network_change
|
||||
{ "controller_db_network_change", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t network_config_request { "controller_network_config_request", "count of config requests handled" };
|
||||
prometheus::simpleapi::gauge_metric_t network_config_request_threads { "controller_network_config_request_threads", "number of active network config handling threads" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network { "controller_db_get_network", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_and_member { "controller_db_get_network_and_member", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary { "controller_db_get_networK_and_member_summary", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_member_list { "controller_db_get_member_list", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_network_list { "controller_db_get_network_list", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_member_change { "controller_db_member_change", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t db_network_change { "controller_db_network_change", "counter" };
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
// Central Controller Metrics
|
||||
prometheus::simpleapi::counter_metric_t pgsql_mem_notification
|
||||
{ "controller_pgsql_member_notifications_received", "number of member change notifications received via pgsql NOTIFY" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_net_notification
|
||||
{ "controller_pgsql_network_notifications_received", "number of network change notifications received via pgsql NOTIFY" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_node_checkin
|
||||
{ "controller_pgsql_node_checkin_count", "number of node check-ins (pgsql)" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_commit_ticks
|
||||
{ "controller_pgsql_commit_ticks", "number of commit ticks run (pgsql)" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_sso_info
|
||||
{ "controller_db_get_sso_info", "counter" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_mem_notification { "controller_pgsql_member_notifications_received", "number of member change notifications received via pgsql NOTIFY" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_net_notification { "controller_pgsql_network_notifications_received", "number of network change notifications received via pgsql NOTIFY" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_node_checkin { "controller_pgsql_node_checkin_count", "number of node check-ins (pgsql)" };
|
||||
prometheus::simpleapi::counter_metric_t pgsql_commit_ticks { "controller_pgsql_commit_ticks", "number of commit ticks run (pgsql)" };
|
||||
prometheus::simpleapi::counter_metric_t db_get_sso_info { "controller_db_get_sso_info", "counter" };
|
||||
|
||||
prometheus::simpleapi::counter_metric_t redis_mem_notification
|
||||
{ "controller_redis_member_notifications_received", "number of member change notifications received via redis" };
|
||||
prometheus::simpleapi::counter_metric_t redis_net_notification
|
||||
{ "controller_redis_network_notifications_received", "number of network change notifications received via redis" };
|
||||
prometheus::simpleapi::counter_metric_t redis_node_checkin
|
||||
{ "controller_redis_node_checkin_count", "number of node check-ins (redis)" };
|
||||
prometheus::simpleapi::counter_metric_t redis_mem_notification { "controller_redis_member_notifications_received", "number of member change notifications received via redis" };
|
||||
prometheus::simpleapi::counter_metric_t redis_net_notification { "controller_redis_network_notifications_received", "number of network change notifications received via redis" };
|
||||
prometheus::simpleapi::counter_metric_t redis_node_checkin { "controller_redis_node_checkin_count", "number of node check-ins (redis)" };
|
||||
|
||||
// Central DB Pool Metrics
|
||||
prometheus::simpleapi::counter_metric_t conn_counter
|
||||
{ "controller_pgsql_connections_created", "number of pgsql connections created"};
|
||||
prometheus::simpleapi::counter_metric_t max_pool_size
|
||||
{ "controller_pgsql_max_conn_pool_size", "max connection pool size for postgres"};
|
||||
prometheus::simpleapi::counter_metric_t min_pool_size
|
||||
{ "controller_pgsql_min_conn_pool_size", "minimum connection pool size for postgres" };
|
||||
prometheus::simpleapi::gauge_metric_t pool_avail
|
||||
{ "controller_pgsql_available_conns", "number of available postgres connections" };
|
||||
prometheus::simpleapi::gauge_metric_t pool_in_use
|
||||
{ "controller_pgsql_in_use_conns", "number of postgres database connections in use" };
|
||||
prometheus::simpleapi::counter_metric_t pool_errors
|
||||
{ "controller_pgsql_connection_errors", "number of connection errors the connection pool has seen" };
|
||||
prometheus::simpleapi::counter_metric_t conn_counter { "controller_pgsql_connections_created", "number of pgsql connections created" };
|
||||
prometheus::simpleapi::counter_metric_t max_pool_size { "controller_pgsql_max_conn_pool_size", "max connection pool size for postgres" };
|
||||
prometheus::simpleapi::counter_metric_t min_pool_size { "controller_pgsql_min_conn_pool_size", "minimum connection pool size for postgres" };
|
||||
prometheus::simpleapi::gauge_metric_t pool_avail { "controller_pgsql_available_conns", "number of available postgres connections" };
|
||||
prometheus::simpleapi::gauge_metric_t pool_in_use { "controller_pgsql_in_use_conns", "number of postgres database connections in use" };
|
||||
prometheus::simpleapi::counter_metric_t pool_errors { "controller_pgsql_connection_errors", "number of connection errors the connection pool has seen" };
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Metrics
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
#ifndef METRICS_H_
|
||||
#define METRICS_H_
|
||||
|
||||
#include <prometheus/simpleapi.h>
|
||||
#include <prometheus/histogram.h>
|
||||
#include <prometheus/simpleapi.h>
|
||||
|
||||
namespace prometheus {
|
||||
namespace simpleapi {
|
||||
extern std::shared_ptr<Registry> registry_ptr;
|
||||
}
|
||||
}
|
||||
} // namespace prometheus
|
||||
|
||||
namespace ZeroTier {
|
||||
namespace Metrics {
|
||||
|
@ -137,7 +137,6 @@ namespace ZeroTier {
|
|||
extern prometheus::simpleapi::counter_metric_t db_member_change;
|
||||
extern prometheus::simpleapi::counter_metric_t db_network_change;
|
||||
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
// Central Controller Metrics
|
||||
extern prometheus::simpleapi::counter_metric_t pgsql_mem_notification;
|
||||
|
@ -150,8 +149,6 @@ namespace ZeroTier {
|
|||
extern prometheus::simpleapi::counter_metric_t redis_net_notification;
|
||||
extern prometheus::simpleapi::counter_metric_t redis_node_checkin;
|
||||
|
||||
|
||||
|
||||
// Central DB Pool Metrics
|
||||
extern prometheus::simpleapi::counter_metric_t conn_counter;
|
||||
extern prometheus::simpleapi::counter_metric_t max_pool_size;
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#ifndef ZT_MULTICASTGROUP_HPP
|
||||
#define ZT_MULTICASTGROUP_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "MAC.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -36,18 +36,13 @@ namespace ZeroTier {
|
|||
*
|
||||
* MulticastGroup behaves as an immutable value object.
|
||||
*/
|
||||
class MulticastGroup
|
||||
{
|
||||
class MulticastGroup {
|
||||
public:
|
||||
MulticastGroup() :
|
||||
_mac(),
|
||||
_adi(0)
|
||||
MulticastGroup() : _mac(), _adi(0)
|
||||
{
|
||||
}
|
||||
|
||||
MulticastGroup(const MAC &m,uint32_t a) :
|
||||
_mac(m),
|
||||
_adi(a)
|
||||
MulticastGroup(const MAC& m, uint32_t a) : _mac(m), _adi(a)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -65,7 +60,8 @@ public:
|
|||
// ADI was added, as well as handling other things that want mindless
|
||||
// Ethernet broadcast to all.
|
||||
return MulticastGroup(MAC(0xffffffffffffULL), Utils::ntoh(*((const uint32_t*)ip.rawIpData())));
|
||||
} else if (ip.isV6()) {
|
||||
}
|
||||
else if (ip.isV6()) {
|
||||
// IPv6 is better designed in this respect. We can compute the IPv6
|
||||
// multicast address directly from the IP address, and it gives us
|
||||
// 24 bits of uniqueness. Collisions aren't likely to be common enough
|
||||
|
@ -79,29 +75,54 @@ public:
|
|||
/**
|
||||
* @return Multicast address
|
||||
*/
|
||||
inline const MAC &mac() const { return _mac; }
|
||||
inline const MAC& mac() const
|
||||
{
|
||||
return _mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Additional distinguishing information
|
||||
*/
|
||||
inline uint32_t adi() const { return _adi; }
|
||||
inline uint32_t adi() const
|
||||
{
|
||||
return _adi;
|
||||
}
|
||||
|
||||
inline unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); }
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (_mac.hashCode() ^ (unsigned long)_adi);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
if (_mac < g._mac) {
|
||||
return true;
|
||||
} else if (_mac == g._mac) {
|
||||
}
|
||||
else if (_mac == g._mac) {
|
||||
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); }
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
MAC _mac;
|
||||
|
|
|
@ -11,24 +11,23 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Multicaster::Multicaster(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_groups(32)
|
||||
Multicaster::Multicaster(const RuntimeEnvironment* renv) : RR(renv), _groups(32)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,7 +69,8 @@ unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const
|
|||
|
||||
if (! limit) {
|
||||
return 0;
|
||||
} else if (limit > 0xffff) {
|
||||
}
|
||||
else if (limit > 0xffff) {
|
||||
limit = 0xffff;
|
||||
}
|
||||
|
||||
|
@ -145,16 +145,7 @@ std::vector<Address> Multicaster::getMembers(uint64_t nwid,const MulticastGroup
|
|||
return ls;
|
||||
}
|
||||
|
||||
void Multicaster::send(
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
const SharedPtr<Network> &network,
|
||||
const Address &origin,
|
||||
const MulticastGroup &mg,
|
||||
const MAC &src,
|
||||
unsigned int etherType,
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
void Multicaster::send(void* tPtr, int64_t now, const SharedPtr<Network>& network, const Address& origin, const MulticastGroup& mg, const MAC& src, unsigned int etherType, const void* data, unsigned int len)
|
||||
{
|
||||
unsigned long idxbuf[4096];
|
||||
unsigned long* indexes = idxbuf;
|
||||
|
@ -269,7 +260,8 @@ void Multicaster::send(
|
|||
++count;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
while (gs.txQueue.size() >= ZT_TX_QUEUE_SIZE) {
|
||||
gs.txQueue.pop_front();
|
||||
}
|
||||
|
@ -341,18 +333,7 @@ void Multicaster::send(
|
|||
gs.txQueue.push_back(OutboundMulticast());
|
||||
OutboundMulticast& out = gs.txQueue.back();
|
||||
|
||||
out.init(
|
||||
RR,
|
||||
now,
|
||||
network->id(),
|
||||
network->config().disableCompression(),
|
||||
limit,
|
||||
gatherLimit,
|
||||
src,
|
||||
mg,
|
||||
etherType,
|
||||
data,
|
||||
len);
|
||||
out.init(RR, now, network->id(), network->config().disableCompression(), limit, gatherLimit, src, mg, etherType, data, len);
|
||||
|
||||
if (origin) {
|
||||
out.logAsSent(origin);
|
||||
|
@ -378,7 +359,9 @@ void Multicaster::send(
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {} // this is a sanity check to catch any failures and make sure indexes[] still gets deleted
|
||||
}
|
||||
catch (...) {
|
||||
} // this is a sanity check to catch any failures and make sure indexes[] still gets deleted
|
||||
|
||||
// Free allocated memory buffer if any
|
||||
if (indexes != idxbuf) {
|
||||
|
@ -396,7 +379,8 @@ void Multicaster::clean(int64_t now)
|
|||
for (std::list<OutboundMulticast>::iterator tx(s->txQueue.begin()); tx != s->txQueue.end();) {
|
||||
if ((tx->expired(now)) || (tx->atLimit())) {
|
||||
s->txQueue.erase(tx++);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++tx;
|
||||
}
|
||||
}
|
||||
|
@ -417,9 +401,11 @@ void Multicaster::clean(int64_t now)
|
|||
|
||||
if (count) {
|
||||
s->members.resize(count);
|
||||
} else if (s->txQueue.empty()) {
|
||||
}
|
||||
else if (s->txQueue.empty()) {
|
||||
_groups.erase(*k);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
s->members.clear();
|
||||
}
|
||||
}
|
||||
|
@ -441,18 +427,21 @@ void Multicaster::_add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup
|
|||
return;
|
||||
}
|
||||
gs.members.insert(m, MulticastGroupMember(member, now));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
gs.members.push_back(MulticastGroupMember(member, now));
|
||||
}
|
||||
|
||||
for (std::list<OutboundMulticast>::iterator tx(gs.txQueue.begin()); tx != gs.txQueue.end();) {
|
||||
if (tx->atLimit()) {
|
||||
gs.txQueue.erase(tx++);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
tx->sendIfNew(RR, tPtr, member);
|
||||
if (tx->atLimit()) {
|
||||
gs.txQueue.erase(tx++);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++tx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,22 +14,21 @@
|
|||
#ifndef ZT_MULTICASTER_HPP
|
||||
#define ZT_MULTICASTER_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "OutboundMulticast.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "OutboundMulticast.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -41,8 +40,7 @@ class Network;
|
|||
/**
|
||||
* Database of known multicast peers within a network
|
||||
*/
|
||||
class Multicaster
|
||||
{
|
||||
class Multicaster {
|
||||
public:
|
||||
Multicaster(const RuntimeEnvironment* renv);
|
||||
~Multicaster();
|
||||
|
@ -126,16 +124,7 @@ public:
|
|||
* @param data Packet data
|
||||
* @param len Length of packet data
|
||||
*/
|
||||
void send(
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
const SharedPtr<Network> &network,
|
||||
const Address &origin,
|
||||
const MulticastGroup &mg,
|
||||
const MAC &src,
|
||||
unsigned int etherType,
|
||||
const void *data,
|
||||
unsigned int len);
|
||||
void send(void* tPtr, int64_t now, const SharedPtr<Network>& network, const Address& origin, const MulticastGroup& mg, const MAC& src, unsigned int etherType, const void* data, unsigned int len);
|
||||
|
||||
/**
|
||||
* Clean database
|
||||
|
@ -146,38 +135,72 @@ public:
|
|||
void clean(int64_t now);
|
||||
|
||||
private:
|
||||
struct Key
|
||||
struct Key {
|
||||
Key() : nwid(0), mg()
|
||||
{
|
||||
Key() : nwid(0),mg() {}
|
||||
Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
|
||||
}
|
||||
Key(uint64_t n, const MulticastGroup& g) : nwid(n), mg(g)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t nwid;
|
||||
MulticastGroup mg;
|
||||
|
||||
inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
|
||||
inline bool operator!=(const Key &k) const { return ((nwid != k.nwid)||(mg != k.mg)); }
|
||||
inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
|
||||
inline bool operator==(const Key& k) const
|
||||
{
|
||||
return ((nwid == k.nwid) && (mg == k.mg));
|
||||
}
|
||||
inline bool operator!=(const Key& k) const
|
||||
{
|
||||
return ((nwid != k.nwid) || (mg != k.mg));
|
||||
}
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32)));
|
||||
}
|
||||
};
|
||||
|
||||
struct MulticastGroupMember
|
||||
struct MulticastGroupMember {
|
||||
MulticastGroupMember()
|
||||
{
|
||||
MulticastGroupMember() {}
|
||||
MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
|
||||
}
|
||||
MulticastGroupMember(const Address& a, uint64_t ts) : address(a), timestamp(ts)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool operator<(const MulticastGroupMember &a) const { return (address < a.address); }
|
||||
inline bool operator==(const MulticastGroupMember &a) const { return (address == a.address); }
|
||||
inline bool operator!=(const MulticastGroupMember &a) const { return (address != a.address); }
|
||||
inline bool operator<(const Address &a) const { return (address < a); }
|
||||
inline bool operator==(const Address &a) const { return (address == a); }
|
||||
inline bool operator!=(const Address &a) const { return (address != a); }
|
||||
inline bool operator<(const MulticastGroupMember& a) const
|
||||
{
|
||||
return (address < a.address);
|
||||
}
|
||||
inline bool operator==(const MulticastGroupMember& a) const
|
||||
{
|
||||
return (address == a.address);
|
||||
}
|
||||
inline bool operator!=(const MulticastGroupMember& a) const
|
||||
{
|
||||
return (address != a.address);
|
||||
}
|
||||
inline bool operator<(const Address& a) const
|
||||
{
|
||||
return (address < a);
|
||||
}
|
||||
inline bool operator==(const Address& a) const
|
||||
{
|
||||
return (address == a);
|
||||
}
|
||||
inline bool operator!=(const Address& a) const
|
||||
{
|
||||
return (address != a);
|
||||
}
|
||||
|
||||
Address address;
|
||||
int64_t timestamp; // time of last notification
|
||||
};
|
||||
|
||||
struct MulticastGroupStatus
|
||||
struct MulticastGroupStatus {
|
||||
MulticastGroupStatus() : lastExplicitGather(0)
|
||||
{
|
||||
MulticastGroupStatus() : lastExplicitGather(0) {}
|
||||
}
|
||||
|
||||
int64_t lastExplicitGather;
|
||||
std::list<OutboundMulticast> txQueue; // pending outbound multicasts
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
|
||||
#ifdef __UNIX_LIKE__
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
// libpthread based mutex lock
|
||||
class Mutex
|
||||
{
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex()
|
||||
{
|
||||
|
@ -48,17 +47,14 @@ public:
|
|||
pthread_mutex_unlock(&((const_cast<Mutex*>(this))->_mh));
|
||||
}
|
||||
|
||||
class Lock
|
||||
{
|
||||
class Lock {
|
||||
public:
|
||||
Lock(Mutex &m) :
|
||||
_m(&m)
|
||||
Lock(Mutex& m) : _m(&m)
|
||||
{
|
||||
m.lock();
|
||||
}
|
||||
|
||||
Lock(const Mutex &m) :
|
||||
_m(const_cast<Mutex *>(&m))
|
||||
Lock(const Mutex& m) : _m(const_cast<Mutex*>(&m))
|
||||
{
|
||||
_m->lock();
|
||||
}
|
||||
|
@ -73,8 +69,13 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
Mutex(const Mutex &) {}
|
||||
const Mutex &operator=(const Mutex &) { return *this; }
|
||||
Mutex(const Mutex&)
|
||||
{
|
||||
}
|
||||
const Mutex& operator=(const Mutex&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
pthread_mutex_t _mh;
|
||||
};
|
||||
|
@ -91,8 +92,7 @@ private:
|
|||
namespace ZeroTier {
|
||||
|
||||
// Windows critical section based lock
|
||||
class Mutex
|
||||
{
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex()
|
||||
{
|
||||
|
@ -124,17 +124,14 @@ public:
|
|||
(const_cast<Mutex*>(this))->unlock();
|
||||
}
|
||||
|
||||
class Lock
|
||||
{
|
||||
class Lock {
|
||||
public:
|
||||
Lock(Mutex &m) :
|
||||
_m(&m)
|
||||
Lock(Mutex& m) : _m(&m)
|
||||
{
|
||||
m.lock();
|
||||
}
|
||||
|
||||
Lock(const Mutex &m) :
|
||||
_m(const_cast<Mutex *>(&m))
|
||||
Lock(const Mutex& m) : _m(const_cast<Mutex*>(&m))
|
||||
{
|
||||
_m->lock();
|
||||
}
|
||||
|
@ -149,8 +146,13 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
Mutex(const Mutex &) {}
|
||||
const Mutex &operator=(const Mutex &) { return *this; }
|
||||
Mutex(const Mutex&)
|
||||
{
|
||||
}
|
||||
const Mutex& operator=(const Mutex&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
CRITICAL_SECTION _cs;
|
||||
};
|
||||
|
|
383
node/Network.cpp
383
node/Network.cpp
|
@ -11,31 +11,30 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "Network.hpp"
|
||||
|
||||
#include "../include/ZeroTierDebug.h"
|
||||
|
||||
#include "ECC.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "../version.h"
|
||||
#include "Network.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Metrics.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <set>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -72,14 +71,7 @@ static inline bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLe
|
|||
return false; // overflow == invalid
|
||||
}
|
||||
|
||||
enum _doZtFilterResult
|
||||
{
|
||||
DOZTFILTER_NO_MATCH,
|
||||
DOZTFILTER_DROP,
|
||||
DOZTFILTER_REDIRECT,
|
||||
DOZTFILTER_ACCEPT,
|
||||
DOZTFILTER_SUPER_ACCEPT
|
||||
};
|
||||
enum _doZtFilterResult { DOZTFILTER_NO_MATCH, DOZTFILTER_DROP, DOZTFILTER_REDIRECT, DOZTFILTER_ACCEPT, DOZTFILTER_SUPER_ACCEPT };
|
||||
|
||||
static _doZtFilterResult _doZtFilter(
|
||||
const RuntimeEnvironment* RR,
|
||||
|
@ -138,7 +130,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
#ifdef ZT_TRACE
|
||||
// fprintf(stderr, "\tskip Drop");
|
||||
#endif
|
||||
skipDrop = 0; continue;
|
||||
skipDrop = 0;
|
||||
continue;
|
||||
}
|
||||
#ifdef ZT_TRACE
|
||||
// fprintf(stderr, "\tDrop\n");
|
||||
|
@ -160,23 +153,29 @@ static _doZtFilterResult _doZtFilter(
|
|||
const Address fwdAddr(rules[rn].v.fwd.address);
|
||||
if (fwdAddr == ztSource) {
|
||||
// Skip as no-op since source is target
|
||||
} else if (fwdAddr == RR->identity.address()) {
|
||||
}
|
||||
else if (fwdAddr == RR->identity.address()) {
|
||||
if (inbound) {
|
||||
return DOZTFILTER_SUPER_ACCEPT;
|
||||
} else {
|
||||
}
|
||||
} else if (fwdAddr == ztDest) {
|
||||
} else {
|
||||
else {
|
||||
}
|
||||
}
|
||||
else if (fwdAddr == ztDest) {
|
||||
}
|
||||
else {
|
||||
if (rt == ZT_NETWORK_RULE_ACTION_REDIRECT) {
|
||||
ztDest = fwdAddr;
|
||||
return DOZTFILTER_REDIRECT;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cc = fwdAddr;
|
||||
ccLength = (rules[rn].v.fwd.length != 0) ? ((frameLen < (unsigned int)rules[rn].v.fwd.length) ? frameLen : (unsigned int)rules[rn].v.fwd.length) : frameLen;
|
||||
ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH);
|
||||
}
|
||||
}
|
||||
} continue;
|
||||
}
|
||||
continue;
|
||||
|
||||
case ZT_NETWORK_RULE_ACTION_BREAK:
|
||||
return DOZTFILTER_NO_MATCH;
|
||||
|
@ -185,7 +184,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
default:
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// If this is an incoming packet and we are a TEE or REDIRECT target, we should
|
||||
// super-accept if we accept at all. This will cause us to accept redirected or
|
||||
// tee'd packets in spite of MAC and ZT addressing checks.
|
||||
|
@ -248,28 +248,32 @@ static _doZtFilterResult _doZtFilter(
|
|||
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void*)&(rules[rn].v.ipv4.ip), 4, rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void*)(frameData + 12), 4, 0)));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void*)&(rules[rn].v.ipv4.ip), 4, rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void*)(frameData + 16), 4, 0)));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void*)rules[rn].v.ipv6.ip, 16, rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void*)(frameData + 8), 16, 0)));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void*)rules[rn].v.ipv6.ip, 16, rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void*)(frameData + 24), 16, 0)));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
|
@ -277,24 +281,29 @@ static _doZtFilterResult _doZtFilter(
|
|||
if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
||||
const uint8_t tosMasked = frameData[1] & rules[rn].v.ipTos.mask;
|
||||
thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1]));
|
||||
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
||||
}
|
||||
else if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) {
|
||||
const uint8_t tosMasked = (((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f)) & rules[rn].v.ipTos.mask;
|
||||
thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1]));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
||||
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == frameData[9]);
|
||||
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
}
|
||||
else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
unsigned int pos = 0, proto = 0;
|
||||
if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
||||
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
|
@ -309,38 +318,48 @@ static _doZtFilterResult _doZtFilter(
|
|||
if (rules[rn].v.icmp.type == frameData[ihl]) {
|
||||
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
||||
thisRuleMatches = (uint8_t)(frameData[ihl + 1] == rules[rn].v.icmp.code);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardYes;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
}
|
||||
else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
unsigned int pos = 0, proto = 0;
|
||||
if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
||||
if ((proto == 0x3a) && (frameLen >= (pos + 2))) {
|
||||
if (rules[rn].v.icmp.type == frameData[pos]) {
|
||||
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
||||
thisRuleMatches = (uint8_t)(frameData[pos + 1] == rules[rn].v.icmp.code);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardYes;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
|
@ -364,7 +383,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
}
|
||||
|
||||
thisRuleMatches = (p >= 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0]) && (p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
|
||||
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
}
|
||||
else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
unsigned int pos = 0, proto = 0;
|
||||
if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
||||
int p = -1;
|
||||
|
@ -384,10 +404,12 @@ static _doZtFilterResult _doZtFilter(
|
|||
break;
|
||||
}
|
||||
thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0]) && (p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
|
@ -404,7 +426,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
InetAddress src;
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
||||
src.set((const void*)(frameData + 12), 4, 0);
|
||||
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
||||
}
|
||||
else if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) {
|
||||
// IPv6 NDP requires special handling, since the src and dest IPs in the packet are empty or link-local.
|
||||
if ((frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87) || (frameData[40] == 0x88))) {
|
||||
if (frameData[40] == 0x87) {
|
||||
|
@ -412,15 +435,18 @@ static _doZtFilterResult _doZtFilter(
|
|||
// hack by considering them authenticated. Otherwise you would pretty much have to do
|
||||
// this manually in the rule set for IPv6 to work at all.
|
||||
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Neighbor advertisements on the other hand can absolutely be authenticated.
|
||||
src.set((const void*)(frameData + 40 + 8), 16, 0);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Other IPv6 packets can be handled normally
|
||||
src.set((const void*)(frameData + 8), 16, 0);
|
||||
}
|
||||
} else if ((etherType == ZT_ETHERTYPE_ARP)&&(frameLen >= 28)) {
|
||||
}
|
||||
else if ((etherType == ZT_ETHERTYPE_ARP) && (frameLen >= 28)) {
|
||||
src.set((const void*)(frameData + 14), 4, 0);
|
||||
}
|
||||
if (inbound) {
|
||||
|
@ -432,7 +458,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (unsigned int i = 0; i < nconf.certificateOfOwnershipCount; ++i) {
|
||||
if ((src) && (nconf.certificatesOfOwnership[i].owns(src))) {
|
||||
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
||||
|
@ -448,7 +475,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
const unsigned int headerLen = 4 * (frameData[0] & 0xf);
|
||||
cf |= (uint64_t)frameData[headerLen + 13];
|
||||
cf |= (((uint64_t)(frameData[headerLen + 12] & 0x0f)) << 8);
|
||||
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
}
|
||||
else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
unsigned int pos = 0, proto = 0;
|
||||
if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
||||
if ((proto == 0x06) && (frameLen > (pos + 14))) {
|
||||
|
@ -487,24 +515,31 @@ static _doZtFilterResult _doZtFilter(
|
|||
if (rt == ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE) {
|
||||
const uint32_t diff = (ltv > rtv) ? (ltv - rtv) : (rtv - ltv);
|
||||
thisRuleMatches = (uint8_t)(diff <= rules[rn].v.tag.value);
|
||||
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND) {
|
||||
}
|
||||
else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND) {
|
||||
thisRuleMatches = (uint8_t)((ltv & rtv) == rules[rn].v.tag.value);
|
||||
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR) {
|
||||
}
|
||||
else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR) {
|
||||
thisRuleMatches = (uint8_t)((ltv | rtv) == rules[rn].v.tag.value);
|
||||
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) {
|
||||
}
|
||||
else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) {
|
||||
thisRuleMatches = (uint8_t)((ltv ^ rtv) == rules[rn].v.tag.value);
|
||||
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) {
|
||||
}
|
||||
else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) {
|
||||
thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value) && (rtv == rules[rn].v.tag.value));
|
||||
} else { // sanity check, can't really happen
|
||||
}
|
||||
else { // sanity check, can't really happen
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((inbound) && (! superAccept)) {
|
||||
thisRuleMatches = hardNo;
|
||||
#ifdef ZT_TRACE
|
||||
// fprintf(stderr, "\tinbound ");
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Outbound side is not strict since if we have to match both tags and
|
||||
// we are sending a first packet to a recipient, we probably do not know
|
||||
// about their tags yet. They will filter on inbound and we will filter
|
||||
|
@ -517,7 +552,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} break;
|
||||
|
@ -536,24 +572,29 @@ static _doZtFilterResult _doZtFilter(
|
|||
if (superAccept) {
|
||||
skipDrop = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
} else if ( ((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER)&&(inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER)&&(!inbound)) ) {
|
||||
}
|
||||
else if (((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER) && (inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) && (! inbound))) {
|
||||
const Tag* const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const Tag*)0);
|
||||
if (remoteTag) {
|
||||
thisRuleMatches = (uint8_t)(remoteTag->value() == rules[rn].v.tag.value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) {
|
||||
// If we are checking the receiver and this is an outbound packet, we
|
||||
// can't be strict since we may not yet know the receiver's tag.
|
||||
skipDrop = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
}
|
||||
} else { // sender and outbound or receiver and inbound
|
||||
}
|
||||
else { // sender and outbound or receiver and inbound
|
||||
if ((localTag != &(nconf.tags[nconf.tagCount])) && (localTag->id() == rules[rn].v.tag.id)) {
|
||||
thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
}
|
||||
|
@ -573,7 +614,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
}
|
||||
}
|
||||
integer &= 0xffffffffffffffffULL >> (64 - bits);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Little-endian
|
||||
unsigned int idx = rules[rn].v.intRange.idx;
|
||||
const unsigned int eof = idx + bytes;
|
||||
|
@ -599,7 +641,8 @@ static _doZtFilterResult _doZtFilter(
|
|||
|
||||
if ((rules[rn].t & 0x40)) {
|
||||
thisSetMatches |= (thisRuleMatches ^ ((rules[rn].t >> 7) & 1));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thisSetMatches &= (thisRuleMatches ^ ((rules[rn].t >> 7) & 1));
|
||||
}
|
||||
}
|
||||
|
@ -611,23 +654,23 @@ static _doZtFilterResult _doZtFilter(
|
|||
|
||||
const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL), 0);
|
||||
|
||||
Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr,const NetworkConfig *nconf) :
|
||||
RR(renv),
|
||||
_uPtr(uptr),
|
||||
_id(nwid),
|
||||
_nwidStr(OSUtils::networkIDStr(nwid)),
|
||||
_lastAnnouncedMulticastGroupsUpstream(0),
|
||||
_mac(renv->identity.address(),nwid),
|
||||
_portInitialized(false),
|
||||
_lastConfigUpdate(0),
|
||||
_destroyed(false),
|
||||
_netconfFailure(NETCONF_FAILURE_NONE),
|
||||
_portError(0),
|
||||
_num_multicast_groups{Metrics::network_num_multicast_groups.Add({{"network_id", _nwidStr}})},
|
||||
_incoming_packets_accepted{Metrics::network_packets.Add({{"direction","rx"},{"network_id", _nwidStr},{"accepted","yes"}})},
|
||||
_incoming_packets_dropped{Metrics::network_packets.Add({{"direction","rx"},{"network_id", _nwidStr},{"accepted","no"}})},
|
||||
_outgoing_packets_accepted{Metrics::network_packets.Add({{"direction","tx"},{"network_id", _nwidStr},{"accepted","yes"}})},
|
||||
_outgoing_packets_dropped{Metrics::network_packets.Add({{"direction","tx"},{"network_id", _nwidStr},{"accepted","no"}})}
|
||||
Network::Network(const RuntimeEnvironment* renv, void* tPtr, uint64_t nwid, void* uptr, const NetworkConfig* nconf)
|
||||
: RR(renv)
|
||||
, _uPtr(uptr)
|
||||
, _id(nwid)
|
||||
, _nwidStr(OSUtils::networkIDStr(nwid))
|
||||
, _lastAnnouncedMulticastGroupsUpstream(0)
|
||||
, _mac(renv->identity.address(), nwid)
|
||||
, _portInitialized(false)
|
||||
, _lastConfigUpdate(0)
|
||||
, _destroyed(false)
|
||||
, _netconfFailure(NETCONF_FAILURE_NONE)
|
||||
, _portError(0)
|
||||
, _num_multicast_groups { Metrics::network_num_multicast_groups.Add({ { "network_id", _nwidStr } }) }
|
||||
, _incoming_packets_accepted { Metrics::network_packets.Add({ { "direction", "rx" }, { "network_id", _nwidStr }, { "accepted", "yes" } }) }
|
||||
, _incoming_packets_dropped { Metrics::network_packets.Add({ { "direction", "rx" }, { "network_id", _nwidStr }, { "accepted", "no" } }) }
|
||||
, _outgoing_packets_accepted { Metrics::network_packets.Add({ { "direction", "tx" }, { "network_id", _nwidStr }, { "accepted", "yes" } }) }
|
||||
, _outgoing_packets_dropped { Metrics::network_packets.Add({ { "direction", "tx" }, { "network_id", _nwidStr }, { "accepted", "no" } }) }
|
||||
{
|
||||
for (int i = 0; i < ZT_NETWORK_MAX_INCOMING_UPDATES; ++i) {
|
||||
_incomingConfigChunks[i].ts = 0;
|
||||
|
@ -636,7 +679,8 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
|
|||
if (nconf) {
|
||||
this->setConfiguration(tPtr, *nconf, false);
|
||||
_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
uint64_t tmp[2];
|
||||
tmp[0] = nwid;
|
||||
tmp[1] = 0;
|
||||
|
@ -653,10 +697,14 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
|
|||
_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
|
||||
got = true;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
delete nconf;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
delete dict;
|
||||
|
||||
if (! got) {
|
||||
|
@ -683,7 +731,8 @@ Network::~Network()
|
|||
if (_destroyed) {
|
||||
// This is done in Node::leave() so we can pass tPtr properly
|
||||
// RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->node->configureVirtualNetworkPort((void*)0, _id, &_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
|
||||
}
|
||||
}
|
||||
|
@ -714,14 +763,32 @@ bool Network::filterOutgoingPacket(
|
|||
Membership* const membership = (ztDest) ? _memberships.get(ztDest) : (Membership*)0;
|
||||
|
||||
switch (_doZtFilter(RR, rrl, _config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, _config.rules, _config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
||||
|
||||
case DOZTFILTER_NO_MATCH: {
|
||||
for (unsigned int c = 0; c < _config.capabilityCount; ++c) {
|
||||
ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match
|
||||
Address cc2;
|
||||
unsigned int ccLength2 = 0;
|
||||
bool ccWatch2 = false;
|
||||
switch (_doZtFilter(RR,crrl,_config,membership,false,ztSource,ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.capabilities[c].rules(),_config.capabilities[c].ruleCount(),cc2,ccLength2,ccWatch2,qosBucket)) {
|
||||
switch (_doZtFilter(
|
||||
RR,
|
||||
crrl,
|
||||
_config,
|
||||
membership,
|
||||
false,
|
||||
ztSource,
|
||||
ztFinalDest,
|
||||
macSource,
|
||||
macDest,
|
||||
frameData,
|
||||
frameLen,
|
||||
etherType,
|
||||
vlanId,
|
||||
_config.capabilities[c].rules(),
|
||||
_config.capabilities[c].ruleCount(),
|
||||
cc2,
|
||||
ccLength2,
|
||||
ccWatch2,
|
||||
qosBucket)) {
|
||||
case DOZTFILTER_NO_MATCH:
|
||||
case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
|
||||
break;
|
||||
|
@ -794,19 +861,69 @@ bool Network::filterOutgoingPacket(
|
|||
RR->sw->send(tPtr, outp, true);
|
||||
|
||||
if (_config.remoteTraceTarget) {
|
||||
RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,0);
|
||||
RR->t->networkFilter(
|
||||
tPtr,
|
||||
*this,
|
||||
rrl,
|
||||
(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0,
|
||||
(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0,
|
||||
ztSource,
|
||||
ztDest,
|
||||
macSource,
|
||||
macDest,
|
||||
frameData,
|
||||
frameLen,
|
||||
etherType,
|
||||
vlanId,
|
||||
noTee,
|
||||
false,
|
||||
0);
|
||||
}
|
||||
return false; // DROP locally, since we redirected
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (_config.remoteTraceTarget) {
|
||||
RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,1);
|
||||
RR->t->networkFilter(
|
||||
tPtr,
|
||||
*this,
|
||||
rrl,
|
||||
(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0,
|
||||
(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0,
|
||||
ztSource,
|
||||
ztDest,
|
||||
macSource,
|
||||
macDest,
|
||||
frameData,
|
||||
frameLen,
|
||||
etherType,
|
||||
vlanId,
|
||||
noTee,
|
||||
false,
|
||||
1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_outgoing_packets_dropped++;
|
||||
if (_config.remoteTraceTarget) {
|
||||
RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,0);
|
||||
RR->t->networkFilter(
|
||||
tPtr,
|
||||
*this,
|
||||
rrl,
|
||||
(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0,
|
||||
(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0,
|
||||
ztSource,
|
||||
ztDest,
|
||||
macSource,
|
||||
macDest,
|
||||
frameData,
|
||||
frameLen,
|
||||
etherType,
|
||||
vlanId,
|
||||
noTee,
|
||||
false,
|
||||
0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -838,7 +955,6 @@ int Network::filterIncomingPacket(
|
|||
Membership& membership = _membership(sourcePeer->address());
|
||||
|
||||
switch (_doZtFilter(RR, rrl, _config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, _config.rules, _config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
||||
|
||||
case DOZTFILTER_NO_MATCH: {
|
||||
Membership::CapabilityIterator mci(membership, _config);
|
||||
while ((c = mci.next())) {
|
||||
|
@ -921,7 +1037,8 @@ int Network::filterIncomingPacket(
|
|||
}
|
||||
return 0; // DROP locally, since we redirected
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_incoming_packets_dropped++;
|
||||
}
|
||||
|
||||
|
@ -936,7 +1053,8 @@ bool Network::subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBr
|
|||
Mutex::Lock _l(_lock);
|
||||
if (std::binary_search(_myMulticastGroups.begin(), _myMulticastGroups.end(), mg)) {
|
||||
return true;
|
||||
} else if (includeBridgedGroups) {
|
||||
}
|
||||
else if (includeBridgedGroups) {
|
||||
return _multicastGroupsBehindMe.contains(mg);
|
||||
}
|
||||
return false;
|
||||
|
@ -1018,7 +1136,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
|||
}
|
||||
|
||||
break;
|
||||
} else if ((!c)||(_incomingConfigChunks[i].ts < c->ts)) {
|
||||
}
|
||||
else if ((! c) || (_incomingConfigChunks[i].ts < c->ts)) {
|
||||
c = &(_incomingConfigChunks[i]);
|
||||
}
|
||||
}
|
||||
|
@ -1045,7 +1164,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if ((source == controller())||(!source)) { // since old chunks aren't signed, only accept from controller itself (or via cluster backplane)
|
||||
}
|
||||
else if ((source == controller()) || (! source)) { // since old chunks aren't signed, only accept from controller itself (or via cluster backplane)
|
||||
// Legacy support for OK(NETWORK_CONFIG_REQUEST) from older controllers
|
||||
chunkId = packetId;
|
||||
configUpdateId = chunkId;
|
||||
|
@ -1061,7 +1181,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
|||
c = &(_incomingConfigChunks[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Single-chunk unsigned legacy configs are only allowed from the controller itself
|
||||
return 0;
|
||||
}
|
||||
|
@ -1090,7 +1211,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
|||
delete nc;
|
||||
nc = (NetworkConfig*)0;
|
||||
}
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
delete nc;
|
||||
nc = (NetworkConfig*)0;
|
||||
}
|
||||
|
@ -1101,7 +1223,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
|||
this->setConfiguration(tPtr, *nc, true);
|
||||
delete nc;
|
||||
return configUpdateId;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1150,12 +1273,16 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
|||
tmp[1] = 0;
|
||||
RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, d->data(), d->sizeBytes());
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
return 2; // OK and configuration has changed
|
||||
} catch ( ... ) {} // ignore invalid configs
|
||||
}
|
||||
catch (...) {
|
||||
} // ignore invalid configs
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1233,10 +1360,12 @@ void Network::requestConfiguration(void *tPtr)
|
|||
|
||||
this->setConfiguration(tPtr, *nconf, false);
|
||||
delete nconf;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->setNotFound(tPtr);
|
||||
}
|
||||
} else if ((_id & 0xff) == 0x01) {
|
||||
}
|
||||
else if ((_id & 0xff) == 0x01) {
|
||||
// ffAAaaaaaaaaaa01 -- where AA is the IPv4 /8 to use and aaaaaaaaaa is the anchor node for multicast gather and replication
|
||||
const uint64_t myAddress = RR->identity.address().toInt();
|
||||
const uint64_t networkHub = (_id >> 8) & 0xffffffffffULL;
|
||||
|
@ -1321,7 +1450,8 @@ void Network::requestConfiguration(void *tPtr)
|
|||
if (ctrl == RR->identity.address()) {
|
||||
if (RR->localNetworkController) {
|
||||
RR->localNetworkController->request(_id, InetAddress(), 0xffffffffffffffffULL, RR->identity, rmd);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->setNotFound(tPtr);
|
||||
}
|
||||
return;
|
||||
|
@ -1335,7 +1465,8 @@ void Network::requestConfiguration(void *tPtr)
|
|||
if (_config) {
|
||||
outp.append((uint64_t)_config.revision);
|
||||
outp.append((uint64_t)_config.timestamp);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
outp.append((unsigned char)0, 16);
|
||||
}
|
||||
outp.compress();
|
||||
|
@ -1366,7 +1497,9 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
// printf("%.16llx %.10llx not allowed, COM ts %lld revocation %lld\n", _id, peer->address().toInt(), comTimestamp, comRevocationThreshold); fflush(stdout);
|
||||
|
||||
return false;
|
||||
|
@ -1406,7 +1539,8 @@ void Network::clean()
|
|||
while (i.next(a, m)) {
|
||||
if (! RR->topology->getPeerNoCache(*a)) {
|
||||
_memberships.erase(*a);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m->clean(now, _config);
|
||||
}
|
||||
}
|
||||
|
@ -1535,7 +1669,8 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|||
ec->mac = _mac.toInt();
|
||||
if (_config) {
|
||||
Utils::scopy(ec->name, sizeof(ec->name), _config.name);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ec->name[0] = (char)0;
|
||||
}
|
||||
ec->status = _status();
|
||||
|
@ -1553,7 +1688,8 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|||
if (i < _config.staticIpCount) {
|
||||
memcpy(&(ec->assignedAddresses[i]), &(_config.staticIps[i]), sizeof(struct sockaddr_storage));
|
||||
++ec->assignedAddressCount;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memset(&(ec->assignedAddresses[i]), 0, sizeof(struct sockaddr_storage));
|
||||
}
|
||||
}
|
||||
|
@ -1563,7 +1699,8 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|||
if (i < _config.routeCount) {
|
||||
memcpy(&(ec->routes[i]), &(_config.routes[i]), sizeof(ZT_VirtualNetworkRoute));
|
||||
++ec->routeCount;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memset(&(ec->routes[i]), 0, sizeof(ZT_VirtualNetworkRoute));
|
||||
}
|
||||
}
|
||||
|
@ -1596,7 +1733,8 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
|
|||
std::vector<MulticastGroup> groups;
|
||||
if (newMulticastGroup) {
|
||||
groups.push_back(*newMulticastGroup);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
groups = _allMulticastGroups();
|
||||
}
|
||||
|
||||
|
@ -1715,7 +1853,8 @@ void Network::setAuthenticationRequired(void *tPtr, const char* issuerURL, const
|
|||
_sendUpdateEvent(tPtr);
|
||||
}
|
||||
|
||||
void Network::_sendUpdateEvent(void *tPtr) {
|
||||
void Network::_sendUpdateEvent(void* tPtr)
|
||||
{
|
||||
ZT_VirtualNetworkConfig ctmp;
|
||||
_externalConfig(&ctmp);
|
||||
RR->node->configureVirtualNetworkPort(tPtr, _id, &_uPtr, (_portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
|
||||
|
|
109
node/Network.hpp
109
node/Network.hpp
|
@ -14,30 +14,28 @@
|
|||
#ifndef ZT_NETWORK_HPP
|
||||
#define ZT_NETWORK_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "Membership.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Membership.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define ZT_NETWORK_MAX_INCOMING_UPDATES 3
|
||||
#define ZT_NETWORK_MAX_UPDATE_CHUNKS ((ZT_NETWORKCONFIG_DICT_CAPACITY / 1024) + 1)
|
||||
|
@ -50,8 +48,7 @@ class Peer;
|
|||
/**
|
||||
* A virtual LAN
|
||||
*/
|
||||
class Network
|
||||
{
|
||||
class Network {
|
||||
friend class SharedPtr<Network>;
|
||||
|
||||
public:
|
||||
|
@ -63,7 +60,10 @@ public:
|
|||
/**
|
||||
* Compute primary controller device ID from network ID
|
||||
*/
|
||||
static inline Address controllerFor(uint64_t nwid) { return Address(nwid >> 24); }
|
||||
static inline Address controllerFor(uint64_t nwid)
|
||||
{
|
||||
return Address(nwid >> 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new network
|
||||
|
@ -81,14 +81,39 @@ public:
|
|||
|
||||
~Network();
|
||||
|
||||
inline uint64_t id() const { return _id; }
|
||||
inline Address controller() const { return Address(_id >> 24); }
|
||||
inline bool multicastEnabled() const { return (_config.multicastLimit > 0); }
|
||||
inline bool hasConfig() const { return (_config); }
|
||||
inline uint64_t lastConfigUpdate() const { return _lastConfigUpdate; }
|
||||
inline ZT_VirtualNetworkStatus status() const { Mutex::Lock _l(_lock); return _status(); }
|
||||
inline const NetworkConfig &config() const { return _config; }
|
||||
inline const MAC &mac() const { return _mac; }
|
||||
inline uint64_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
inline Address controller() const
|
||||
{
|
||||
return Address(_id >> 24);
|
||||
}
|
||||
inline bool multicastEnabled() const
|
||||
{
|
||||
return (_config.multicastLimit > 0);
|
||||
}
|
||||
inline bool hasConfig() const
|
||||
{
|
||||
return (_config);
|
||||
}
|
||||
inline uint64_t lastConfigUpdate() const
|
||||
{
|
||||
return _lastConfigUpdate;
|
||||
}
|
||||
inline ZT_VirtualNetworkStatus status() const
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return _status();
|
||||
}
|
||||
inline const NetworkConfig& config() const
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
inline const MAC& mac() const
|
||||
{
|
||||
return _mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filters to an outgoing packet
|
||||
|
@ -304,7 +329,10 @@ public:
|
|||
/**
|
||||
* @return True if QoS is in effect for this network
|
||||
*/
|
||||
inline bool qosEnabled() { return false; }
|
||||
inline bool qosEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a bridge route
|
||||
|
@ -425,7 +453,10 @@ public:
|
|||
/**
|
||||
* @return Externally usable pointer-to-pointer exported via the core API
|
||||
*/
|
||||
inline void **userPtr() { return &_uPtr; }
|
||||
inline void** userPtr()
|
||||
{
|
||||
return &_uPtr;
|
||||
}
|
||||
|
||||
private:
|
||||
ZT_VirtualNetworkStatus _status() const;
|
||||
|
@ -452,9 +483,11 @@ private:
|
|||
NetworkConfig _config;
|
||||
int64_t _lastConfigUpdate;
|
||||
|
||||
struct _IncomingConfigChunk
|
||||
struct _IncomingConfigChunk {
|
||||
_IncomingConfigChunk()
|
||||
{
|
||||
_IncomingConfigChunk() { memset(this,0,sizeof(_IncomingConfigChunk)); }
|
||||
memset(this, 0, sizeof(_IncomingConfigChunk));
|
||||
}
|
||||
uint64_t ts;
|
||||
uint64_t updateId;
|
||||
uint64_t haveChunkIds[ZT_NETWORK_MAX_UPDATE_CHUNKS];
|
||||
|
@ -466,13 +499,7 @@ private:
|
|||
|
||||
bool _destroyed;
|
||||
|
||||
enum {
|
||||
NETCONF_FAILURE_NONE,
|
||||
NETCONF_FAILURE_ACCESS_DENIED,
|
||||
NETCONF_FAILURE_NOT_FOUND,
|
||||
NETCONF_FAILURE_INIT_FAILED,
|
||||
NETCONF_FAILURE_AUTHENTICATION_REQUIRED
|
||||
} _netconfFailure;
|
||||
enum { NETCONF_FAILURE_NONE, NETCONF_FAILURE_ACCESS_DENIED, NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED, NETCONF_FAILURE_AUTHENTICATION_REQUIRED } _netconfFailure;
|
||||
int _portError; // return value from port config callback
|
||||
std::string _authenticationURL;
|
||||
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "NetworkConfig.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "NetworkConfig.hpp"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -129,7 +128,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
|
|||
ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[i].t & 0x7f);
|
||||
if (rt == ZT_NETWORK_RULE_MATCH_ETHERTYPE) {
|
||||
et = rules[i].v.etherType;
|
||||
} else if (rt == ZT_NETWORK_RULE_ACTION_ACCEPT) {
|
||||
}
|
||||
else if (rt == ZT_NETWORK_RULE_ACTION_ACCEPT) {
|
||||
if (((int)lastrt < 32) || (lastrt == ZT_NETWORK_RULE_MATCH_ETHERTYPE)) {
|
||||
if (ets.length() > 0) {
|
||||
ets.push_back(',');
|
||||
|
@ -280,7 +280,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
|
|||
return false;
|
||||
}
|
||||
}
|
||||
} else if(this->ssoVersion == 1) {
|
||||
}
|
||||
else if (this->ssoVersion == 1) {
|
||||
if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION, this->ssoVersion)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -309,7 +310,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
|
|||
}
|
||||
|
||||
delete tmp;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
delete tmp;
|
||||
throw;
|
||||
}
|
||||
|
@ -347,7 +349,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
this->mtu = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MTU, ZT_DEFAULT_MTU);
|
||||
if (this->mtu < 1280) {
|
||||
this->mtu = 1280; // minimum MTU allowed by IPv6 standard and others
|
||||
} else if (this->mtu > ZT_MAX_MTU) {
|
||||
}
|
||||
else if (this->mtu > ZT_MAX_MTU) {
|
||||
this->mtu = ZT_MAX_MTU;
|
||||
}
|
||||
|
||||
|
@ -405,7 +408,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
}
|
||||
this->rules[this->ruleCount++].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT;
|
||||
this->ruleCount = 1;
|
||||
}
|
||||
|
@ -420,7 +424,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
delete tmp;
|
||||
return false;
|
||||
#endif // ZT_SUPPORT_OLD_STYLE_NETCONF
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Otherwise we can use the new fields
|
||||
this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS, 0);
|
||||
this->type = (ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)ZT_NETWORK_TYPE_PRIVATE);
|
||||
|
@ -437,7 +442,9 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
p += cap.deserialize(*tmp, p);
|
||||
this->capabilities[this->capabilityCount++] = cap;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
std::sort(&(this->capabilities[0]), &(this->capabilities[this->capabilityCount]));
|
||||
}
|
||||
|
||||
|
@ -449,7 +456,9 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
p += tag.deserialize(*tmp, p);
|
||||
this->tags[this->tagCount++] = tag;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
std::sort(&(this->tags[0]), &(this->tags[this->tagCount]));
|
||||
}
|
||||
|
||||
|
@ -458,7 +467,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
while (p < tmp->size()) {
|
||||
if (certificateOfOwnershipCount < ZT_MAX_CERTIFICATES_OF_OWNERSHIP) {
|
||||
p += certificatesOfOwnership[certificateOfOwnershipCount++].deserialize(*tmp, p);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
CertificateOfOwnership foo;
|
||||
p += foo.deserialize(*tmp, p);
|
||||
}
|
||||
|
@ -514,15 +524,18 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
if (this->ssoEnabled) {
|
||||
if (d.get(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL, (unsigned int)sizeof(this->authenticationURL)) > 0) {
|
||||
this->authenticationURL[sizeof(this->authenticationURL) - 1] = 0; // ensure null terminated
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->authenticationURL[0] = 0;
|
||||
}
|
||||
this->authenticationExpiryTime = d.getI(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_EXPIRY_TIME, 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->authenticationURL[0] = 0;
|
||||
this->authenticationExpiryTime = 0;
|
||||
}
|
||||
} else if (this->ssoVersion == 1) {
|
||||
}
|
||||
else if (this->ssoVersion == 1) {
|
||||
// full flow
|
||||
if (this->ssoEnabled) {
|
||||
if (d.get(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL, (unsigned int)sizeof(this->authenticationURL)) > 0) {
|
||||
|
@ -545,11 +558,13 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
}
|
||||
if (d.get(ZT_NETWORKCONFIG_DICT_KEY_SSO_PROVIDER, this->ssoProvider, (unsigned int)(sizeof(this->ssoProvider))) > 0) {
|
||||
this->ssoProvider[sizeof(this->ssoProvider) - 1] = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
strncpy(this->ssoProvider, "default", sizeof(this->ssoProvider));
|
||||
this->ssoProvider[sizeof(this->ssoProvider) - 1] = 0;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this->authenticationURL[0] = 0;
|
||||
this->authenticationExpiryTime = 0;
|
||||
this->centralAuthURL[0] = 0;
|
||||
|
@ -568,7 +583,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
|||
|
||||
delete tmp;
|
||||
return true;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
delete tmp;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,31 +14,29 @@
|
|||
#ifndef ZT_NETWORKCONFIG_HPP
|
||||
#define ZT_NETWORKCONFIG_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "DNS.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "CertificateOfOwnership.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "DNS.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Default time delta for COMs, tags, and capabilities
|
||||
|
@ -93,7 +91,9 @@
|
|||
namespace ZeroTier {
|
||||
|
||||
// Dictionary capacity needed for max size network config
|
||||
#define ZT_NETWORKCONFIG_DICT_CAPACITY (4096 + (sizeof(ZT_VirtualNetworkConfig)) + (sizeof(ZT_VirtualNetworkRule) * ZT_MAX_NETWORK_RULES) + (sizeof(Capability) * ZT_MAX_NETWORK_CAPABILITIES) + (sizeof(Tag) * ZT_MAX_NETWORK_TAGS) + (sizeof(CertificateOfOwnership) * ZT_MAX_CERTIFICATES_OF_OWNERSHIP))
|
||||
#define ZT_NETWORKCONFIG_DICT_CAPACITY \
|
||||
(4096 + (sizeof(ZT_VirtualNetworkConfig)) + (sizeof(ZT_VirtualNetworkRule) * ZT_MAX_NETWORK_RULES) + (sizeof(Capability) * ZT_MAX_NETWORK_CAPABILITIES) + (sizeof(Tag) * ZT_MAX_NETWORK_TAGS) \
|
||||
+ (sizeof(CertificateOfOwnership) * ZT_MAX_CERTIFICATES_OF_OWNERSHIP))
|
||||
|
||||
// Dictionary capacity needed for max size network meta-data
|
||||
#define ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY 1024
|
||||
|
@ -248,40 +248,39 @@ namespace ZeroTier {
|
|||
* This is a memcpy()'able structure and is safe (in a crash sense) to modify
|
||||
* without locks.
|
||||
*/
|
||||
class NetworkConfig
|
||||
{
|
||||
class NetworkConfig {
|
||||
public:
|
||||
NetworkConfig() :
|
||||
networkId(0),
|
||||
timestamp(0),
|
||||
credentialTimeMaxDelta(0),
|
||||
revision(0),
|
||||
issuedTo(),
|
||||
remoteTraceTarget(),
|
||||
flags(0),
|
||||
remoteTraceLevel(Trace::LEVEL_NORMAL),
|
||||
mtu(0),
|
||||
multicastLimit(0),
|
||||
specialistCount(0),
|
||||
routeCount(0),
|
||||
staticIpCount(0),
|
||||
ruleCount(0),
|
||||
capabilityCount(0),
|
||||
tagCount(0),
|
||||
certificateOfOwnershipCount(0),
|
||||
capabilities(),
|
||||
tags(),
|
||||
certificatesOfOwnership(),
|
||||
type(ZT_NETWORK_TYPE_PRIVATE),
|
||||
dnsCount(0),
|
||||
ssoEnabled(false),
|
||||
authenticationURL(),
|
||||
authenticationExpiryTime(0),
|
||||
issuerURL(),
|
||||
centralAuthURL(),
|
||||
ssoNonce(),
|
||||
ssoState(),
|
||||
ssoClientID()
|
||||
NetworkConfig()
|
||||
: networkId(0)
|
||||
, timestamp(0)
|
||||
, credentialTimeMaxDelta(0)
|
||||
, revision(0)
|
||||
, issuedTo()
|
||||
, remoteTraceTarget()
|
||||
, flags(0)
|
||||
, remoteTraceLevel(Trace::LEVEL_NORMAL)
|
||||
, mtu(0)
|
||||
, multicastLimit(0)
|
||||
, specialistCount(0)
|
||||
, routeCount(0)
|
||||
, staticIpCount(0)
|
||||
, ruleCount(0)
|
||||
, capabilityCount(0)
|
||||
, tagCount(0)
|
||||
, certificateOfOwnershipCount(0)
|
||||
, capabilities()
|
||||
, tags()
|
||||
, certificatesOfOwnership()
|
||||
, type(ZT_NETWORK_TYPE_PRIVATE)
|
||||
, dnsCount(0)
|
||||
, ssoEnabled(false)
|
||||
, authenticationURL()
|
||||
, authenticationExpiryTime(0)
|
||||
, issuerURL()
|
||||
, centralAuthURL()
|
||||
, ssoNonce()
|
||||
, ssoState()
|
||||
, ssoClientID()
|
||||
{
|
||||
name[0] = 0;
|
||||
memset(specialists, 0, sizeof(uint64_t) * ZT_MAX_NETWORK_SPECIALISTS);
|
||||
|
@ -318,12 +317,18 @@ public:
|
|||
/**
|
||||
* @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network
|
||||
*/
|
||||
inline bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); }
|
||||
inline bool enableBroadcast() const
|
||||
{
|
||||
return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns
|
||||
*/
|
||||
inline bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); }
|
||||
inline bool ndpEmulation() const
|
||||
{
|
||||
return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if frames should not be compressed
|
||||
|
@ -344,12 +349,18 @@ public:
|
|||
/**
|
||||
* @return Network type is public (no access control)
|
||||
*/
|
||||
inline bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); }
|
||||
inline bool isPublic() const
|
||||
{
|
||||
return (this->type == ZT_NETWORK_TYPE_PUBLIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Network type is private (certificate access control)
|
||||
*/
|
||||
inline bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); }
|
||||
inline bool isPrivate() const
|
||||
{
|
||||
return (this->type == ZT_NETWORK_TYPE_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZeroTier addresses of devices on this network designated as active bridges
|
||||
|
@ -474,9 +485,18 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
inline operator bool() const { return (networkId != 0); }
|
||||
inline bool operator==(const NetworkConfig &nc) const { return (memcmp(this,&nc,sizeof(NetworkConfig)) == 0); }
|
||||
inline bool operator!=(const NetworkConfig &nc) const { return (!(*this == nc)); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (networkId != 0);
|
||||
}
|
||||
inline bool operator==(const NetworkConfig& nc) const
|
||||
{
|
||||
return (memcmp(this, &nc, sizeof(NetworkConfig)) == 0);
|
||||
}
|
||||
inline bool operator!=(const NetworkConfig& nc) const
|
||||
{
|
||||
return (! (*this == nc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a specialist or mask flags if already present
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#ifndef ZT_NETWORKCONFIGMASTER_HPP
|
||||
#define ZT_NETWORKCONFIGMASTER_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "Address.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -30,23 +30,14 @@ struct InetAddress;
|
|||
/**
|
||||
* Interface for network controller implementations
|
||||
*/
|
||||
class NetworkController
|
||||
{
|
||||
class NetworkController {
|
||||
public:
|
||||
enum ErrorCode
|
||||
{
|
||||
NC_ERROR_NONE = 0,
|
||||
NC_ERROR_OBJECT_NOT_FOUND = 1,
|
||||
NC_ERROR_ACCESS_DENIED = 2,
|
||||
NC_ERROR_INTERNAL_SERVER_ERROR = 3,
|
||||
NC_ERROR_AUTHENTICATION_REQUIRED = 4
|
||||
};
|
||||
enum ErrorCode { NC_ERROR_NONE = 0, NC_ERROR_OBJECT_NOT_FOUND = 1, NC_ERROR_ACCESS_DENIED = 2, NC_ERROR_INTERNAL_SERVER_ERROR = 3, NC_ERROR_AUTHENTICATION_REQUIRED = 4 };
|
||||
|
||||
/**
|
||||
* Interface for sender used to send pushes and replies
|
||||
*/
|
||||
class Sender
|
||||
{
|
||||
class Sender {
|
||||
public:
|
||||
/**
|
||||
* Send a configuration to a remote peer
|
||||
|
@ -83,8 +74,12 @@ public:
|
|||
virtual void ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode, const void* errorData, unsigned int errorDataSize) = 0;
|
||||
};
|
||||
|
||||
NetworkController() {}
|
||||
virtual ~NetworkController() {}
|
||||
NetworkController()
|
||||
{
|
||||
}
|
||||
virtual ~NetworkController()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this is added to a Node to initialize and supply info
|
||||
|
@ -104,12 +99,7 @@ public:
|
|||
* @param metaData Meta-data bundled with request (if any)
|
||||
* @return Returns NETCONF_QUERY_OK if result 'nc' is valid, or an error code on error
|
||||
*/
|
||||
virtual void request(
|
||||
uint64_t nwid,
|
||||
const InetAddress &fromAddr,
|
||||
uint64_t requestPacketId,
|
||||
const Identity &identity,
|
||||
const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData) = 0;
|
||||
virtual void request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY>& metaData) = 0;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
245
node/Node.cpp
245
node/Node.cpp
|
@ -11,32 +11,32 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "Node.hpp"
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "ECC.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "PacketMultiplexer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Trace.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// FIXME: remove this suppression and actually fix warnings
|
||||
#ifdef __GNUC__
|
||||
|
@ -49,17 +49,17 @@ namespace ZeroTier {
|
|||
/* Public Node interface (C++, exposed via CAPI bindings) */
|
||||
/****************************************************************************/
|
||||
|
||||
Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now) :
|
||||
_RR(this),
|
||||
RR(&_RR),
|
||||
_uPtr(uptr),
|
||||
_networks(8),
|
||||
_now(now),
|
||||
_lastPingCheck(0),
|
||||
_lastGratuitousPingCheck(0),
|
||||
_lastHousekeepingRun(0),
|
||||
_lastMemoizedTraceSettings(0),
|
||||
_lowBandwidthMode(false)
|
||||
Node::Node(void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now)
|
||||
: _RR(this)
|
||||
, RR(&_RR)
|
||||
, _uPtr(uptr)
|
||||
, _networks(8)
|
||||
, _now(now)
|
||||
, _lastPingCheck(0)
|
||||
, _lastGratuitousPingCheck(0)
|
||||
, _lastHousekeepingRun(0)
|
||||
, _lastMemoizedTraceSettings(0)
|
||||
, _lowBandwidthMode(false)
|
||||
{
|
||||
if (callbacks->version != 0) {
|
||||
throw ZT_EXCEPTION_INVALID_ARGUMENT;
|
||||
|
@ -86,7 +86,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
|
|||
if (RR->identity.fromString(tmp)) {
|
||||
RR->identity.toString(false, RR->publicIdentityStr);
|
||||
RR->identity.toString(true, RR->secretIdentityStr);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw ZT_EXCEPTION_INVALID_IDENTITY;
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
|
|||
idtmp[1] = 0;
|
||||
stateObjectPut(tptr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, RR->secretIdentityStr, (unsigned int)strlen(RR->secretIdentityStr));
|
||||
stateObjectPut(tptr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
idtmp[0] = RR->identity.address().toInt();
|
||||
idtmp[1] = 0;
|
||||
n = stateObjectGet(tptr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, tmp, sizeof(tmp) - 1);
|
||||
|
@ -146,7 +148,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
|
|||
RR->bc = new (m) Bond(RR);
|
||||
m += bcs;
|
||||
RR->pm = new (m) PacketMultiplexer(RR);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
if (RR->sa) {
|
||||
RR->sa->~SelfAwareness();
|
||||
}
|
||||
|
@ -205,14 +208,7 @@ Node::~Node()
|
|||
::free(RR->rtmem);
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::processWirePacket(
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
ZT_ResultCode Node::processWirePacket(void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline)
|
||||
{
|
||||
_now = now;
|
||||
RR->sw->onRemotePacket(tptr, localSocket, *(reinterpret_cast<const InetAddress*>(remoteAddress)), packetData, packetLength);
|
||||
|
@ -236,7 +232,8 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
|
|||
if (nw) {
|
||||
RR->sw->onLocalEthernet(tptr, nw, MAC(sourceMac), MAC(destMac), etherType, vlanId, frameData, frameLength);
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
@ -247,15 +244,14 @@ void Node::initMultithreading(unsigned int concurrency, bool cpuPinningEnabled)
|
|||
}
|
||||
|
||||
// Closure used to ping upstream and active/online peers
|
||||
class _PingPeersThatNeedPing
|
||||
{
|
||||
class _PingPeersThatNeedPing {
|
||||
public:
|
||||
_PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &alwaysContact,int64_t now) :
|
||||
RR(renv),
|
||||
_tPtr(tPtr),
|
||||
_alwaysContact(alwaysContact),
|
||||
_now(now),
|
||||
_bestCurrentUpstream(RR->topology->getUpstreamPeer())
|
||||
_PingPeersThatNeedPing(const RuntimeEnvironment* renv, void* tPtr, Hashtable<Address, std::vector<InetAddress> >& alwaysContact, int64_t now)
|
||||
: RR(renv)
|
||||
, _tPtr(tPtr)
|
||||
, _alwaysContact(alwaysContact)
|
||||
, _now(now)
|
||||
, _bestCurrentUpstream(RR->topology->getUpstreamPeer())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -263,7 +259,6 @@ public:
|
|||
{
|
||||
const std::vector<InetAddress>* const alwaysContactEndpoints = _alwaysContact.get(p->address());
|
||||
if (alwaysContactEndpoints) {
|
||||
|
||||
ZT_PeerRole role = RR->topology->role(p->address());
|
||||
|
||||
// Contact upstream peers as infrequently as possible
|
||||
|
@ -310,7 +305,8 @@ public:
|
|||
}
|
||||
|
||||
_alwaysContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain
|
||||
} else if (p->isActive(_now)) {
|
||||
}
|
||||
else if (p->isActive(_now)) {
|
||||
p->doPingAndKeepalive(_tPtr, _now);
|
||||
}
|
||||
}
|
||||
|
@ -430,10 +426,12 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
|
|||
if (oldOnline != _online) {
|
||||
postEvent(tptr, _online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
|
||||
}
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck;
|
||||
}
|
||||
|
||||
|
@ -448,14 +446,16 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
|
|||
RR->topology->doPeriodicTasks(tptr, now);
|
||||
RR->sa->clean(now);
|
||||
RR->mc->clean(now);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
*nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(bondCheckInterval, std::min(timeUntilNextPingCheck, RR->sw->doTimerTasks(tptr, now))), (unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,8 @@ ZT_ResultCode Node::multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multica
|
|||
if (nw) {
|
||||
nw->multicastSubscribe(tptr, MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
@ -525,7 +526,8 @@ ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,u
|
|||
if (nw) {
|
||||
nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
@ -576,7 +578,8 @@ ZT_PeerList *Node::peers() const
|
|||
p->versionMajor = pi->second->remoteVersionMajor();
|
||||
p->versionMinor = pi->second->remoteVersionMinor();
|
||||
p->versionRev = pi->second->remoteVersionRevision();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p->versionMajor = -1;
|
||||
p->versionMinor = -1;
|
||||
p->versionRev = -1;
|
||||
|
@ -699,7 +702,9 @@ int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *d
|
|||
RR->sw->send(tptr, outp, true);
|
||||
return 1;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -784,7 +789,8 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
|
|||
return;
|
||||
}
|
||||
n->setConfiguration((void*)0, nc, true);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>* dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
try {
|
||||
if (nc.toDictionary(*dconf, sendLegacyFormatConfig)) {
|
||||
|
@ -824,7 +830,8 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
|
|||
}
|
||||
}
|
||||
delete dconf;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
delete dconf;
|
||||
throw;
|
||||
}
|
||||
|
@ -839,7 +846,8 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
|
|||
return;
|
||||
}
|
||||
n->addCredential((void*)0, RR->identity.address(), rev);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Packet outp(destination, RR->identity.address(), Packet::VERB_NETWORK_CREDENTIALS);
|
||||
outp.append((uint8_t)0x00);
|
||||
outp.append((uint16_t)0);
|
||||
|
@ -874,7 +882,8 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des
|
|||
default:
|
||||
break;
|
||||
}
|
||||
} else if (requestPacketId) {
|
||||
}
|
||||
else if (requestPacketId) {
|
||||
Packet outp(destination, RR->identity.address(), Packet::VERB_ERROR);
|
||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append(requestPacketId);
|
||||
|
@ -920,11 +929,14 @@ enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct
|
|||
try {
|
||||
*node = reinterpret_cast<ZT_Node*>(new ZeroTier::Node(uptr, tptr, callbacks, now));
|
||||
return ZT_RESULT_OK;
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (std::runtime_error &exc) {
|
||||
}
|
||||
catch (std::runtime_error& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -933,24 +945,21 @@ void ZT_Node_delete(ZT_Node *node)
|
|||
{
|
||||
try {
|
||||
delete (reinterpret_cast<ZeroTier::Node*>(node));
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
enum ZT_ResultCode
|
||||
ZT_Node_processWirePacket(ZT_Node* node, void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->processWirePacket(tptr, now, localSocket, remoteAddress, packetData, packetLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_OK; // "OK" since invalid packets are simply dropped, but the system is still up
|
||||
}
|
||||
}
|
||||
|
@ -970,9 +979,11 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->processVirtualNetworkFrame(tptr, now, nwid, sourceMac, destMac, etherType, vlanId, frameData, frameLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -981,9 +992,11 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,int64
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -992,9 +1005,11 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tpt
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->join(nwid, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1003,9 +1018,11 @@ enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *t
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->leave(nwid, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1014,9 +1031,11 @@ enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1025,9 +1044,11 @@ enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
}
|
||||
catch (std::bad_alloc& exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1036,7 +1057,8 @@ enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,u
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->orbit(tptr, moonWorldId, moonSeed);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1045,7 +1067,8 @@ enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->deorbit(tptr, moonWorldId);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -1059,14 +1082,17 @@ void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status)
|
|||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node*>(node)->status(status);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
ZT_PeerList* ZT_Node_peers(ZT_Node* node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->peers();
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return (ZT_PeerList*)0;
|
||||
}
|
||||
}
|
||||
|
@ -1075,7 +1101,8 @@ ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid)
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->networkConfig(nwid);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return (ZT_VirtualNetworkConfig*)0;
|
||||
}
|
||||
}
|
||||
|
@ -1084,7 +1111,8 @@ ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
|||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->networks();
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return (ZT_VirtualNetworkList*)0;
|
||||
}
|
||||
}
|
||||
|
@ -1093,14 +1121,17 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr)
|
|||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node*>(node)->freeQueryResult(qr);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_addLocalInterfaceAddress(ZT_Node* node, const struct sockaddr_storage* addr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->addLocalInterfaceAddress(addr);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1109,14 +1140,17 @@ void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node)
|
|||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node*>(node)->clearLocalInterfaceAddresses();
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_sendUserMessage(ZT_Node* node, void* tptr, uint64_t dest, uint64_t typeId, const void* data, unsigned int len)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->sendUserMessage(tptr, dest, typeId, data, len);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1125,14 +1159,17 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance)
|
|||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node*>(node)->setNetconfMaster(networkControllerInstance);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node* node, const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node*>(node)->setPhysicalPathConfiguration(pathNetwork, pathConfig);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
|
166
node/Node.hpp
166
node/Node.hpp
|
@ -14,29 +14,26 @@
|
|||
#ifndef ZT_NODE_HPP
|
||||
#define ZT_NODE_HPP
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Bond.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "NetworkController.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Bond.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
|
||||
// Bit mask for "expecting reply" hash
|
||||
#define ZT_EXPECTING_REPLIES_BUCKET_MASK1 255
|
||||
#define ZT_EXPECTING_REPLIES_BUCKET_MASK2 31
|
||||
|
@ -50,28 +47,26 @@ class World;
|
|||
*
|
||||
* The pointer returned by ZT_Node_new() is an instance of this class.
|
||||
*/
|
||||
class Node : public NetworkController::Sender
|
||||
{
|
||||
class Node : public NetworkController::Sender {
|
||||
public:
|
||||
Node(void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now);
|
||||
virtual ~Node();
|
||||
|
||||
// Get rid of alignment warnings on 32-bit Windows and possibly improve performance
|
||||
#ifdef __WINDOWS__
|
||||
void * operator new(size_t i) { return _mm_malloc(i,16); }
|
||||
void operator delete(void* p) { _mm_free(p); }
|
||||
void* operator new(size_t i)
|
||||
{
|
||||
return _mm_malloc(i, 16);
|
||||
}
|
||||
void operator delete(void* p)
|
||||
{
|
||||
_mm_free(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Public API Functions ----------------------------------------------------
|
||||
|
||||
ZT_ResultCode processWirePacket(
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
volatile int64_t *nextBackgroundTaskDeadline);
|
||||
ZT_ResultCode processWirePacket(void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline);
|
||||
ZT_ResultCode processVirtualNetworkFrame(
|
||||
void* tptr,
|
||||
int64_t now,
|
||||
|
@ -103,35 +98,19 @@ public:
|
|||
|
||||
// Internal functions ------------------------------------------------------
|
||||
|
||||
inline int64_t now() const { return _now; }
|
||||
inline int64_t now() const
|
||||
{
|
||||
return _now;
|
||||
}
|
||||
|
||||
inline bool putPacket(void* tPtr, const int64_t localSocket, const InetAddress& addr, const void* data, unsigned int len, unsigned int ttl = 0)
|
||||
{
|
||||
return (_cb.wirePacketSendFunction(
|
||||
reinterpret_cast<ZT_Node *>(this),
|
||||
_uPtr,
|
||||
tPtr,
|
||||
localSocket,
|
||||
reinterpret_cast<const struct sockaddr_storage *>(&addr),
|
||||
data,
|
||||
len,
|
||||
ttl) == 0);
|
||||
return (_cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, localSocket, reinterpret_cast<const struct sockaddr_storage*>(&addr), data, len, ttl) == 0);
|
||||
}
|
||||
|
||||
inline void putFrame(void* tPtr, uint64_t nwid, void** nuptr, const MAC& source, const MAC& dest, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len)
|
||||
{
|
||||
_cb.virtualNetworkFrameFunction(
|
||||
reinterpret_cast<ZT_Node *>(this),
|
||||
_uPtr,
|
||||
tPtr,
|
||||
nwid,
|
||||
nuptr,
|
||||
source.toInt(),
|
||||
dest.toInt(),
|
||||
etherType,
|
||||
vlanId,
|
||||
data,
|
||||
len);
|
||||
_cb.virtualNetworkFrameFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, nwid, nuptr, source.toInt(), dest.toInt(), etherType, vlanId, data, len);
|
||||
}
|
||||
|
||||
inline SharedPtr<Network> network(uint64_t nwid) const
|
||||
|
@ -169,18 +148,39 @@ public:
|
|||
return _directPaths;
|
||||
}
|
||||
|
||||
inline void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ev,md); }
|
||||
inline void postEvent(void* tPtr, ZT_Event ev, const void* md = (const void*)0)
|
||||
{
|
||||
_cb.eventCallback(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, ev, md);
|
||||
}
|
||||
|
||||
inline int configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,nwid,nuptr,op,nc); }
|
||||
inline int configureVirtualNetworkPort(void* tPtr, uint64_t nwid, void** nuptr, ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig* nc)
|
||||
{
|
||||
return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, nwid, nuptr, op, nc);
|
||||
}
|
||||
|
||||
inline bool online() const { return _online; }
|
||||
inline bool online() const
|
||||
{
|
||||
return _online;
|
||||
}
|
||||
|
||||
inline int stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],void *const data,const unsigned int maxlen) { return _cb.stateGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,maxlen); }
|
||||
inline void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,(int)len); }
|
||||
inline void stateObjectDelete(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2]) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,(const void *)0,-1); }
|
||||
inline int stateObjectGet(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2], void* const data, const unsigned int maxlen)
|
||||
{
|
||||
return _cb.stateGetFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, type, id, data, maxlen);
|
||||
}
|
||||
inline void stateObjectPut(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2], const void* const data, const unsigned int len)
|
||||
{
|
||||
_cb.statePutFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, type, id, data, (int)len);
|
||||
}
|
||||
inline void stateObjectDelete(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2])
|
||||
{
|
||||
_cb.statePutFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, type, id, (const void*)0, -1);
|
||||
}
|
||||
|
||||
bool shouldUsePathForZeroTierTraffic(void* tPtr, const Address& ztaddr, const int64_t localSocket, const InetAddress& remoteAddress);
|
||||
inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
|
||||
inline bool externalPathLookup(void* tPtr, const Address& ztaddr, int family, InetAddress& addr)
|
||||
{
|
||||
return ((_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node*>(this), _uPtr, tPtr, ztaddr.toInt(), family, reinterpret_cast<struct sockaddr_storage*>(&addr)) != 0) : false);
|
||||
}
|
||||
|
||||
uint64_t prng();
|
||||
ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig);
|
||||
|
@ -188,11 +188,20 @@ public:
|
|||
World planet() const;
|
||||
std::vector<World> moons() const;
|
||||
|
||||
inline const Identity &identity() const { return _RR.identity; }
|
||||
inline const Identity& identity() const
|
||||
{
|
||||
return _RR.identity;
|
||||
}
|
||||
|
||||
inline const std::vector<InetAddress> SurfaceAddresses() const { return _RR.sa->whoami(); }
|
||||
inline const std::vector<InetAddress> SurfaceAddresses() const
|
||||
{
|
||||
return _RR.sa->whoami();
|
||||
}
|
||||
|
||||
inline Bond *bondController() const { return _RR.bc; }
|
||||
inline Bond* bondController() const
|
||||
{
|
||||
return _RR.bc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that we are expecting a reply to a packet ID
|
||||
|
@ -253,8 +262,14 @@ public:
|
|||
virtual void ncSendRevocation(const Address& destination, const Revocation& rev);
|
||||
virtual void ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode, const void* errorData, unsigned int errorDataSize);
|
||||
|
||||
inline const Address &remoteTraceTarget() const { return _remoteTraceTarget; }
|
||||
inline Trace::Level remoteTraceLevel() const { return _remoteTraceLevel; }
|
||||
inline const Address& remoteTraceTarget() const
|
||||
{
|
||||
return _remoteTraceTarget;
|
||||
}
|
||||
inline Trace::Level remoteTraceLevel() const
|
||||
{
|
||||
return _remoteTraceLevel;
|
||||
}
|
||||
|
||||
inline bool localControllerHasAuthorized(const int64_t now, const uint64_t nwid, const Address& addr) const
|
||||
{
|
||||
|
@ -285,7 +300,6 @@ public:
|
|||
|
||||
void initMultithreading(unsigned int concurrency, bool cpuPinningEnabled);
|
||||
|
||||
|
||||
public:
|
||||
RuntimeEnvironment _RR;
|
||||
RuntimeEnvironment* RR;
|
||||
|
@ -304,13 +318,23 @@ public:
|
|||
|
||||
// Map that remembers if we have recently sent a network config to someone
|
||||
// querying us as a controller.
|
||||
struct _LocalControllerAuth
|
||||
{
|
||||
struct _LocalControllerAuth {
|
||||
uint64_t nwid, address;
|
||||
_LocalControllerAuth(const uint64_t nwid_,const Address &address_) : nwid(nwid_),address(address_.toInt()) {}
|
||||
inline unsigned long hashCode() const { return (unsigned long)(nwid ^ address); }
|
||||
inline bool operator==(const _LocalControllerAuth &a) const { return ((a.nwid == nwid)&&(a.address == address)); }
|
||||
inline bool operator!=(const _LocalControllerAuth &a) const { return ((a.nwid != nwid)||(a.address != address)); }
|
||||
_LocalControllerAuth(const uint64_t nwid_, const Address& address_) : nwid(nwid_), address(address_.toInt())
|
||||
{
|
||||
}
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (unsigned long)(nwid ^ address);
|
||||
}
|
||||
inline bool operator==(const _LocalControllerAuth& a) const
|
||||
{
|
||||
return ((a.nwid == nwid) && (a.address == address));
|
||||
}
|
||||
inline bool operator!=(const _LocalControllerAuth& a) const
|
||||
{
|
||||
return ((a.nwid != nwid) || (a.address != address));
|
||||
}
|
||||
};
|
||||
Hashtable<_LocalControllerAuth, int64_t> _localControllerAuthorizations;
|
||||
Mutex _localControllerAuthorizations_m;
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "OutboundMulticast.hpp"
|
||||
#include "Switch.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -42,7 +43,8 @@ void OutboundMulticast::init(
|
|||
if (src) {
|
||||
_macSrc = src;
|
||||
flags |= 0x04;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_macSrc.fromAddress(RR->identity.address(), nwid);
|
||||
}
|
||||
_macDest = dest.mac();
|
||||
|
|
|
@ -14,17 +14,16 @@
|
|||
#ifndef ZT_OUTBOUNDMULTICAST_HPP
|
||||
#define ZT_OUTBOUNDMULTICAST_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Packet.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class CertificateOfMembership;
|
||||
|
@ -35,15 +34,16 @@ class RuntimeEnvironment;
|
|||
*
|
||||
* This object isn't guarded by a mutex; caller must synchronize access.
|
||||
*/
|
||||
class OutboundMulticast
|
||||
{
|
||||
class OutboundMulticast {
|
||||
public:
|
||||
/**
|
||||
* Create an uninitialized outbound multicast
|
||||
*
|
||||
* It must be initialized with init().
|
||||
*/
|
||||
OutboundMulticast() {}
|
||||
OutboundMulticast()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize outbound multicast
|
||||
|
@ -77,18 +77,27 @@ public:
|
|||
/**
|
||||
* @return Multicast creation time
|
||||
*/
|
||||
inline uint64_t timestamp() const { return _timestamp; }
|
||||
inline uint64_t timestamp() const
|
||||
{
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param now Current time
|
||||
* @return True if this multicast is expired (has exceeded transmit timeout)
|
||||
*/
|
||||
inline bool expired(int64_t now) const { return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); }
|
||||
inline bool expired(int64_t now) const
|
||||
{
|
||||
return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this outbound multicast has been sent to enough peers
|
||||
*/
|
||||
inline bool atLimit() const { return (_alreadySentTo.size() >= _limit); }
|
||||
inline bool atLimit() const
|
||||
{
|
||||
return (_alreadySentTo.size() >= _limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just send without checking log
|
||||
|
@ -135,7 +144,8 @@ public:
|
|||
if (std::find(_alreadySentTo.begin(), _alreadySentTo.end(), toAddr) == _alreadySentTo.end()) {
|
||||
sendAndLog(RR, tPtr, toAddr);
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
230
node/Packet.cpp
230
node/Packet.cpp
|
@ -11,15 +11,16 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Packet.hpp"
|
||||
|
||||
#include "ECC.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(ZT_USE_X64_ASM_SALSA2012) && defined(ZT_ARCH_X64)
|
||||
#include "../ext/x64-salsa2012-asm/salsa2012.h"
|
||||
#endif
|
||||
|
@ -50,10 +51,11 @@ namespace ZeroTier {
|
|||
|
||||
// ARM (32-bit) NEON crypto (must be detected)
|
||||
#ifdef ZT_USE_ARM32_NEON_ASM_SALSA2012
|
||||
class _FastCryptoChecker
|
||||
{
|
||||
class _FastCryptoChecker {
|
||||
public:
|
||||
_FastCryptoChecker() : canHas(zt_arm_has_neon()) {}
|
||||
_FastCryptoChecker() : canHas(zt_arm_has_neon())
|
||||
{
|
||||
}
|
||||
bool canHas;
|
||||
};
|
||||
static const _FastCryptoChecker _ZT_FAST_CRYPTO_CHECK;
|
||||
|
@ -64,7 +66,9 @@ static const _FastCryptoChecker _ZT_FAST_CRYPTO_CHECK;
|
|||
// No fast crypto available
|
||||
#ifndef ZT_HAS_FAST_CRYPTO
|
||||
#define ZT_HAS_FAST_CRYPTO() (false)
|
||||
#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) {}
|
||||
#define ZT_FAST_SINGLE_PASS_SALSA2012(b, l, n, k) \
|
||||
{ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************** */
|
||||
|
@ -225,35 +229,78 @@ typedef uintptr_t reg_t;
|
|||
|
||||
static inline unsigned LZ4_isLittleEndian(void)
|
||||
{
|
||||
const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
|
||||
const union {
|
||||
U32 u;
|
||||
BYTE c[4];
|
||||
} one = { 1 }; /* don't use static : performance detrimental */
|
||||
return one.c[0];
|
||||
}
|
||||
|
||||
#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 2)
|
||||
static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; }
|
||||
static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; }
|
||||
static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; }
|
||||
static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
|
||||
static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
|
||||
static U16 LZ4_read16(const void* memPtr)
|
||||
{
|
||||
return *(const U16*)memPtr;
|
||||
}
|
||||
static U32 LZ4_read32(const void* memPtr)
|
||||
{
|
||||
return *(const U32*)memPtr;
|
||||
}
|
||||
static reg_t LZ4_read_ARCH(const void* memPtr)
|
||||
{
|
||||
return *(const reg_t*)memPtr;
|
||||
}
|
||||
static void LZ4_write16(void* memPtr, U16 value)
|
||||
{
|
||||
*(U16*)memPtr = value;
|
||||
}
|
||||
static void LZ4_write32(void* memPtr, U32 value)
|
||||
{
|
||||
*(U32*)memPtr = value;
|
||||
}
|
||||
#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 1)
|
||||
typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign;
|
||||
static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
|
||||
static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
|
||||
static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; }
|
||||
static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
|
||||
static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
|
||||
typedef union {
|
||||
U16 u16;
|
||||
U32 u32;
|
||||
reg_t uArch;
|
||||
} __attribute__((packed)) unalign;
|
||||
static U16 LZ4_read16(const void* ptr)
|
||||
{
|
||||
return ((const unalign*)ptr)->u16;
|
||||
}
|
||||
static U32 LZ4_read32(const void* ptr)
|
||||
{
|
||||
return ((const unalign*)ptr)->u32;
|
||||
}
|
||||
static reg_t LZ4_read_ARCH(const void* ptr)
|
||||
{
|
||||
return ((const unalign*)ptr)->uArch;
|
||||
}
|
||||
static void LZ4_write16(void* memPtr, U16 value)
|
||||
{
|
||||
((unalign*)memPtr)->u16 = value;
|
||||
}
|
||||
static void LZ4_write32(void* memPtr, U32 value)
|
||||
{
|
||||
((unalign*)memPtr)->u32 = value;
|
||||
}
|
||||
#else /* safe and portable access through memcpy() */
|
||||
static inline U16 LZ4_read16(const void* memPtr)
|
||||
{
|
||||
U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||
U16 val;
|
||||
memcpy(&val, memPtr, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
static inline U32 LZ4_read32(const void* memPtr)
|
||||
{
|
||||
U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||
U32 val;
|
||||
memcpy(&val, memPtr, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
static inline reg_t LZ4_read_ARCH(const void* memPtr)
|
||||
{
|
||||
reg_t val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||
reg_t val;
|
||||
memcpy(&val, memPtr, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
static inline void LZ4_write16(void* memPtr, U16 value)
|
||||
{
|
||||
|
@ -269,7 +316,8 @@ static inline U16 LZ4_readLE16(const void* memPtr)
|
|||
{
|
||||
if (LZ4_isLittleEndian()) {
|
||||
return LZ4_read16(memPtr);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const BYTE* p = (const BYTE*)memPtr;
|
||||
return (U16)((U16)p[0] + (p[1] << 8));
|
||||
}
|
||||
|
@ -279,7 +327,8 @@ static inline void LZ4_writeLE16(void* memPtr, U16 value)
|
|||
{
|
||||
if (LZ4_isLittleEndian()) {
|
||||
LZ4_write16(memPtr, value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BYTE* p = (BYTE*)memPtr;
|
||||
p[0] = (BYTE)value;
|
||||
p[1] = (BYTE)(value >> 8);
|
||||
|
@ -322,7 +371,10 @@ static const int LZ4_minLength = (MFLIMIT+1);
|
|||
#define RUN_BITS (8 - ML_BITS)
|
||||
#define RUN_MASK ((1U << RUN_BITS) - 1)
|
||||
|
||||
#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||
#define LZ4_STATIC_ASSERT(c) \
|
||||
{ \
|
||||
enum { LZ4_static_assert = 1 / (int)(! ! (c)) }; \
|
||||
} /* use only *after* variable declarations */
|
||||
|
||||
static inline unsigned LZ4_NbCommonBytes(reg_t val)
|
||||
{
|
||||
|
@ -335,10 +387,12 @@ static inline unsigned LZ4_NbCommonBytes (reg_t val)
|
|||
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT)
|
||||
return (__builtin_ctzll((U64)val) >> 3);
|
||||
#else
|
||||
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
|
||||
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7,
|
||||
7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
|
||||
return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
|
||||
#endif
|
||||
} else /* 32 bits */ {
|
||||
}
|
||||
else /* 32 bits */ {
|
||||
#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT)
|
||||
unsigned long r;
|
||||
_BitScanForward(&r, (U32)val);
|
||||
|
@ -350,7 +404,8 @@ static inline unsigned LZ4_NbCommonBytes (reg_t val)
|
|||
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
|
||||
#endif
|
||||
}
|
||||
} else /* Big Endian CPU */ {
|
||||
}
|
||||
else /* Big Endian CPU */ {
|
||||
if (sizeof(val) == 8) {
|
||||
#if defined(_MSC_VER) && defined(_WIN64) && ! defined(LZ4_FORCE_SW_BITCOUNT)
|
||||
unsigned long r = 0;
|
||||
|
@ -362,20 +417,23 @@ static inline unsigned LZ4_NbCommonBytes (reg_t val)
|
|||
unsigned r;
|
||||
if (! (val >> 32)) {
|
||||
r = 4;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
r = 0;
|
||||
val >>= 32;
|
||||
}
|
||||
if (! (val >> 16)) {
|
||||
r += 2;
|
||||
val >>= 8;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
val >>= 24;
|
||||
}
|
||||
r += (! val);
|
||||
return r;
|
||||
#endif
|
||||
} else /* 32 bits */ {
|
||||
}
|
||||
else /* 32 bits */ {
|
||||
#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT)
|
||||
unsigned long r = 0;
|
||||
_BitScanReverse(&r, (unsigned long)val);
|
||||
|
@ -387,7 +445,8 @@ static inline unsigned LZ4_NbCommonBytes (reg_t val)
|
|||
if (! (val >> 16)) {
|
||||
r = 2;
|
||||
val >>= 8;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
r = 0;
|
||||
val >>= 24;
|
||||
}
|
||||
|
@ -407,17 +466,20 @@ static inline unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE
|
|||
reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
|
||||
if (! diff) {
|
||||
pIn += STEPSIZE;
|
||||
pMatch+=STEPSIZE; continue;
|
||||
pMatch += STEPSIZE;
|
||||
continue;
|
||||
}
|
||||
pIn += LZ4_NbCommonBytes(diff);
|
||||
return (unsigned)(pIn - pStart);
|
||||
}
|
||||
|
||||
if ((STEPSIZE == 8) && (pIn < (pInLimit - 3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) {
|
||||
pIn+=4; pMatch+=4;
|
||||
pIn += 4;
|
||||
pMatch += 4;
|
||||
}
|
||||
if ((pIn < (pInLimit - 1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) {
|
||||
pIn+=2; pMatch+=2;
|
||||
pIn += 2;
|
||||
pMatch += 2;
|
||||
}
|
||||
if ((pIn < pInLimit) && (*pMatch == *pIn)) {
|
||||
pIn++;
|
||||
|
@ -437,13 +499,17 @@ typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
|
|||
typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
|
||||
typedef enum { full = 0, partial = 1 } earlyEnd_directive;
|
||||
|
||||
static inline int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
|
||||
static inline int LZ4_compressBound(int isize)
|
||||
{
|
||||
return LZ4_COMPRESSBOUND(isize);
|
||||
}
|
||||
|
||||
static inline U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
|
||||
{
|
||||
if (tableType == byU16) {
|
||||
return ((sequence * 2654435761U) >> ((MINMATCH * 8) - (LZ4_HASHLOG + 1)));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ((sequence * 2654435761U) >> ((MINMATCH * 8) - LZ4_HASHLOG));
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +521,8 @@ static inline U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
|
|||
const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG + 1 : LZ4_HASHLOG;
|
||||
if (LZ4_isLittleEndian()) {
|
||||
return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
|
||||
}
|
||||
}
|
||||
|
@ -472,15 +539,18 @@ static inline void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase,
|
|||
{
|
||||
switch (tableType) {
|
||||
case byPtr: {
|
||||
const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p;
|
||||
const BYTE** hashTable = (const BYTE**)tableBase;
|
||||
hashTable[h] = p;
|
||||
return;
|
||||
}
|
||||
case byU32: {
|
||||
U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase);
|
||||
U32* hashTable = (U32*)tableBase;
|
||||
hashTable[h] = (U32)(p - srcBase);
|
||||
return;
|
||||
}
|
||||
case byU16: {
|
||||
U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase);
|
||||
U16* hashTable = (U16*)tableBase;
|
||||
hashTable[h] = (U16)(p - srcBase);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -600,7 +670,8 @@ FORCE_INLINE int LZ4_compress_generic(
|
|||
if (match < (const BYTE*)source) {
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictionary;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
}
|
||||
|
@ -608,9 +679,7 @@ FORCE_INLINE int LZ4_compress_generic(
|
|||
forwardH = LZ4_hashPosition(forwardIp, tableType);
|
||||
LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
|
||||
|
||||
} while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
|
||||
|| ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
|
||||
|| (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
|
||||
} while (((dictIssue == dictSmall) ? (match < lowRefLimit) : 0) || ((tableType == byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match + refDelta) != LZ4_read32(ip)));
|
||||
}
|
||||
|
||||
/* Catch up */
|
||||
|
@ -634,7 +703,8 @@ FORCE_INLINE int LZ4_compress_generic(
|
|||
*op++ = 255;
|
||||
}
|
||||
*op++ = (BYTE)len;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*token = (BYTE)(litLength << ML_BITS);
|
||||
}
|
||||
|
||||
|
@ -666,7 +736,8 @@ _next_match:
|
|||
matchCode += more;
|
||||
ip += more;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit);
|
||||
ip += MINMATCH + matchCode;
|
||||
}
|
||||
|
@ -686,7 +757,8 @@ _next_match:
|
|||
}
|
||||
op += matchCode / 255;
|
||||
*op++ = (BYTE)(matchCode % 255);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*token += (BYTE)(matchCode);
|
||||
}
|
||||
}
|
||||
|
@ -707,15 +779,14 @@ _next_match:
|
|||
if (match < (const BYTE*)source) {
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictionary;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
}
|
||||
}
|
||||
LZ4_putPosition(ip, cctx->hashTable, tableType, base);
|
||||
if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
|
||||
&& (match+MAX_DISTANCE>=ip)
|
||||
&& (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) {
|
||||
if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1) && (match + MAX_DISTANCE >= ip) && (LZ4_read32(match + refDelta) == LZ4_read32(ip))) {
|
||||
token = op++;
|
||||
*token = 0;
|
||||
goto _next_match;
|
||||
|
@ -740,7 +811,8 @@ _last_literals:
|
|||
*op++ = 255;
|
||||
}
|
||||
*op++ = (BYTE)accumulator;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*op++ = (BYTE)(lastRun << ML_BITS);
|
||||
}
|
||||
memcpy(op, anchor, lastRun);
|
||||
|
@ -760,13 +832,16 @@ static inline int LZ4_compress_fast_extState(void* state, const char* source, ch
|
|||
if (maxOutputSize >= LZ4_compressBound(inputSize)) {
|
||||
if (inputSize < LZ4_64Klimit) {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (inputSize < LZ4_64Klimit) {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
}
|
||||
|
@ -826,7 +901,6 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
const int safeDecode = (endOnInput == endOnInputSize);
|
||||
const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
|
||||
|
||||
|
||||
/* Special cases */
|
||||
if ((partialDecoding) && (oexit > oend - MFLIMIT)) {
|
||||
oexit = oend - MFLIMIT; /* targetOutputSize too high => decode everything */
|
||||
|
@ -862,8 +936,7 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
|
||||
/* copy literals */
|
||||
cpy = op + length;
|
||||
if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
|
||||
|| ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) ) {
|
||||
if (((endOnInput) && ((cpy > (partialDecoding ? oexit : oend - MFLIMIT)) || (ip + length > iend - (2 + 1 + LASTLITERALS)))) || ((! endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
|
||||
if (partialDecoding) {
|
||||
if (cpy > oend) {
|
||||
goto _output_error; /* Error : write attempt beyond end of output buffer */
|
||||
|
@ -871,7 +944,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
if ((endOnInput) && (ip + length > iend)) {
|
||||
goto _output_error; /* Error : read attempt beyond end of input buffer */
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((! endOnInput) && (cpy != oend)) {
|
||||
goto _output_error; /* Error : block decoding must stop exactly there */
|
||||
}
|
||||
|
@ -924,7 +998,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
/* match can be copied as a single segment from external dictionary */
|
||||
memmove(op, dictEnd - (lowPrefix - match), length);
|
||||
op += length;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* match encompass external dictionary and current block */
|
||||
size_t const copySize = (size_t)(lowPrefix - match);
|
||||
size_t const restSize = length - copySize;
|
||||
|
@ -936,7 +1011,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
while (op < endOfMatch) {
|
||||
*op++ = *copyFrom++;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(op, lowPrefix, restSize);
|
||||
op += restSize;
|
||||
}
|
||||
|
@ -955,7 +1031,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
match += dec32table[offset];
|
||||
memcpy(op + 4, match, 4);
|
||||
match -= dec64;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
LZ4_copy8(op, match);
|
||||
match += 8;
|
||||
}
|
||||
|
@ -974,7 +1051,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
while (op < cpy) {
|
||||
*op++ = *match++;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
LZ4_copy8(op, match);
|
||||
if (length > 16) {
|
||||
LZ4_wildCopy(op + 8, match + 8, cpy);
|
||||
|
@ -986,7 +1064,8 @@ FORCE_INLINE int LZ4_decompress_generic(
|
|||
/* end of decoding */
|
||||
if (endOnInput) {
|
||||
return (int)(((char*)op) - dest); /* Nb of output bytes decoded */
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (int)(((const char*)ip) - source); /* Nb of input bytes read */
|
||||
}
|
||||
/* Overflow error detected */
|
||||
|
@ -1033,7 +1112,8 @@ void Packet::armor(const void *key,bool encryptPayload,bool extendedArmor,const
|
|||
*reinterpret_cast<uint64_t*>(data + ZT_PACKET_IDX_IV) = tag[0];
|
||||
*reinterpret_cast<uint64_t*>(data + ZT_PACKET_IDX_MAC) = tag[1];
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE);
|
||||
|
||||
uint8_t mangledKey[32];
|
||||
|
@ -1053,7 +1133,8 @@ void Packet::armor(const void *key,bool encryptPayload,bool extendedArmor,const
|
|||
#else
|
||||
(*reinterpret_cast<uint64_t*>(data + ZT_PACKET_IDX_MAC)) = mac[0];
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
uint64_t macKey[4];
|
||||
uint64_t mac[2];
|
||||
|
||||
|
@ -1136,7 +1217,8 @@ bool Packet::dearmor(const void *key,const AES aesKeys[2],const Identity &identi
|
|||
dec.update(payload, payloadLen);
|
||||
return dec.finish();
|
||||
}
|
||||
} else if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) {
|
||||
}
|
||||
else if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE) || (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) {
|
||||
uint8_t mangledKey[32];
|
||||
_salsa20MangleKey((const unsigned char*)key, mangledKey);
|
||||
if (ZT_HAS_FAST_CRYPTO()) {
|
||||
|
@ -1156,7 +1238,8 @@ bool Packet::dearmor(const void *key,const AES aesKeys[2],const Identity &identi
|
|||
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) {
|
||||
Salsa20::memxor(data + ZT_PACKET_IDX_VERB, reinterpret_cast<const uint8_t*>(keyStream + 8), payloadLen);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Salsa20 s20(mangledKey, data + ZT_PACKET_IDX_IV);
|
||||
uint64_t macKey[4];
|
||||
s20.crypt12(ZERO_KEY, macKey, sizeof(macKey));
|
||||
|
@ -1225,7 +1308,8 @@ bool Packet::uncompress()
|
|||
if ((ucl > 0) && (ucl <= (int)(capacity() - ZT_PACKET_IDX_PAYLOAD))) {
|
||||
setSize((unsigned int)ucl + ZT_PACKET_IDX_PAYLOAD);
|
||||
memcpy(data + ZT_PACKET_IDX_PAYLOAD, buf, ucl);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
178
node/Packet.hpp
178
node/Packet.hpp
|
@ -14,22 +14,20 @@
|
|||
#ifndef ZT_N_PACKET_HPP
|
||||
#define ZT_N_PACKET_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include "AES.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Poly1305.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "AES.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Identity.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Protocol version -- incremented only for major changes
|
||||
|
@ -345,8 +343,7 @@ namespace ZeroTier {
|
|||
* For unencrypted packets, MAC is computed on plaintext. Only HELLO is ever
|
||||
* sent in the clear, as it's the "here is my public key" message.
|
||||
*/
|
||||
class Packet : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
|
||||
{
|
||||
class Packet : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH> {
|
||||
public:
|
||||
/**
|
||||
* A packet fragment
|
||||
|
@ -374,22 +371,17 @@ public:
|
|||
* receipt to authenticate and decrypt; there is no per-fragment MAC. (But if
|
||||
* fragments are corrupt, the MAC will fail for the whole assembled packet.)
|
||||
*/
|
||||
class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
|
||||
{
|
||||
class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH> {
|
||||
public:
|
||||
Fragment() :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>()
|
||||
Fragment() : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>()
|
||||
{
|
||||
}
|
||||
|
||||
template<unsigned int C2>
|
||||
Fragment(const Buffer<C2> &b) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
|
||||
template <unsigned int C2> Fragment(const Buffer<C2>& b) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
|
||||
{
|
||||
}
|
||||
|
||||
Fragment(const void *data,unsigned int len) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len)
|
||||
Fragment(const void* data, unsigned int len) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data, len)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -438,32 +430,50 @@ public:
|
|||
*
|
||||
* @return Destination ZT address
|
||||
*/
|
||||
inline Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
|
||||
inline Address destination() const
|
||||
{
|
||||
return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if fragment is of a valid length
|
||||
*/
|
||||
inline bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); }
|
||||
inline bool lengthValid() const
|
||||
{
|
||||
return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID of packet this is a fragment of
|
||||
*/
|
||||
inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); }
|
||||
inline uint64_t packetId() const
|
||||
{
|
||||
return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Total number of fragments in packet
|
||||
*/
|
||||
inline unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); }
|
||||
inline unsigned int totalFragments() const
|
||||
{
|
||||
return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Fragment number of this fragment
|
||||
*/
|
||||
inline unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); }
|
||||
inline unsigned int fragmentNumber() const
|
||||
{
|
||||
return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Fragment ZT hop count
|
||||
*/
|
||||
inline unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); }
|
||||
inline unsigned int hops() const
|
||||
{
|
||||
return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment this packet's hop count
|
||||
|
@ -476,7 +486,10 @@ public:
|
|||
/**
|
||||
* @return Length of payload in bytes
|
||||
*/
|
||||
inline unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); }
|
||||
inline unsigned int payloadLength() const
|
||||
{
|
||||
return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Raw packet payload
|
||||
|
@ -1013,8 +1026,7 @@ public:
|
|||
/**
|
||||
* Error codes for VERB_ERROR
|
||||
*/
|
||||
enum ErrorCode
|
||||
{
|
||||
enum ErrorCode {
|
||||
/* No error, not actually used in transit */
|
||||
ERROR_NONE = 0x00,
|
||||
|
||||
|
@ -1046,14 +1058,11 @@ public:
|
|||
ERROR_NETWORK_AUTHENTICATION_REQUIRED = 0x09
|
||||
};
|
||||
|
||||
template<unsigned int C2>
|
||||
Packet(const Buffer<C2> &b) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
|
||||
template <unsigned int C2> Packet(const Buffer<C2>& b) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
|
||||
{
|
||||
}
|
||||
|
||||
Packet(const void *data,unsigned int len) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len)
|
||||
Packet(const void* data, unsigned int len) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data, len)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1064,8 +1073,7 @@ public:
|
|||
* Use the header access methods (setDestination() and friends) to fill out
|
||||
* the header. Payload should be appended; initial size is header size.
|
||||
*/
|
||||
Packet() :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
|
||||
Packet() : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
|
||||
{
|
||||
Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8);
|
||||
(*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags, cipher ID, and hops
|
||||
|
@ -1080,8 +1088,7 @@ public:
|
|||
* @param prototype Prototype packet
|
||||
* @param dest Destination ZeroTier address for new packet
|
||||
*/
|
||||
Packet(const Packet &prototype,const Address &dest) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(prototype)
|
||||
Packet(const Packet& prototype, const Address& dest) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(prototype)
|
||||
{
|
||||
Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8);
|
||||
setDestination(dest);
|
||||
|
@ -1094,8 +1101,7 @@ public:
|
|||
* @param source Source ZT address
|
||||
* @param v Verb
|
||||
*/
|
||||
Packet(const Address &dest,const Address &source,const Verb v) :
|
||||
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
|
||||
Packet(const Address& dest, const Address& source, const Verb v) : Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
|
||||
{
|
||||
Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8);
|
||||
setDestination(dest);
|
||||
|
@ -1128,45 +1134,66 @@ public:
|
|||
* technically different but otherwise identical copies of the same
|
||||
* packet.
|
||||
*/
|
||||
inline void newInitializationVector() { Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); }
|
||||
inline void newInitializationVector()
|
||||
{
|
||||
Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's destination
|
||||
*
|
||||
* @param dest ZeroTier address of destination
|
||||
*/
|
||||
inline void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
|
||||
inline void setDestination(const Address& dest)
|
||||
{
|
||||
dest.copyTo(field(ZT_PACKET_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's source
|
||||
*
|
||||
* @param source ZeroTier address of source
|
||||
*/
|
||||
inline void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
|
||||
inline void setSource(const Address& source)
|
||||
{
|
||||
source.copyTo(field(ZT_PACKET_IDX_SOURCE, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this packet's destination
|
||||
*
|
||||
* @return Destination ZT address
|
||||
*/
|
||||
inline Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
|
||||
inline Address destination() const
|
||||
{
|
||||
return Address(field(ZT_PACKET_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this packet's source
|
||||
*
|
||||
* @return Source ZT address
|
||||
*/
|
||||
inline Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
|
||||
inline Address source() const
|
||||
{
|
||||
return Address(field(ZT_PACKET_IDX_SOURCE, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if packet is of valid length
|
||||
*/
|
||||
inline bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); }
|
||||
inline bool lengthValid() const
|
||||
{
|
||||
return (size() >= ZT_PROTO_MIN_PACKET_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if packet is fragmented (expect fragments)
|
||||
*/
|
||||
inline bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); }
|
||||
inline bool fragmented() const
|
||||
{
|
||||
return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's fragmented flag
|
||||
|
@ -1177,7 +1204,8 @@ public:
|
|||
{
|
||||
if (f) {
|
||||
(*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_FRAGMENTED;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
(*this)[ZT_PACKET_IDX_FLAGS] &= (char)(~ZT_PROTO_FLAG_FRAGMENTED);
|
||||
}
|
||||
}
|
||||
|
@ -1185,7 +1213,10 @@ public:
|
|||
/**
|
||||
* @return True if packet is encrypted with an extra ephemeral key
|
||||
*/
|
||||
inline bool extendedArmor() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_EXTENDED_ARMOR) != 0); }
|
||||
inline bool extendedArmor() const
|
||||
{
|
||||
return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_EXTENDED_ARMOR) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's extended armor flag
|
||||
|
@ -1196,7 +1227,8 @@ public:
|
|||
{
|
||||
if (f) {
|
||||
(*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_EXTENDED_ARMOR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
(*this)[ZT_PACKET_IDX_FLAGS] &= (char)(~ZT_PROTO_FLAG_EXTENDED_ARMOR);
|
||||
}
|
||||
}
|
||||
|
@ -1204,12 +1236,18 @@ public:
|
|||
/**
|
||||
* @return True if compressed (result only valid if unencrypted)
|
||||
*/
|
||||
inline bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); }
|
||||
inline bool compressed() const
|
||||
{
|
||||
return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZeroTier forwarding hops (0 to 7)
|
||||
*/
|
||||
inline unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); }
|
||||
inline unsigned int hops() const
|
||||
{
|
||||
return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment this packet's hop count
|
||||
|
@ -1250,7 +1288,10 @@ public:
|
|||
*
|
||||
* @return Trusted path ID (from MAC field)
|
||||
*/
|
||||
inline uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); }
|
||||
inline uint64_t trustedPathId() const
|
||||
{
|
||||
return at<uint64_t>(ZT_PACKET_IDX_MAC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's trusted path ID and set the cipher spec to trusted path
|
||||
|
@ -1274,7 +1315,10 @@ public:
|
|||
*
|
||||
* @return Packet ID
|
||||
*/
|
||||
inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
|
||||
inline uint64_t packetId() const
|
||||
{
|
||||
return at<uint64_t>(ZT_PACKET_IDX_IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set packet verb
|
||||
|
@ -1284,22 +1328,34 @@ public:
|
|||
*
|
||||
* @param v New packet verb
|
||||
*/
|
||||
inline void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; }
|
||||
inline void setVerb(Verb v)
|
||||
{
|
||||
(*this)[ZT_PACKET_IDX_VERB] = (char)v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Packet verb (not including flag bits)
|
||||
*/
|
||||
inline Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); }
|
||||
inline Verb verb() const
|
||||
{
|
||||
return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Length of packet payload
|
||||
*/
|
||||
inline unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); }
|
||||
inline unsigned int payloadLength() const
|
||||
{
|
||||
return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Raw packet payload
|
||||
*/
|
||||
inline const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); }
|
||||
inline const unsigned char* payload() const
|
||||
{
|
||||
return field(ZT_PACKET_IDX_PAYLOAD, size() - ZT_PACKET_IDX_PAYLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Armor packet for transport
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
#include "PacketMultiplexer.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
/****/
|
||||
|
||||
#include "Path.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
|
270
node/Path.hpp
270
node/Path.hpp
|
@ -14,20 +14,19 @@
|
|||
#ifndef ZT_PATH_HPP
|
||||
#define ZT_PATH_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "RingBuffer.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Maximum return value of preferenceRank()
|
||||
|
@ -41,8 +40,7 @@ class RuntimeEnvironment;
|
|||
/**
|
||||
* A path across the physical network
|
||||
*/
|
||||
class Path
|
||||
{
|
||||
class Path {
|
||||
friend class SharedPtr<Path>;
|
||||
friend class Bond;
|
||||
|
||||
|
@ -50,10 +48,11 @@ public:
|
|||
/**
|
||||
* Efficient unique key for paths in a Hashtable
|
||||
*/
|
||||
class HashKey
|
||||
{
|
||||
class HashKey {
|
||||
public:
|
||||
HashKey() {}
|
||||
HashKey()
|
||||
{
|
||||
}
|
||||
|
||||
HashKey(const int64_t l, const InetAddress& r)
|
||||
{
|
||||
|
@ -61,69 +60,82 @@ public:
|
|||
_k[0] = (uint64_t)reinterpret_cast<const struct sockaddr_in*>(&r)->sin_addr.s_addr;
|
||||
_k[1] = (uint64_t)reinterpret_cast<const struct sockaddr_in*>(&r)->sin_port;
|
||||
_k[2] = (uint64_t)l;
|
||||
} else if (r.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (r.ss_family == AF_INET6) {
|
||||
memcpy(_k, reinterpret_cast<const struct sockaddr_in6*>(&r)->sin6_addr.s6_addr, 16);
|
||||
_k[2] = ((uint64_t)reinterpret_cast<const struct sockaddr_in6*>(&r)->sin6_port << 32) ^ (uint64_t)l;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(_k, &r, std::min(sizeof(_k), sizeof(InetAddress)));
|
||||
_k[2] += (uint64_t)l;
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); }
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return (unsigned long)(_k[0] + _k[1] + _k[2]);
|
||||
}
|
||||
|
||||
inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); }
|
||||
inline bool operator!=(const HashKey &k) const { return (!(*this == k)); }
|
||||
inline bool operator==(const HashKey& k) const
|
||||
{
|
||||
return ((_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]));
|
||||
}
|
||||
inline bool operator!=(const HashKey& k) const
|
||||
{
|
||||
return (! (*this == k));
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _k[3];
|
||||
};
|
||||
|
||||
Path() :
|
||||
_lastOut(0),
|
||||
_lastIn(0),
|
||||
_lastTrustEstablishedPacketReceived(0),
|
||||
_lastEchoRequestReceived(0),
|
||||
_localPort(0),
|
||||
_localSocket(-1),
|
||||
_latencyMean(0.0),
|
||||
_latencyVariance(0.0),
|
||||
_packetLossRatio(0.0),
|
||||
_packetErrorRatio(0.0),
|
||||
_assignedFlowCount(0),
|
||||
_valid(true),
|
||||
_eligible(false),
|
||||
_bonded(false),
|
||||
_mtu(0),
|
||||
_givenLinkSpeed(0),
|
||||
_relativeQuality(0),
|
||||
_latency(0xffff),
|
||||
_addr(),
|
||||
_ipScope(InetAddress::IP_SCOPE_NONE)
|
||||
{}
|
||||
Path()
|
||||
: _lastOut(0)
|
||||
, _lastIn(0)
|
||||
, _lastTrustEstablishedPacketReceived(0)
|
||||
, _lastEchoRequestReceived(0)
|
||||
, _localPort(0)
|
||||
, _localSocket(-1)
|
||||
, _latencyMean(0.0)
|
||||
, _latencyVariance(0.0)
|
||||
, _packetLossRatio(0.0)
|
||||
, _packetErrorRatio(0.0)
|
||||
, _assignedFlowCount(0)
|
||||
, _valid(true)
|
||||
, _eligible(false)
|
||||
, _bonded(false)
|
||||
, _mtu(0)
|
||||
, _givenLinkSpeed(0)
|
||||
, _relativeQuality(0)
|
||||
, _latency(0xffff)
|
||||
, _addr()
|
||||
, _ipScope(InetAddress::IP_SCOPE_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
Path(const int64_t localSocket,const InetAddress &addr) :
|
||||
_lastOut(0),
|
||||
_lastIn(0),
|
||||
_lastTrustEstablishedPacketReceived(0),
|
||||
_lastEchoRequestReceived(0),
|
||||
_localPort(0),
|
||||
_localSocket(localSocket),
|
||||
_latencyMean(0.0),
|
||||
_latencyVariance(0.0),
|
||||
_packetLossRatio(0.0),
|
||||
_packetErrorRatio(0.0),
|
||||
_assignedFlowCount(0),
|
||||
_valid(true),
|
||||
_eligible(false),
|
||||
_bonded(false),
|
||||
_mtu(0),
|
||||
_givenLinkSpeed(0),
|
||||
_relativeQuality(0),
|
||||
_latency(0xffff),
|
||||
_addr(addr),
|
||||
_ipScope(addr.ipScope())
|
||||
{}
|
||||
Path(const int64_t localSocket, const InetAddress& addr)
|
||||
: _lastOut(0)
|
||||
, _lastIn(0)
|
||||
, _lastTrustEstablishedPacketReceived(0)
|
||||
, _lastEchoRequestReceived(0)
|
||||
, _localPort(0)
|
||||
, _localSocket(localSocket)
|
||||
, _latencyMean(0.0)
|
||||
, _latencyVariance(0.0)
|
||||
, _packetLossRatio(0.0)
|
||||
, _packetErrorRatio(0.0)
|
||||
, _assignedFlowCount(0)
|
||||
, _valid(true)
|
||||
, _eligible(false)
|
||||
, _bonded(false)
|
||||
, _mtu(0)
|
||||
, _givenLinkSpeed(0)
|
||||
, _relativeQuality(0)
|
||||
, _latency(0xffff)
|
||||
, _addr(addr)
|
||||
, _ipScope(addr.ipScope())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a packet is received from this remote path, regardless of content
|
||||
|
@ -138,7 +150,10 @@ public:
|
|||
/**
|
||||
* Set time last trusted packet was received (done in Peer::received())
|
||||
*/
|
||||
inline void trustedPacketReceived(const uint64_t t) { _lastTrustEstablishedPacketReceived = t; }
|
||||
inline void trustedPacketReceived(const uint64_t t)
|
||||
{
|
||||
_lastTrustEstablishedPacketReceived = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet via this path (last out time is also updated)
|
||||
|
@ -157,7 +172,10 @@ public:
|
|||
*
|
||||
* @param t Time of send
|
||||
*/
|
||||
inline void sent(const int64_t t) { _lastOut = t; }
|
||||
inline void sent(const int64_t t)
|
||||
{
|
||||
_lastOut = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update path latency with a new measurement
|
||||
|
@ -169,7 +187,8 @@ public:
|
|||
unsigned int pl = _latency;
|
||||
if (pl < 0xffff) {
|
||||
_latency = (pl + l) / 2;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_latency = l;
|
||||
}
|
||||
}
|
||||
|
@ -177,27 +196,42 @@ public:
|
|||
/**
|
||||
* @return Local socket as specified by external code
|
||||
*/
|
||||
inline int64_t localSocket() const { return _localSocket; }
|
||||
inline int64_t localSocket() const
|
||||
{
|
||||
return _localSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Local port corresponding to the localSocket
|
||||
*/
|
||||
inline int64_t localPort() const { return _localPort; }
|
||||
inline int64_t localPort() const
|
||||
{
|
||||
return _localPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Physical address
|
||||
*/
|
||||
inline const InetAddress &address() const { return _addr; }
|
||||
inline const InetAddress& address() const
|
||||
{
|
||||
return _addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IP scope -- faster shortcut for address().ipScope()
|
||||
*/
|
||||
inline InetAddress::IpScope ipScope() const { return _ipScope; }
|
||||
inline InetAddress::IpScope ipScope() const
|
||||
{
|
||||
return _ipScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if path has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms
|
||||
*/
|
||||
inline bool trustEstablished(const int64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); }
|
||||
inline bool trustEstablished(const int64_t now) const
|
||||
{
|
||||
return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Preference rank, higher == better
|
||||
|
@ -253,7 +287,10 @@ public:
|
|||
/**
|
||||
* @return Latency or 0xffff if unknown
|
||||
*/
|
||||
inline unsigned int latency() const { return _latency; }
|
||||
inline unsigned int latency() const
|
||||
{
|
||||
return _latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Path quality -- lower is better
|
||||
|
@ -268,34 +305,50 @@ public:
|
|||
/**
|
||||
* @return True if this path is alive (receiving heartbeats)
|
||||
*/
|
||||
inline bool alive(const int64_t now) const {
|
||||
inline bool alive(const int64_t now) const
|
||||
{
|
||||
return (now - _lastIn) < (ZT_PATH_HEARTBEAT_PERIOD + 5000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this path needs a heartbeat
|
||||
*/
|
||||
inline bool needsHeartbeat(const int64_t now) const { return ((now - _lastOut) >= ZT_PATH_HEARTBEAT_PERIOD); }
|
||||
inline bool needsHeartbeat(const int64_t now) const
|
||||
{
|
||||
return ((now - _lastOut) >= ZT_PATH_HEARTBEAT_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last time we sent something
|
||||
*/
|
||||
inline int64_t lastOut() const { return _lastOut; }
|
||||
inline int64_t lastOut() const
|
||||
{
|
||||
return _lastOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last time we received anything
|
||||
*/
|
||||
inline int64_t lastIn() const { return _lastIn; }
|
||||
inline int64_t lastIn() const
|
||||
{
|
||||
return _lastIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the age of the path in terms of receiving packets
|
||||
*/
|
||||
inline int64_t age(int64_t now) { return (now - _lastIn); }
|
||||
inline int64_t age(int64_t now)
|
||||
{
|
||||
return (now - _lastIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time last trust-established packet was received
|
||||
*/
|
||||
inline int64_t lastTrustEstablishedPacketReceived() const { return _lastTrustEstablishedPacketReceived; }
|
||||
inline int64_t lastTrustEstablishedPacketReceived() const
|
||||
{
|
||||
return _lastTrustEstablishedPacketReceived;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rate limit gate for inbound ECHO requests
|
||||
|
@ -312,68 +365,101 @@ public:
|
|||
/**
|
||||
* @return Mean latency as reported by the bonding layer
|
||||
*/
|
||||
inline float latencyMean() const { return _latencyMean; }
|
||||
inline float latencyMean() const
|
||||
{
|
||||
return _latencyMean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Latency variance as reported by the bonding layer
|
||||
*/
|
||||
inline float latencyVariance() const { return _latencyVariance; }
|
||||
inline float latencyVariance() const
|
||||
{
|
||||
return _latencyVariance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Packet Loss Ratio as reported by the bonding layer
|
||||
*/
|
||||
inline float packetLossRatio() const { return _packetLossRatio; }
|
||||
inline float packetLossRatio() const
|
||||
{
|
||||
return _packetLossRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Packet Error Ratio as reported by the bonding layer
|
||||
*/
|
||||
inline float packetErrorRatio() const { return _packetErrorRatio; }
|
||||
inline float packetErrorRatio() const
|
||||
{
|
||||
return _packetErrorRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Number of flows assigned to this path
|
||||
*/
|
||||
inline unsigned int assignedFlowCount() const { return _assignedFlowCount; }
|
||||
inline unsigned int assignedFlowCount() const
|
||||
{
|
||||
return _assignedFlowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this path is valid as reported by the bonding layer. The bonding layer
|
||||
* actually checks with Phy to see if the interface is still up
|
||||
*/
|
||||
inline bool valid() const { return _valid; }
|
||||
inline bool valid() const
|
||||
{
|
||||
return _valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this path is eligible for use in a bond as reported by the bonding layer
|
||||
*/
|
||||
inline bool eligible() const { return _eligible; }
|
||||
inline bool eligible() const
|
||||
{
|
||||
return _eligible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this path is bonded as reported by the bonding layer
|
||||
*/
|
||||
inline bool bonded() const { return _bonded; }
|
||||
inline bool bonded() const
|
||||
{
|
||||
return _bonded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the user-specified MTU for this path (determined by MTU for parent link)
|
||||
*/
|
||||
inline uint16_t mtu() const { return _mtu; }
|
||||
inline uint16_t mtu() const
|
||||
{
|
||||
return _mtu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Given link capacity as reported by the bonding layer
|
||||
*/
|
||||
inline uint32_t givenLinkSpeed() const { return _givenLinkSpeed; }
|
||||
inline uint32_t givenLinkSpeed() const
|
||||
{
|
||||
return _givenLinkSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Path's quality as reported by the bonding layer
|
||||
*/
|
||||
inline float relativeQuality() const { return _relativeQuality; }
|
||||
inline float relativeQuality() const
|
||||
{
|
||||
return _relativeQuality;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Physical interface name that this path lives on
|
||||
*/
|
||||
char *ifname() {
|
||||
char* ifname()
|
||||
{
|
||||
return _ifname;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char _ifname[ZT_MAX_PHYSIFNAME] = {};
|
||||
|
||||
volatile int64_t _lastOut;
|
||||
|
|
|
@ -11,19 +11,20 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Peer.hpp"
|
||||
|
||||
#include "../version.h"
|
||||
#include "Constants.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "RingBuffer.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "RingBuffer.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -129,7 +130,8 @@ void Peer::received(
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +160,8 @@ void Peer::received(
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
replacePath = i;
|
||||
break;
|
||||
}
|
||||
|
@ -176,17 +179,20 @@ void Peer::received(
|
|||
_bond->nominatePathToBond(_paths[replacePath].p, now);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Mutex::Lock ltl(_lastTriedPath_m);
|
||||
|
||||
bool triedTooRecently = false;
|
||||
for (std::list<std::pair<Path*, int64_t> >::iterator i(_lastTriedPath.begin()); i != _lastTriedPath.end();) {
|
||||
if ((now - i->second) > 1000) {
|
||||
_lastTriedPath.erase(i++);
|
||||
} else if (i->first == path.ptr()) {
|
||||
}
|
||||
else if (i->first == path.ptr()) {
|
||||
++i;
|
||||
triedTooRecently = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +285,8 @@ SharedPtr<Path> Peer::getAppropriatePath(int64_t now, bool includeExpired, int32
|
|||
bestPath = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +337,8 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &o
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +363,8 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &o
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -388,14 +397,16 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &o
|
|||
if (other->_paths[theirs].p->address().ss_family == AF_INET6) {
|
||||
outp.append((uint8_t)16);
|
||||
outp.append(other->_paths[theirs].p->address().rawIpData(), 16);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
outp.append((uint8_t)4);
|
||||
outp.append(other->_paths[theirs].p->address().rawIpData(), 4);
|
||||
}
|
||||
outp.armor(_key, true, false, aesKeysIfSupported(), _id);
|
||||
Metrics::pkt_rendezvous_out++;
|
||||
_paths[mine].p->send(RR, tPtr, outp.data(), outp.size(), now);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Packet outp(other->_id.address(), RR->identity.address(), Packet::VERB_RENDEZVOUS);
|
||||
outp.append((uint8_t)0);
|
||||
_id.address().appendTo(outp);
|
||||
|
@ -403,7 +414,8 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &o
|
|||
if (_paths[mine].p->address().ss_family == AF_INET6) {
|
||||
outp.append((uint8_t)16);
|
||||
outp.append(_paths[mine].p->address().rawIpData(), 16);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
outp.append((uint8_t)4);
|
||||
outp.append(_paths[mine].p->address().rawIpData(), 4);
|
||||
}
|
||||
|
@ -456,7 +468,8 @@ void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atA
|
|||
outp.armor(_key, false, false, nullptr, _id);
|
||||
RR->node->expectReplyTo(outp.packetId());
|
||||
RR->node->putPacket(tPtr, RR->node->lowBandwidthModeEnabled() ? localSocket : -1, atAddress, outp.data(), outp.size());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->node->expectReplyTo(outp.packetId());
|
||||
RR->sw->send(tPtr, outp, true);
|
||||
}
|
||||
|
@ -470,7 +483,8 @@ void Peer::attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAdd
|
|||
Metrics::pkt_echo_out++;
|
||||
RR->node->expectReplyTo(outp.packetId());
|
||||
RR->node->putPacket(tPtr, localSocket, atAddress, outp.data(), outp.size());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sendHELLO(tPtr, localSocket, atAddress, now);
|
||||
}
|
||||
}
|
||||
|
@ -551,7 +565,8 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now)
|
|||
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
|
||||
if (_paths[i].p) {
|
||||
maxPriority = std::max(_paths[i].priority, maxPriority);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -566,7 +581,8 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now)
|
|||
_paths[i].p->sent(now);
|
||||
sent |= (_paths[i].p->address().ss_family == AF_INET) ? 0x1 : 0x2;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_paths[i] = _PeerPath();
|
||||
deletionOccurred = true;
|
||||
}
|
||||
|
@ -622,7 +638,8 @@ void Peer::clusterRedirect(void *tPtr,const SharedPtr<Path> &originatingPath,con
|
|||
newPriority = _paths[i].priority;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -666,14 +683,14 @@ void Peer::resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddres
|
|||
_paths[i].p->sent(now);
|
||||
_paths[i].lr = 0; // path will not be used unless it speaks again
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::recordOutgoingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
|
||||
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
|
||||
void Peer::recordOutgoingPacket(const SharedPtr<Path>& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
|
||||
{
|
||||
#ifndef ZT_NO_PEER_METRICS
|
||||
_outgoing_packet++;
|
||||
|
@ -693,8 +710,7 @@ void Peer::recordIncomingInvalidPacket(const SharedPtr<Path>& path)
|
|||
}
|
||||
}
|
||||
|
||||
void Peer::recordIncomingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
|
||||
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
|
||||
void Peer::recordIncomingPacket(const SharedPtr<Path>& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
|
||||
{
|
||||
if (_localMultipathSupported && _bond) {
|
||||
_bond->recordIncomingPacket(path, packetId, payloadLength, verb, flowId, now);
|
||||
|
|
164
node/Peer.hpp
164
node/Peer.hpp
|
@ -14,27 +14,26 @@
|
|||
#ifndef ZT_PEER_HPP
|
||||
#define ZT_PEER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "AES.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "Bond.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Bond.hpp"
|
||||
#include "AES.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#define ZT_PEER_MAX_SERIALIZED_STATE_SIZE (sizeof(Peer) + 32 + (sizeof(Path) * 2))
|
||||
|
||||
|
@ -43,8 +42,7 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Peer on P2P Network (virtual layer 1)
|
||||
*/
|
||||
class Peer
|
||||
{
|
||||
class Peer {
|
||||
friend class SharedPtr<Peer>;
|
||||
friend class SharedPtr<Bond>;
|
||||
friend class Switch;
|
||||
|
@ -54,7 +52,8 @@ private:
|
|||
Peer() = delete; // disabled to prevent bugs -- should not be constructed uninitialized
|
||||
|
||||
public:
|
||||
~Peer() {
|
||||
~Peer()
|
||||
{
|
||||
Utils::burn(_key, sizeof(_key));
|
||||
}
|
||||
|
||||
|
@ -71,12 +70,18 @@ public:
|
|||
/**
|
||||
* @return This peer's ZT address (short for identity().address())
|
||||
*/
|
||||
inline const Address &address() const { return _id.address(); }
|
||||
inline const Address& address() const
|
||||
{
|
||||
return _id.address();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return This peer's identity
|
||||
*/
|
||||
inline const Identity &identity() const { return _id; }
|
||||
inline const Identity& identity() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log receipt of an authenticated packet
|
||||
|
@ -122,7 +127,8 @@ public:
|
|||
if (((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION) && (_paths[i].p->address() == addr)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,8 +165,7 @@ public:
|
|||
* @param flowId Flow ID
|
||||
* @param now Current time
|
||||
*/
|
||||
void recordIncomingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
|
||||
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
|
||||
void recordIncomingPacket(const SharedPtr<Path>& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -171,8 +176,7 @@ public:
|
|||
* @param flowId Flow ID
|
||||
* @param now Current time
|
||||
*/
|
||||
void recordOutgoingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
|
||||
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
|
||||
void recordOutgoingPacket(const SharedPtr<Path>& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
|
||||
|
||||
/**
|
||||
* Record an invalid incoming packet. This packet failed
|
||||
|
@ -296,19 +300,31 @@ public:
|
|||
/**
|
||||
* @return Time of last receive of anything, whether direct or relayed
|
||||
*/
|
||||
inline int64_t lastReceive() const { return _lastReceive; }
|
||||
inline int64_t lastReceive() const
|
||||
{
|
||||
return _lastReceive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
|
||||
*/
|
||||
inline bool isAlive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
|
||||
inline bool isAlive(const int64_t now) const
|
||||
{
|
||||
return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this peer has sent us real network traffic recently
|
||||
*/
|
||||
inline int64_t isActive(int64_t now) const { return ((now - _lastNontrivialReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
|
||||
inline int64_t isActive(int64_t now) const
|
||||
{
|
||||
return ((now - _lastNontrivialReceive) < ZT_PEER_ACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
inline int64_t lastSentFullHello() { return _lastSentFullHello; }
|
||||
inline int64_t lastSentFullHello()
|
||||
{
|
||||
return _lastSentFullHello;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
|
||||
|
@ -317,7 +333,8 @@ public:
|
|||
{
|
||||
if (_localMultipathSupported) {
|
||||
return (int)_lastComputedAggregateMeanLatency;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
SharedPtr<Path> bp(getAppropriatePath(now, false));
|
||||
if (bp) {
|
||||
return (unsigned int)bp->latency();
|
||||
|
@ -353,7 +370,10 @@ public:
|
|||
/**
|
||||
* @return 256-bit secret symmetric encryption key
|
||||
*/
|
||||
inline const unsigned char *key() const { return _key; }
|
||||
inline const unsigned char* key() const
|
||||
{
|
||||
return _key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the currently known remote version of this peer's client
|
||||
|
@ -371,17 +391,35 @@ public:
|
|||
_vRevision = (uint16_t)vrev;
|
||||
}
|
||||
|
||||
inline unsigned int remoteVersionProtocol() const { return _vProto; }
|
||||
inline unsigned int remoteVersionMajor() const { return _vMajor; }
|
||||
inline unsigned int remoteVersionMinor() const { return _vMinor; }
|
||||
inline unsigned int remoteVersionRevision() const { return _vRevision; }
|
||||
inline unsigned int remoteVersionProtocol() const
|
||||
{
|
||||
return _vProto;
|
||||
}
|
||||
inline unsigned int remoteVersionMajor() const
|
||||
{
|
||||
return _vMajor;
|
||||
}
|
||||
inline unsigned int remoteVersionMinor() const
|
||||
{
|
||||
return _vMinor;
|
||||
}
|
||||
inline unsigned int remoteVersionRevision() const
|
||||
{
|
||||
return _vRevision;
|
||||
}
|
||||
|
||||
inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
|
||||
inline bool remoteVersionKnown() const
|
||||
{
|
||||
return ((_vMajor > 0) || (_vMinor > 0) || (_vRevision > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if peer has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms
|
||||
*/
|
||||
inline bool trustEstablished(const int64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); }
|
||||
inline bool trustEstablished(const int64_t now) const
|
||||
{
|
||||
return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rate limit gate for VERB_PUSH_DIRECT_PATHS
|
||||
|
@ -390,7 +428,8 @@ public:
|
|||
{
|
||||
if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME) {
|
||||
++_directPathPushCutoffCount;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_directPathPushCutoffCount = 0;
|
||||
}
|
||||
_lastDirectPathPushReceive = now;
|
||||
|
@ -496,8 +535,7 @@ public:
|
|||
*
|
||||
* This does not serialize everything, just non-ephemeral information.
|
||||
*/
|
||||
template<unsigned int C>
|
||||
inline void serializeForCache(Buffer<C> &b) const
|
||||
template <unsigned int C> inline void serializeForCache(Buffer<C>& b) const
|
||||
{
|
||||
b.append((uint8_t)2);
|
||||
|
||||
|
@ -514,7 +552,8 @@ public:
|
|||
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
|
||||
if (_paths[i].p) {
|
||||
++pc;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -525,8 +564,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline static SharedPtr<Peer> deserializeFromCache(int64_t now,void *tPtr,Buffer<C> &b,const RuntimeEnvironment *renv)
|
||||
template <unsigned int C> inline static SharedPtr<Peer> deserializeFromCache(int64_t now, void* tPtr, Buffer<C>& b, const RuntimeEnvironment* renv)
|
||||
{
|
||||
try {
|
||||
unsigned int ptr = 0;
|
||||
|
@ -563,13 +601,15 @@ public:
|
|||
if (inaddr) {
|
||||
p->attemptToContactAt(tPtr, -1, inaddr, now, true);
|
||||
}
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
}
|
||||
|
@ -577,12 +617,16 @@ public:
|
|||
/**
|
||||
* @return The bonding policy used to reach this peer
|
||||
*/
|
||||
SharedPtr<Bond> bond() { return _bond; }
|
||||
SharedPtr<Bond> bond()
|
||||
{
|
||||
return _bond;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The bonding policy used to reach this peer
|
||||
*/
|
||||
inline int8_t bondingPolicy() {
|
||||
inline int8_t bondingPolicy()
|
||||
{
|
||||
Mutex::Lock _l(_bond_m);
|
||||
if (_bond) {
|
||||
return _bond->policy();
|
||||
|
@ -593,7 +637,8 @@ public:
|
|||
/**
|
||||
* @return the number of links in this bond which are considered alive
|
||||
*/
|
||||
inline uint8_t getNumAliveLinks() {
|
||||
inline uint8_t getNumAliveLinks()
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
if (_bond) {
|
||||
return _bond->getNumAliveLinks();
|
||||
|
@ -604,7 +649,8 @@ public:
|
|||
/**
|
||||
* @return the number of links in this bond
|
||||
*/
|
||||
inline uint8_t getNumTotalLinks() {
|
||||
inline uint8_t getNumTotalLinks()
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
if (_bond) {
|
||||
return _bond->getNumTotalLinks();
|
||||
|
@ -616,15 +662,20 @@ public:
|
|||
//{ return (const AES *)0; }
|
||||
|
||||
inline const AES* aesKeysIfSupported() const
|
||||
{ return (_vProto >= 12) ? _aesKeys : (const AES *)0; }
|
||||
{
|
||||
return (_vProto >= 12) ? _aesKeys : (const AES*)0;
|
||||
}
|
||||
|
||||
inline const AES* aesKeys() const
|
||||
{ return _aesKeys; }
|
||||
{
|
||||
return _aesKeys;
|
||||
}
|
||||
|
||||
private:
|
||||
struct _PeerPath
|
||||
struct _PeerPath {
|
||||
_PeerPath() : lr(0), p(), priority(1)
|
||||
{
|
||||
_PeerPath() : lr(0),p(),priority(1) {}
|
||||
}
|
||||
int64_t lr; // time of last valid ZeroTier packet
|
||||
SharedPtr<Path> p;
|
||||
long priority; // >= 1, higher is better
|
||||
|
@ -692,11 +743,10 @@ private:
|
|||
|
||||
// Add a swap() for shared ptr's to peers to speed up peer sorts
|
||||
namespace std {
|
||||
template<>
|
||||
inline void swap(ZeroTier::SharedPtr<ZeroTier::Peer> &a,ZeroTier::SharedPtr<ZeroTier::Peer> &b)
|
||||
template <> inline void swap(ZeroTier::SharedPtr<ZeroTier::Peer>& a, ZeroTier::SharedPtr<ZeroTier::Peer>& b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,11 +4,12 @@ D. J. Bernstein
|
|||
Public domain.
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Poly1305.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -39,8 +40,18 @@ typedef struct poly1305_context {
|
|||
} uint128_t;
|
||||
|
||||
#define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)
|
||||
#define ADD(out, in) { unsigned long long t = out.lo; out.lo += in.lo; out.hi += (out.lo < t) + in.hi; }
|
||||
#define ADDLO(out, in) { unsigned long long t = out.lo; out.lo += in; out.hi += (out.lo < t); }
|
||||
#define ADD(out, in) \
|
||||
{ \
|
||||
unsigned long long t = out.lo; \
|
||||
out.lo += in.lo; \
|
||||
out.hi += (out.lo < t) + in.hi; \
|
||||
}
|
||||
#define ADDLO(out, in) \
|
||||
{ \
|
||||
unsigned long long t = out.lo; \
|
||||
out.lo += in; \
|
||||
out.hi += (out.lo < t); \
|
||||
}
|
||||
#define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
|
||||
#define LO(in) (in.lo)
|
||||
|
||||
|
@ -76,15 +87,9 @@ typedef struct poly1305_state_internal_t {
|
|||
#if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN)
|
||||
static inline unsigned long long U8TO64(const unsigned char* p)
|
||||
{
|
||||
return
|
||||
(((unsigned long long)(p[0] & 0xff) ) |
|
||||
((unsigned long long)(p[1] & 0xff) << 8) |
|
||||
((unsigned long long)(p[2] & 0xff) << 16) |
|
||||
((unsigned long long)(p[3] & 0xff) << 24) |
|
||||
((unsigned long long)(p[4] & 0xff) << 32) |
|
||||
((unsigned long long)(p[5] & 0xff) << 40) |
|
||||
((unsigned long long)(p[6] & 0xff) << 48) |
|
||||
((unsigned long long)(p[7] & 0xff) << 56));
|
||||
return (
|
||||
((unsigned long long)(p[0] & 0xff)) | ((unsigned long long)(p[1] & 0xff) << 8) | ((unsigned long long)(p[2] & 0xff) << 16) | ((unsigned long long)(p[3] & 0xff) << 24) | ((unsigned long long)(p[4] & 0xff) << 32)
|
||||
| ((unsigned long long)(p[5] & 0xff) << 40) | ((unsigned long long)(p[6] & 0xff) << 48) | ((unsigned long long)(p[7] & 0xff) << 56));
|
||||
}
|
||||
#else
|
||||
#define U8TO64(p) (*reinterpret_cast<const unsigned long long*>(p))
|
||||
|
@ -106,7 +111,8 @@ static inline void U64TO8(unsigned char *p, unsigned long long v)
|
|||
#define U64TO8(p, v) ((*reinterpret_cast<unsigned long long*>(p)) = (v))
|
||||
#endif
|
||||
|
||||
static inline void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
|
||||
static inline void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
|
||||
{
|
||||
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
|
||||
unsigned long long t0, t1;
|
||||
|
||||
|
@ -131,7 +137,8 @@ static inline void poly1305_init(poly1305_context *ctx, const unsigned char key[
|
|||
st->final = 0;
|
||||
}
|
||||
|
||||
static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) {
|
||||
static inline void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes)
|
||||
{
|
||||
const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */
|
||||
unsigned long long r0, r1, r2;
|
||||
unsigned long long s1, s2;
|
||||
|
@ -162,15 +169,34 @@ static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned
|
|||
h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d);
|
||||
MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d);
|
||||
MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
|
||||
MUL(d0, h0, r0);
|
||||
MUL(d, h1, s2);
|
||||
ADD(d0, d);
|
||||
MUL(d, h2, s1);
|
||||
ADD(d0, d);
|
||||
MUL(d1, h0, r1);
|
||||
MUL(d, h1, r0);
|
||||
ADD(d1, d);
|
||||
MUL(d, h2, s2);
|
||||
ADD(d1, d);
|
||||
MUL(d2, h0, r2);
|
||||
MUL(d, h1, r1);
|
||||
ADD(d2, d);
|
||||
MUL(d, h2, r0);
|
||||
ADD(d2, d);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
|
||||
ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
|
||||
ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff;
|
||||
c = SHR(d0, 44);
|
||||
h0 = LO(d0) & 0xfffffffffff;
|
||||
ADDLO(d1, c);
|
||||
c = SHR(d1, 44);
|
||||
h1 = LO(d1) & 0xfffffffffff;
|
||||
ADDLO(d2, c);
|
||||
c = SHR(d2, 42);
|
||||
h2 = LO(d2) & 0x3ffffffffff;
|
||||
h0 += c * 5;
|
||||
c = (h0 >> 44);
|
||||
h0 = h0 & 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
m += poly1305_block_size;
|
||||
|
@ -182,7 +208,8 @@ static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned
|
|||
st->h[2] = h2;
|
||||
}
|
||||
|
||||
static inline void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
|
||||
static inline void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
|
||||
{
|
||||
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
|
||||
unsigned long long h0, h1, h2, c;
|
||||
unsigned long long g0, g1, g2;
|
||||
|
@ -204,17 +231,32 @@ static inline void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
|
|||
h1 = st->h[1];
|
||||
h2 = st->h[2];
|
||||
|
||||
c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
c = (h1 >> 44);
|
||||
h1 &= 0xfffffffffff;
|
||||
h2 += c;
|
||||
c = (h2 >> 42);
|
||||
h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5;
|
||||
c = (h0 >> 44);
|
||||
h0 &= 0xfffffffffff;
|
||||
h1 += c;
|
||||
c = (h1 >> 44);
|
||||
h1 &= 0xfffffffffff;
|
||||
h2 += c;
|
||||
c = (h2 >> 42);
|
||||
h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5;
|
||||
c = (h0 >> 44);
|
||||
h0 &= 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
|
||||
g0 = h0 + 5;
|
||||
c = (g0 >> 44);
|
||||
g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c;
|
||||
c = (g1 >> 44);
|
||||
g1 &= 0xfffffffffff;
|
||||
g2 = h2 + c - ((unsigned long long)1 << 42);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
|
@ -231,9 +273,14 @@ static inline void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
|
|||
t0 = st->pad[0];
|
||||
t1 = st->pad[1];
|
||||
|
||||
h0 += (( t0 ) & 0xfffffffffff) ; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c; h2 &= 0x3ffffffffff;
|
||||
h0 += ((t0) & 0xfffffffffff);
|
||||
c = (h0 >> 44);
|
||||
h0 &= 0xfffffffffff;
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
|
||||
c = (h1 >> 44);
|
||||
h1 &= 0xfffffffffff;
|
||||
h2 += (((t1 >> 24)) & 0x3ffffffffff) + c;
|
||||
h2 &= 0x3ffffffffff;
|
||||
|
||||
/* mac = h % (2^128) */
|
||||
h0 = ((h0) | (h1 << 44));
|
||||
|
@ -273,26 +320,22 @@ typedef struct poly1305_state_internal_t {
|
|||
} poly1305_state_internal_t;
|
||||
|
||||
/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */
|
||||
static unsigned long
|
||||
U8TO32(const unsigned char *p) {
|
||||
return
|
||||
(((unsigned long)(p[0] & 0xff) ) |
|
||||
((unsigned long)(p[1] & 0xff) << 8) |
|
||||
((unsigned long)(p[2] & 0xff) << 16) |
|
||||
((unsigned long)(p[3] & 0xff) << 24));
|
||||
static unsigned long U8TO32(const unsigned char* p)
|
||||
{
|
||||
return (((unsigned long)(p[0] & 0xff)) | ((unsigned long)(p[1] & 0xff) << 8) | ((unsigned long)(p[2] & 0xff) << 16) | ((unsigned long)(p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */
|
||||
static void
|
||||
U32TO8(unsigned char *p, unsigned long v) {
|
||||
static void U32TO8(unsigned char* p, unsigned long v)
|
||||
{
|
||||
p[0] = (v) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
|
||||
static inline void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
|
||||
{
|
||||
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
|
||||
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
|
@ -319,8 +362,8 @@ poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
|
|||
st->final = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) {
|
||||
static inline void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes)
|
||||
{
|
||||
const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
|
||||
unsigned long r0, r1, r2, r3, r4;
|
||||
unsigned long s1, s2, s3, s4;
|
||||
|
@ -361,12 +404,23 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t by
|
|||
d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
|
||||
d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
|
||||
d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
|
||||
d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;
|
||||
d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff;
|
||||
h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
|
||||
c = (unsigned long)(d0 >> 26);
|
||||
h0 = (unsigned long)d0 & 0x3ffffff;
|
||||
d1 += c;
|
||||
c = (unsigned long)(d1 >> 26);
|
||||
h1 = (unsigned long)d1 & 0x3ffffff;
|
||||
d2 += c;
|
||||
c = (unsigned long)(d2 >> 26);
|
||||
h2 = (unsigned long)d2 & 0x3ffffff;
|
||||
d3 += c;
|
||||
c = (unsigned long)(d3 >> 26);
|
||||
h3 = (unsigned long)d3 & 0x3ffffff;
|
||||
d4 += c;
|
||||
c = (unsigned long)(d4 >> 26);
|
||||
h4 = (unsigned long)d4 & 0x3ffffff;
|
||||
h0 += c * 5;
|
||||
c = (h0 >> 26);
|
||||
h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
m += poly1305_block_size;
|
||||
|
@ -380,8 +434,8 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t by
|
|||
st->h[4] = h4;
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
|
||||
static inline void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
|
||||
{
|
||||
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
|
||||
unsigned long h0, h1, h2, h3, h4, c;
|
||||
unsigned long g0, g1, g2, g3, g4;
|
||||
|
@ -406,18 +460,35 @@ poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
|
|||
h3 = st->h[3];
|
||||
h4 = st->h[4];
|
||||
|
||||
c = h1 >> 26; h1 = h1 & 0x3ffffff;
|
||||
h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
|
||||
h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
|
||||
h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
|
||||
h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
c = h1 >> 26;
|
||||
h1 = h1 & 0x3ffffff;
|
||||
h2 += c;
|
||||
c = h2 >> 26;
|
||||
h2 = h2 & 0x3ffffff;
|
||||
h3 += c;
|
||||
c = h3 >> 26;
|
||||
h3 = h3 & 0x3ffffff;
|
||||
h4 += c;
|
||||
c = h4 >> 26;
|
||||
h4 = h4 & 0x3ffffff;
|
||||
h0 += c * 5;
|
||||
c = h0 >> 26;
|
||||
h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g0 = h0 + 5;
|
||||
c = g0 >> 26;
|
||||
g0 &= 0x3ffffff;
|
||||
g1 = h1 + c;
|
||||
c = g1 >> 26;
|
||||
g1 &= 0x3ffffff;
|
||||
g2 = h2 + c;
|
||||
c = g2 >> 26;
|
||||
g2 &= 0x3ffffff;
|
||||
g3 = h3 + c;
|
||||
c = g3 >> 26;
|
||||
g3 &= 0x3ffffff;
|
||||
g4 = h4 + c - (1 << 26);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
|
@ -441,10 +512,14 @@ poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
|
|||
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
|
||||
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f;
|
||||
f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f;
|
||||
f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f;
|
||||
f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f;
|
||||
f = (unsigned long long)h0 + st->pad[0];
|
||||
h0 = (unsigned long)f;
|
||||
f = (unsigned long long)h1 + st->pad[1] + (f >> 32);
|
||||
h1 = (unsigned long)f;
|
||||
f = (unsigned long long)h2 + st->pad[2] + (f >> 32);
|
||||
h2 = (unsigned long)f;
|
||||
f = (unsigned long long)h3 + st->pad[3] + (f >> 32);
|
||||
h3 = (unsigned long)f;
|
||||
|
||||
U32TO8(mac + 0, h0);
|
||||
U32TO8(mac + 4, h1);
|
||||
|
@ -472,7 +547,8 @@ poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
|
|||
|
||||
#endif // MSC/GCC or not
|
||||
|
||||
static inline void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
|
||||
static inline void poly1305_update(poly1305_context* ctx, const unsigned char* m, size_t bytes)
|
||||
{
|
||||
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
|
||||
size_t i;
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ namespace ZeroTier {
|
|||
* keystream as a one-time-use key. These 32 bytes are then discarded and
|
||||
* the packet is encrypted with the next N bytes.
|
||||
*/
|
||||
class Poly1305
|
||||
{
|
||||
class Poly1305 {
|
||||
public:
|
||||
/**
|
||||
* Compute a one-time authentication code
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
/****/
|
||||
|
||||
#include "Revocation.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
#include "Identity.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -35,7 +36,8 @@ int Revocation::verify(const RuntimeEnvironment *RR,void *tPtr) const
|
|||
Buffer<sizeof(Revocation) + 64> tmp;
|
||||
this->serialize(tmp, true);
|
||||
return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
#ifndef ZT_REVOCATION_HPP
|
||||
#define ZT_REVOCATION_HPP
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Credential.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Identity.hpp"
|
||||
|
||||
/**
|
||||
* Flag: fast propagation via rumor mill algorithm
|
||||
|
@ -40,20 +40,14 @@ class RuntimeEnvironment;
|
|||
/**
|
||||
* Revocation certificate to instantaneously revoke a COM, capability, or tag
|
||||
*/
|
||||
class Revocation : public Credential
|
||||
{
|
||||
class Revocation : public Credential {
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_REVOCATION; }
|
||||
static inline Credential::Type credentialType()
|
||||
{
|
||||
return Credential::CREDENTIAL_TYPE_REVOCATION;
|
||||
}
|
||||
|
||||
Revocation() :
|
||||
_id(0),
|
||||
_credentialId(0),
|
||||
_networkId(0),
|
||||
_threshold(0),
|
||||
_flags(0),
|
||||
_target(),
|
||||
_signedBy(),
|
||||
_type(Credential::CREDENTIAL_TYPE_NULL)
|
||||
Revocation() : _id(0), _credentialId(0), _networkId(0), _threshold(0), _flags(0), _target(), _signedBy(), _type(Credential::CREDENTIAL_TYPE_NULL)
|
||||
{
|
||||
memset(_signature.data, 0, sizeof(_signature.data));
|
||||
}
|
||||
|
@ -67,28 +61,52 @@ public:
|
|||
* @param tgt Target node whose credential(s) are being revoked
|
||||
* @param ct Credential type being revoked
|
||||
*/
|
||||
Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const int64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) :
|
||||
_id(i),
|
||||
_credentialId(cid),
|
||||
_networkId(nwid),
|
||||
_threshold(thr),
|
||||
_flags(fl),
|
||||
_target(tgt),
|
||||
_signedBy(),
|
||||
_type(ct)
|
||||
Revocation(const uint32_t i, const uint64_t nwid, const uint32_t cid, const int64_t thr, const uint64_t fl, const Address& tgt, const Credential::Type ct)
|
||||
: _id(i)
|
||||
, _credentialId(cid)
|
||||
, _networkId(nwid)
|
||||
, _threshold(thr)
|
||||
, _flags(fl)
|
||||
, _target(tgt)
|
||||
, _signedBy()
|
||||
, _type(ct)
|
||||
{
|
||||
memset(_signature.data, 0, sizeof(_signature.data));
|
||||
}
|
||||
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline uint32_t credentialId() const { return _credentialId; }
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline int64_t threshold() const { return _threshold; }
|
||||
inline const Address &target() const { return _target; }
|
||||
inline const Address &signer() const { return _signedBy; }
|
||||
inline Credential::Type type() const { return _type; }
|
||||
inline uint32_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
inline uint32_t credentialId() const
|
||||
{
|
||||
return _credentialId;
|
||||
}
|
||||
inline uint64_t networkId() const
|
||||
{
|
||||
return _networkId;
|
||||
}
|
||||
inline int64_t threshold() const
|
||||
{
|
||||
return _threshold;
|
||||
}
|
||||
inline const Address& target() const
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
inline const Address& signer() const
|
||||
{
|
||||
return _signedBy;
|
||||
}
|
||||
inline Credential::Type type() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
|
||||
inline bool fastPropagate() const
|
||||
{
|
||||
return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signer Signing identity, must have private key
|
||||
|
@ -115,8 +133,7 @@ public:
|
|||
*/
|
||||
int verify(const RuntimeEnvironment* RR, void* tPtr) const;
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, const bool forSign = false) const
|
||||
{
|
||||
if (forSign) {
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
@ -147,8 +164,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
*this = Revocation();
|
||||
|
||||
|
@ -177,10 +193,12 @@ public:
|
|||
p += 2;
|
||||
memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN);
|
||||
p += ZT_ECC_SIGNATURE_LEN;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p += 2 + b.template at<uint16_t>(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
#ifndef ZT_RINGBUFFER_H
|
||||
#define ZT_RINGBUFFER_H
|
||||
|
||||
#include <typeinfo>
|
||||
#include <cstdint>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -34,9 +34,7 @@ namespace ZeroTier {
|
|||
* to reduce the complexity of code needed to interact with this type of buffer.
|
||||
*/
|
||||
|
||||
template <class T,size_t S>
|
||||
class RingBuffer
|
||||
{
|
||||
template <class T, size_t S> class RingBuffer {
|
||||
private:
|
||||
T buf[S];
|
||||
size_t begin;
|
||||
|
@ -44,10 +42,7 @@ private:
|
|||
bool wrap;
|
||||
|
||||
public:
|
||||
RingBuffer() :
|
||||
begin(0),
|
||||
end(0),
|
||||
wrap(false)
|
||||
RingBuffer() : begin(0), end(0), wrap(false)
|
||||
{
|
||||
memset(buf, 0, sizeof(T) * S);
|
||||
}
|
||||
|
@ -87,7 +82,10 @@ public:
|
|||
* Fast erase, O(1).
|
||||
* Merely reset the buffer pointer, doesn't erase contents
|
||||
*/
|
||||
inline void reset() { consume(count()); }
|
||||
inline void reset()
|
||||
{
|
||||
consume(count());
|
||||
}
|
||||
|
||||
/**
|
||||
* adjust buffer index pointer as if we copied data out
|
||||
|
@ -157,7 +155,10 @@ public:
|
|||
/**
|
||||
* @return The most recently pushed element on the buffer
|
||||
*/
|
||||
inline T get_most_recent() { return *(buf + end); }
|
||||
inline T get_most_recent()
|
||||
{
|
||||
return *(buf + end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dest Destination buffer
|
||||
|
@ -193,9 +194,11 @@ public:
|
|||
{
|
||||
if (end == begin) {
|
||||
return wrap ? S : 0;
|
||||
} else if (end > begin) {
|
||||
}
|
||||
else if (end > begin) {
|
||||
return end - begin;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return S + end - begin;
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +206,10 @@ public:
|
|||
/**
|
||||
* @return The number of slots that are unused in the buffer
|
||||
*/
|
||||
inline size_t getFree() { return S - count(); }
|
||||
inline size_t getFree()
|
||||
{
|
||||
return S - count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The arithmetic mean of the contents of the buffer
|
||||
|
@ -254,7 +260,10 @@ public:
|
|||
/**
|
||||
* @return The sample standard deviation of element values
|
||||
*/
|
||||
inline float stddev() { return sqrt(variance()); }
|
||||
inline float stddev()
|
||||
{
|
||||
return sqrt(variance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The variance of element values
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#ifndef ZT_RUNTIMEENVIRONMENT_HPP
|
||||
#define ZT_RUNTIMEENVIRONMENT_HPP
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -36,17 +36,9 @@ class PacketMultiplexer;
|
|||
/**
|
||||
* Holds global state for an instance of ZeroTier::Node
|
||||
*/
|
||||
class RuntimeEnvironment
|
||||
{
|
||||
class RuntimeEnvironment {
|
||||
public:
|
||||
RuntimeEnvironment(Node *n) :
|
||||
node(n)
|
||||
,localNetworkController((NetworkController *)0)
|
||||
,rtmem((void *)0)
|
||||
,sw((Switch *)0)
|
||||
,mc((Multicaster *)0)
|
||||
,topology((Topology *)0)
|
||||
,sa((SelfAwareness *)0)
|
||||
RuntimeEnvironment(Node* n) : node(n), localNetworkController((NetworkController*)0), rtmem((void*)0), sw((Switch*)0), mc((Multicaster*)0), topology((Topology*)0), sa((SelfAwareness*)0)
|
||||
{
|
||||
publicIdentityStr[0] = (char)0;
|
||||
secretIdentityStr[0] = (char)0;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// This code is public domain, taken from a PD crypto source file on GitHub.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "SHA512.hpp"
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
#ifndef ZT_HAVE_NATIVE_SHA512
|
||||
|
@ -17,28 +18,15 @@ struct sha512_state {
|
|||
uint8_t buf[128];
|
||||
};
|
||||
|
||||
static const uint64_t K[80] = {
|
||||
0x428a2f98d728ae22ULL,0x7137449123ef65cdULL,0xb5c0fbcfec4d3b2fULL,0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL,0x59f111f1b605d019ULL,0x923f82a4af194f9bULL,0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL,0x12835b0145706fbeULL,0x243185be4ee4b28cULL,0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL,0x80deb1fe3b1696b1ULL,0x9bdc06a725c71235ULL,0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL,0xefbe4786384f25e3ULL,0x0fc19dc68b8cd5b5ULL,0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL,0x4a7484aa6ea6e483ULL,0x5cb0a9dcbd41fbd4ULL,0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL,0xa831c66d2db43210ULL,0xb00327c898fb213fULL,0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL,0xd5a79147930aa725ULL,0x06ca6351e003826fULL,0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL,0x2e1b21385c26c926ULL,0x4d2c6dfc5ac42aedULL,0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL,0x766a0abb3c77b2a8ULL,0x81c2c92e47edaee6ULL,0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL,0xa81a664bbc423001ULL,0xc24b8b70d0f89791ULL,0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL,0xd69906245565a910ULL,0xf40e35855771202aULL,0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL,0x1e376c085141ab53ULL,0x2748774cdf8eeb99ULL,0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL,0x4ed8aa4ae3418acbULL,0x5b9cca4f7763e373ULL,0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL,0x78a5636f43172f60ULL,0x84c87814a1f0ab72ULL,0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL,0xa4506cebde82bde9ULL,0xbef9a3f7b2c67915ULL,0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL,0xd186b8c721c0c207ULL,0xeada7dd6cde0eb1eULL,0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL,0x0a637dc5a2c898a6ULL,0x113f9804bef90daeULL,0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL,0x32caab7b40c72493ULL,0x3c9ebe0a15c9bebcULL,0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL,0x597f299cfc657e2aULL,0x5fcb6fab3ad6faecULL,0x6c44198c4a475817ULL
|
||||
};
|
||||
static const uint64_t K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
|
||||
0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
|
||||
0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
|
||||
0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
|
||||
0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
|
||||
|
||||
#define STORE64H(x, y) Utils::storeBigEndian<uint64_t>(y, x)
|
||||
#define LOAD64H(x, y) x = Utils::loadBigEndian<uint64_t>(y)
|
||||
|
@ -126,7 +114,8 @@ static void sha512_process(sha512_state *const md,const uint8_t *in,unsigned lon
|
|||
md->length += 128 * 8;
|
||||
in += 128;
|
||||
inlen -= 128;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
unsigned long n = std::min(inlen, (128 - md->curlen));
|
||||
Utils::copy(md->buf + md->curlen, in, n);
|
||||
md->curlen += n;
|
||||
|
@ -282,4 +271,6 @@ void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const char label,c
|
|||
// Internally re-export to included C code, which includes some fast crypto code ported in on some platforms.
|
||||
// This eliminates the need to link against a third party SHA512() from this code
|
||||
extern "C" void ZT_sha512internal(void* digest, const void* data, unsigned int len)
|
||||
{ ZeroTier::SHA512(digest,data,len); }
|
||||
{
|
||||
ZeroTier::SHA512(digest, data, len);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
* Since the original was public domain, this is too.
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#define ROTATE(v, c) (((v) << (c)) | ((v) >> (32 - (c))))
|
||||
#define XOR(v, w) ((v) ^ (w))
|
||||
#define PLUS(v, w) ((uint32_t)((v) + (w)))
|
||||
|
@ -22,7 +23,13 @@
|
|||
#ifdef ZT_NO_TYPE_PUNNING
|
||||
// Slower version that does not use type punning
|
||||
#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
|
||||
static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (uint8_t)v; c[1] = (uint8_t)(v >> 8); c[2] = (uint8_t)(v >> 16); c[3] = (uint8_t)(v >> 24); }
|
||||
static inline void U32TO8_LITTLE(uint8_t* const c, const uint32_t v)
|
||||
{
|
||||
c[0] = (uint8_t)v;
|
||||
c[1] = (uint8_t)(v >> 8);
|
||||
c[2] = (uint8_t)(v >> 16);
|
||||
c[3] = (uint8_t)(v >> 24);
|
||||
}
|
||||
#else
|
||||
// Fast version that just does 32-bit load/store
|
||||
#define U8TO32_LITTLE(p) (*((const uint32_t*)((const void*)(p))))
|
||||
|
@ -41,7 +48,13 @@ static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (ui
|
|||
|
||||
// Otherwise do it the slow, manual way on BE machines
|
||||
#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
|
||||
static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (uint8_t)v; c[1] = (uint8_t)(v >> 8); c[2] = (uint8_t)(v >> 16); c[3] = (uint8_t)(v >> 24); }
|
||||
static inline void U32TO8_LITTLE(uint8_t* const c, const uint32_t v)
|
||||
{
|
||||
c[0] = (uint8_t)v;
|
||||
c[1] = (uint8_t)(v >> 8);
|
||||
c[2] = (uint8_t)(v >> 16);
|
||||
c[3] = (uint8_t)(v >> 24);
|
||||
}
|
||||
|
||||
#endif // __GNUC__ or not
|
||||
|
||||
|
@ -51,8 +64,7 @@ static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (ui
|
|||
|
||||
// Statically compute and define SSE constants
|
||||
#ifdef ZT_SALSA20_SSE
|
||||
class _s20sseconsts
|
||||
{
|
||||
class _s20sseconsts {
|
||||
public:
|
||||
_s20sseconsts()
|
||||
{
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
#ifndef ZT_SALSA20_HPP
|
||||
#define ZT_SALSA20_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (! defined(ZT_SALSA20_SSE)) && (defined(__SSE2__) || (defined(__WINDOWS__) && ! defined(__MINGW32__) && ! defined(_M_ARM64)))
|
||||
#define ZT_SALSA20_SSE 1
|
||||
#endif
|
||||
|
@ -28,11 +28,15 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Salsa20 stream cipher
|
||||
*/
|
||||
class Salsa20
|
||||
{
|
||||
class Salsa20 {
|
||||
public:
|
||||
Salsa20() {}
|
||||
~Salsa20() { Utils::burn(&_state,sizeof(_state)); }
|
||||
Salsa20()
|
||||
{
|
||||
}
|
||||
~Salsa20()
|
||||
{
|
||||
Utils::burn(&_state, sizeof(_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* XOR d with s
|
||||
|
|
|
@ -11,38 +11,38 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "SelfAwareness.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Trace.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Trace.hpp"
|
||||
|
||||
// Entry timeout -- make it fairly long since this is just to prevent stale buildup
|
||||
#define ZT_SELFAWARENESS_ENTRY_TIMEOUT 600000
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class _ResetWithinScope
|
||||
{
|
||||
class _ResetWithinScope {
|
||||
public:
|
||||
_ResetWithinScope(void *tPtr,int64_t now,int inetAddressFamily,InetAddress::IpScope scope) :
|
||||
_now(now),
|
||||
_tPtr(tPtr),
|
||||
_family(inetAddressFamily),
|
||||
_scope(scope) {}
|
||||
_ResetWithinScope(void* tPtr, int64_t now, int inetAddressFamily, InetAddress::IpScope scope) : _now(now), _tPtr(tPtr), _family(inetAddressFamily), _scope(scope)
|
||||
{
|
||||
}
|
||||
|
||||
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); }
|
||||
inline void operator()(Topology& t, const SharedPtr<Peer>& p)
|
||||
{
|
||||
p->resetWithinScope(_tPtr, _scope, _family, _now);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _now;
|
||||
|
@ -51,9 +51,7 @@ private:
|
|||
InetAddress::IpScope _scope;
|
||||
};
|
||||
|
||||
SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_phy(128)
|
||||
SelfAwareness::SelfAwareness(const RuntimeEnvironment* renv) : RR(renv), _phy(128)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,7 +91,8 @@ void SelfAwareness::iam(void *tPtr,const Address &reporter,const int64_t receive
|
|||
// Reset all paths within this scope and address family
|
||||
_ResetWithinScope rset(tPtr, now, myPhysicalAddress.ss_family, (InetAddress::IpScope)scope);
|
||||
RR->topology->eachPeer<_ResetWithinScope&>(rset);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Otherwise just update DB to use to determine external surface info
|
||||
entry.mySurface = myPhysicalAddress;
|
||||
entry.ts = now;
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#ifndef ZT_SELFAWARENESS_HPP
|
||||
#define ZT_SELFAWARENESS_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -27,8 +27,7 @@ class RuntimeEnvironment;
|
|||
/**
|
||||
* Tracks changes to this peer's real world addresses
|
||||
*/
|
||||
class SelfAwareness
|
||||
{
|
||||
class SelfAwareness {
|
||||
public:
|
||||
SelfAwareness(const RuntimeEnvironment* renv);
|
||||
|
||||
|
@ -59,27 +58,39 @@ public:
|
|||
void clean(int64_t now);
|
||||
|
||||
private:
|
||||
struct PhySurfaceKey
|
||||
{
|
||||
struct PhySurfaceKey {
|
||||
Address reporter;
|
||||
int64_t receivedOnLocalSocket;
|
||||
InetAddress reporterPhysicalAddress;
|
||||
InetAddress::IpScope scope;
|
||||
|
||||
PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {}
|
||||
PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {}
|
||||
|
||||
inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
|
||||
inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
|
||||
};
|
||||
struct PhySurfaceEntry
|
||||
PhySurfaceKey() : reporter(), scope(InetAddress::IP_SCOPE_NONE)
|
||||
{
|
||||
}
|
||||
PhySurfaceKey(const Address& r, const int64_t rol, const InetAddress& ra, InetAddress::IpScope s) : reporter(r), receivedOnLocalSocket(rol), reporterPhysicalAddress(ra), scope(s)
|
||||
{
|
||||
}
|
||||
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return ((unsigned long)reporter.toInt() + (unsigned long)scope);
|
||||
}
|
||||
inline bool operator==(const PhySurfaceKey& k) const
|
||||
{
|
||||
return ((reporter == k.reporter) && (receivedOnLocalSocket == k.receivedOnLocalSocket) && (reporterPhysicalAddress == k.reporterPhysicalAddress) && (scope == k.scope));
|
||||
}
|
||||
};
|
||||
struct PhySurfaceEntry {
|
||||
InetAddress mySurface;
|
||||
uint64_t ts;
|
||||
bool trusted;
|
||||
|
||||
PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {}
|
||||
PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {}
|
||||
PhySurfaceEntry() : mySurface(), ts(0), trusted(false)
|
||||
{
|
||||
}
|
||||
PhySurfaceEntry(const InetAddress& a, const uint64_t t) : mySurface(a), ts(t), trusted(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
const RuntimeEnvironment* RR;
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#ifndef ZT_SHAREDPTR_HPP
|
||||
#define ZT_SHAREDPTR_HPP
|
||||
|
||||
#include "Mutex.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
#include "Mutex.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -26,13 +26,18 @@ namespace ZeroTier {
|
|||
* counted must list this as a 'friend' and must have a private instance of
|
||||
* AtomicCounter called __refCount.
|
||||
*/
|
||||
template<typename T>
|
||||
class SharedPtr
|
||||
{
|
||||
template <typename T> class SharedPtr {
|
||||
public:
|
||||
SharedPtr() : _ptr((T *)0) {}
|
||||
SharedPtr(T *obj) : _ptr(obj) { ++obj->__refCount; }
|
||||
SharedPtr(const SharedPtr &sp) : _ptr(sp._getAndInc()) {}
|
||||
SharedPtr() : _ptr((T*)0)
|
||||
{
|
||||
}
|
||||
SharedPtr(T* obj) : _ptr(obj)
|
||||
{
|
||||
++obj->__refCount;
|
||||
}
|
||||
SharedPtr(const SharedPtr& sp) : _ptr(sp._getAndInc())
|
||||
{
|
||||
}
|
||||
|
||||
~SharedPtr()
|
||||
{
|
||||
|
@ -84,14 +89,26 @@ public:
|
|||
with._ptr = tmp;
|
||||
}
|
||||
|
||||
inline operator bool() const { return (_ptr != (T *)0); }
|
||||
inline T &operator*() const { return *_ptr; }
|
||||
inline T *operator->() const { return _ptr; }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_ptr != (T*)0);
|
||||
}
|
||||
inline T& operator*() const
|
||||
{
|
||||
return *_ptr;
|
||||
}
|
||||
inline T* operator->() const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Raw pointer to held object
|
||||
*/
|
||||
inline T *ptr() const { return _ptr; }
|
||||
inline T* ptr() const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this pointer to NULL
|
||||
|
@ -117,12 +134,30 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const SharedPtr &sp) const { return (_ptr == sp._ptr); }
|
||||
inline bool operator!=(const SharedPtr &sp) const { return (_ptr != sp._ptr); }
|
||||
inline bool operator>(const SharedPtr &sp) const { return (_ptr > sp._ptr); }
|
||||
inline bool operator<(const SharedPtr &sp) const { return (_ptr < sp._ptr); }
|
||||
inline bool operator>=(const SharedPtr &sp) const { return (_ptr >= sp._ptr); }
|
||||
inline bool operator<=(const SharedPtr &sp) const { return (_ptr <= sp._ptr); }
|
||||
inline bool operator==(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr == sp._ptr);
|
||||
}
|
||||
inline bool operator!=(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr != sp._ptr);
|
||||
}
|
||||
inline bool operator>(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr > sp._ptr);
|
||||
}
|
||||
inline bool operator<(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr < sp._ptr);
|
||||
}
|
||||
inline bool operator>=(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr >= sp._ptr);
|
||||
}
|
||||
inline bool operator<=(const SharedPtr& sp) const
|
||||
{
|
||||
return (_ptr <= sp._ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
inline T* _getAndInc() const
|
||||
|
|
199
node/Switch.cpp
199
node/Switch.cpp
|
@ -11,35 +11,30 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Switch.hpp"
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "../version.h"
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Trace.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../version.h"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "Metrics.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <utility>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Switch::Switch(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_lastBeaconResponse(0),
|
||||
_lastCheckedQueues(0),
|
||||
_lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine
|
||||
Switch::Switch(const RuntimeEnvironment* renv) : RR(renv), _lastBeaconResponse(0), _lastCheckedQueues(0), _lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -109,7 +104,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Fragment looks like ours
|
||||
const uint64_t fragmentPacketId = fragment.packetId();
|
||||
const unsigned int fragmentNumber = fragment.fragmentNumber();
|
||||
|
@ -133,7 +129,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
rq->totalFragments = totalFragments; // total fragment count is known
|
||||
rq->haveFragments = 1 << fragmentNumber; // we have only this fragment
|
||||
rq->complete = false;
|
||||
} else if (!(rq->haveFragments & (1 << fragmentNumber))) {
|
||||
}
|
||||
else if (! (rq->haveFragments & (1 << fragmentNumber))) {
|
||||
// We have other fragments and maybe the head, so add this one and check
|
||||
|
||||
rq->frags[fragmentNumber - 1] = fragment;
|
||||
|
@ -148,7 +145,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
|
||||
if (rq->frag0.tryDecode(RR, tPtr, flowId)) {
|
||||
rq->timestamp = 0; // packet decoded, free entry
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +155,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
} else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { // min length check is important!
|
||||
}
|
||||
else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { // min length check is important!
|
||||
// Handle packet head -------------------------------------------------
|
||||
|
||||
const Address destination(reinterpret_cast<const uint8_t*>(data) + 8, ZT_ADDRESS_LENGTH);
|
||||
|
@ -184,7 +183,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
relayTo->introduce(tPtr, now, sourcePeer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
relayTo = RR->topology->getUpstreamPeer();
|
||||
if ((relayTo) && (relayTo->address() != source)) {
|
||||
if (relayTo->sendDirect(tPtr, packet.data(), packet.size(), now, true)) {
|
||||
|
@ -196,19 +196,14 @@ 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) {
|
||||
}
|
||||
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
|
||||
|
||||
const uint64_t packetId = (
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[0]) << 56) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[1]) << 48) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[2]) << 40) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[3]) << 32) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[4]) << 24) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[5]) << 16) |
|
||||
(((uint64_t)reinterpret_cast<const uint8_t *>(data)[6]) << 8) |
|
||||
((uint64_t)reinterpret_cast<const uint8_t *>(data)[7])
|
||||
);
|
||||
const uint64_t packetId =
|
||||
((((uint64_t)reinterpret_cast<const uint8_t*>(data)[0]) << 56) | (((uint64_t)reinterpret_cast<const uint8_t*>(data)[1]) << 48) | (((uint64_t)reinterpret_cast<const uint8_t*>(data)[2]) << 40)
|
||||
| (((uint64_t)reinterpret_cast<const uint8_t*>(data)[3]) << 32) | (((uint64_t)reinterpret_cast<const uint8_t*>(data)[4]) << 24) | (((uint64_t)reinterpret_cast<const uint8_t*>(data)[5]) << 16)
|
||||
| (((uint64_t)reinterpret_cast<const uint8_t*>(data)[6]) << 8) | ((uint64_t)reinterpret_cast<const uint8_t*>(data)[7]));
|
||||
|
||||
RXQueueEntry* const rq = _findRXQueueEntry(packetId);
|
||||
Mutex::Lock rql(rq->lock);
|
||||
|
@ -222,7 +217,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
rq->totalFragments = 0;
|
||||
rq->haveFragments = 1;
|
||||
rq->complete = false;
|
||||
} else if (!(rq->haveFragments & 1)) {
|
||||
}
|
||||
else if (! (rq->haveFragments & 1)) {
|
||||
// If we have other fragments but no head, see if we are complete with the head
|
||||
|
||||
if ((rq->totalFragments > 1) && (Utils::countBits(rq->haveFragments |= 1) == rq->totalFragments)) {
|
||||
|
@ -235,15 +231,18 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
|
||||
if (rq->frag0.tryDecode(RR, tPtr, flowId)) {
|
||||
rq->timestamp = 0; // packet decoded, free entry
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Still waiting on more fragments, but keep the head
|
||||
rq->frag0.init(data, len, path, now);
|
||||
}
|
||||
} // else this is a duplicate head, ignore
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Packet is unfragmented, so just process it
|
||||
IncomingPacket packet(data, len, path, now);
|
||||
if (! packet.tryDecode(RR, tPtr, flowId)) {
|
||||
|
@ -262,7 +261,9 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
|
|||
// --------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {} // sanity check, should be caught elsewhere
|
||||
}
|
||||
catch (...) {
|
||||
} // sanity check, should be caught elsewhere
|
||||
}
|
||||
|
||||
void Switch::onLocalEthernet(void* tPtr, const SharedPtr<Network>& network, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len)
|
||||
|
@ -354,7 +355,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
MulticastGroup multicastGroup(to, 0);
|
||||
|
||||
if (to.isBroadcast()) {
|
||||
if ( (etherType == ZT_ETHERTYPE_ARP) && (len >= 28) && ((((const uint8_t *)data)[2] == 0x08)&&(((const uint8_t *)data)[3] == 0x00)&&(((const uint8_t *)data)[4] == 6)&&(((const uint8_t *)data)[5] == 4)&&(((const uint8_t *)data)[7] == 0x01)) ) {
|
||||
if ((etherType == ZT_ETHERTYPE_ARP) && (len >= 28)
|
||||
&& ((((const uint8_t*)data)[2] == 0x08) && (((const uint8_t*)data)[3] == 0x00) && (((const uint8_t*)data)[4] == 6) && (((const uint8_t*)data)[5] == 4) && (((const uint8_t*)data)[7] == 0x01))) {
|
||||
/* IPv4 ARP is one of the few special cases that we impose upon what is
|
||||
* otherwise a straightforward Ethernet switch emulation. Vanilla ARP
|
||||
* is dumb old broadcast and simply doesn't scale. ZeroTier multicast
|
||||
|
@ -365,12 +367,14 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
* the 32-bit ADI field. In practice this uses our multicast pub/sub
|
||||
* system to implement a kind of extended/distributed ARP table. */
|
||||
multicastGroup = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(((const unsigned char*)data) + 24, 4, 0));
|
||||
} else if (!network->config().enableBroadcast()) {
|
||||
}
|
||||
else if (! network->config().enableBroadcast()) {
|
||||
// Don't transmit broadcasts if this network doesn't want them
|
||||
RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "broadcast disabled");
|
||||
return;
|
||||
}
|
||||
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(len >= (40 + 8 + 16))) {
|
||||
}
|
||||
else if ((etherType == ZT_ETHERTYPE_IPV6) && (len >= (40 + 8 + 16))) {
|
||||
// IPv6 NDP emulation for certain very special patterns of private IPv6 addresses -- if enabled
|
||||
if ((network->config().ndpEmulation()) && (reinterpret_cast<const uint8_t*>(data)[6] == 0x3a) && (reinterpret_cast<const uint8_t*>(data)[40] == 0x87)) { // ICMPv6 neighbor solicitation
|
||||
Address v6EmbeddedAddress;
|
||||
|
@ -401,7 +405,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
v6EmbeddedAddress.setTo(pkt6 + ptr, 5);
|
||||
break;
|
||||
}
|
||||
} else if (sipNetmaskBits == 40) { // ZT-6PLANE /40 ???
|
||||
}
|
||||
else if (sipNetmaskBits == 40) { // ZT-6PLANE /40 ???
|
||||
const uint32_t nwid32 = (uint32_t)((network->id() ^ (network->id() >> 32)) & 0xffffffff);
|
||||
if ((my6[0] == 0xfc) && (my6[1] == (uint8_t)((nwid32 >> 24) & 0xff)) && (my6[2] == (uint8_t)((nwid32 >> 16) & 0xff)) && (my6[3] == (uint8_t)((nwid32 >> 8) & 0xff)) && (my6[4] == (uint8_t)(nwid32 & 0xff))) {
|
||||
unsigned int ptr = 0;
|
||||
|
@ -491,9 +496,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
//
|
||||
|
||||
std::thread([=]() {
|
||||
|
||||
RR->node->putFrame(tPtr, network->id(), network->userPtr(), peerMac, from, ZT_ETHERTYPE_IPV6, 0, adv, 72);
|
||||
|
||||
}).detach();
|
||||
|
||||
return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query.
|
||||
|
@ -521,30 +524,19 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
return;
|
||||
}
|
||||
|
||||
RR->mc->send(
|
||||
tPtr,
|
||||
RR->node->now(),
|
||||
network,
|
||||
Address(),
|
||||
multicastGroup,
|
||||
(fromBridged) ? from : MAC(),
|
||||
etherType,
|
||||
data,
|
||||
len);
|
||||
} else if (to == network->mac()) {
|
||||
|
||||
RR->mc->send(tPtr, RR->node->now(), network, Address(), multicastGroup, (fromBridged) ? from : MAC(), etherType, data, len);
|
||||
}
|
||||
else if (to == network->mac()) {
|
||||
// Destination is this node, so just reinject it
|
||||
|
||||
//
|
||||
// same pattern as putFrame call above
|
||||
//
|
||||
std::thread([=]() {
|
||||
|
||||
RR->node->putFrame(tPtr, network->id(), network->userPtr(), from, to, etherType, vlanId, data, len);
|
||||
|
||||
}).detach();
|
||||
|
||||
} else if (to[0] == MAC::firstOctetForNetwork(network->id())) {
|
||||
}
|
||||
else if (to[0] == MAC::firstOctetForNetwork(network->id())) {
|
||||
// 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
|
||||
|
@ -566,7 +558,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
// if (!network->config().disableCompression())
|
||||
// outp.compress();
|
||||
aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Packet outp(toZT, RR->identity.address(), Packet::VERB_EXT_FRAME);
|
||||
outp.append(network->id());
|
||||
outp.append((unsigned char)0x00);
|
||||
|
@ -579,7 +572,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
// outp.compress();
|
||||
aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Destination is bridged behind a remote peer
|
||||
|
||||
// We filter with a NULL destination ZeroTier address first. Filtrations
|
||||
|
@ -599,7 +593,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
if ((bridges[0]) && (bridges[0] != RR->identity.address()) && (network->config().permitsBridging(bridges[0]))) {
|
||||
/* We have a known bridge route for this MAC, send it there. */
|
||||
++numBridges;
|
||||
} else if (!activeBridges.empty()) {
|
||||
}
|
||||
else if (! activeBridges.empty()) {
|
||||
/* If there is no known route, spam to up to ZT_MAX_BRIDGE_SPAM active
|
||||
* bridges. If someone responds, we'll learn the route. */
|
||||
std::vector<Address>::const_iterator ab(activeBridges.begin());
|
||||
|
@ -609,7 +604,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
bridges[numBridges++] = *ab;
|
||||
++ab;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Otherwise pick a random set of them
|
||||
while (numBridges < ZT_MAX_BRIDGE_SPAM) {
|
||||
if (ab == activeBridges.end()) {
|
||||
|
@ -618,7 +614,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
if (((unsigned long)RR->node->prng() % (unsigned long)activeBridges.size()) == 0) {
|
||||
bridges[numBridges++] = *ab;
|
||||
++ab;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++ab;
|
||||
}
|
||||
}
|
||||
|
@ -638,7 +635,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
|||
// if (!network->config().disableCompression())
|
||||
// outp.compress();
|
||||
aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "filter blocked (bridge replication)");
|
||||
}
|
||||
}
|
||||
|
@ -764,12 +762,14 @@ Switch::dqr Switch::dodequeue(ManagedQueue *q, uint64_t now)
|
|||
if (sojourn_time < ZT_AQM_TARGET || q->byteLength <= ZT_DEFAULT_MTU) {
|
||||
// went below - stay below for at least interval
|
||||
q->first_above_time = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (q->first_above_time == 0) {
|
||||
// just went above from below. if still above at
|
||||
// first_above_time, will say it's ok to drop.
|
||||
q->first_above_time = now + ZT_AQM_INTERVAL;
|
||||
} else if (now >= q->first_above_time) {
|
||||
}
|
||||
else if (now >= q->first_above_time) {
|
||||
r.ok_to_drop = true;
|
||||
}
|
||||
}
|
||||
|
@ -790,18 +790,19 @@ Switch::TXQueueEntry * Switch::CoDelDequeue(ManagedQueue *q, bool isNew, uint64_
|
|||
if (! r.ok_to_drop) {
|
||||
// leave dropping state
|
||||
q->dropping = false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++(q->count);
|
||||
// schedule the next drop.
|
||||
q->drop_next = control_law(q->drop_next, q->count);
|
||||
}
|
||||
}
|
||||
} else if (r.ok_to_drop) {
|
||||
}
|
||||
else if (r.ok_to_drop) {
|
||||
q->q.pop_front(); // drop
|
||||
r = dodequeue(q, now);
|
||||
q->dropping = true;
|
||||
q->count = (q->count > 2 && now - q->drop_next < 8*ZT_AQM_INTERVAL)?
|
||||
q->count - 2 : 1;
|
||||
q->count = (q->count > 2 && now - q->drop_next < 8 * ZT_AQM_INTERVAL) ? q->count - 2 : 1;
|
||||
q->drop_next = control_law(now, q->count);
|
||||
}
|
||||
return r.p;
|
||||
|
@ -833,14 +834,16 @@ void Switch::aqm_dequeue(void *tPtr)
|
|||
// DEBUG_INFO("moving q=%p from NEW to OLD list", queueAtFrontOfList);
|
||||
oldQueues->push_back(queueAtFrontOfList);
|
||||
currQueues->erase(currQueues->begin());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
entryToEmit = CoDelDequeue(queueAtFrontOfList, examiningNewQueues, now);
|
||||
if (! entryToEmit) {
|
||||
// Move to end of list of OLD queues
|
||||
// DEBUG_INFO("moving q=%p from NEW to OLD list", queueAtFrontOfList);
|
||||
oldQueues->push_back(queueAtFrontOfList);
|
||||
currQueues->erase(currQueues->begin());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int len = entryToEmit->packet.payloadLength();
|
||||
queueAtFrontOfList->byteLength -= len;
|
||||
queueAtFrontOfList->byteCredit -= len;
|
||||
|
@ -865,14 +868,16 @@ void Switch::aqm_dequeue(void *tPtr)
|
|||
queueAtFrontOfList->byteCredit += ZT_AQM_QUANTUM;
|
||||
oldQueues->push_back(queueAtFrontOfList);
|
||||
currQueues->erase(currQueues->begin());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
entryToEmit = CoDelDequeue(queueAtFrontOfList, examiningNewQueues, now);
|
||||
if (! entryToEmit) {
|
||||
// DEBUG_INFO("moving q=%p from OLD to INACTIVE list", queueAtFrontOfList);
|
||||
// Move to inactive list of queues
|
||||
inactiveQueues->push_back(queueAtFrontOfList);
|
||||
currQueues->erase(currQueues->begin());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int len = entryToEmit->packet.payloadLength();
|
||||
queueAtFrontOfList->byteLength -= len;
|
||||
queueAtFrontOfList->byteCredit -= len;
|
||||
|
@ -933,7 +938,8 @@ void Switch::requestWhois(void *tPtr,const int64_t now,const Address &addr)
|
|||
int64_t& last = _lastSentWhoisRequest[addr];
|
||||
if ((now - last) < ZT_WHOIS_RETRY_DELAY) {
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
@ -971,10 +977,12 @@ void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr<Peer> &peer)
|
|||
if (txi->dest == peer->address()) {
|
||||
if (_trySend(tPtr, txi->packet, txi->encrypt, txi->flowId)) {
|
||||
_txQueue.erase(txi++);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++txi;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++txi;
|
||||
}
|
||||
}
|
||||
|
@ -996,9 +1004,11 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
|
|||
for (std::list<TXQueueEntry>::iterator txi(_txQueue.begin()); txi != _txQueue.end();) {
|
||||
if (_trySend(tPtr, txi->packet, txi->encrypt, txi->flowId)) {
|
||||
_txQueue.erase(txi++);
|
||||
} else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) {
|
||||
}
|
||||
else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) {
|
||||
_txQueue.erase(txi++);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (! RR->topology->getPeer(tPtr, txi->dest)) {
|
||||
needWhois.push_back(txi->dest);
|
||||
}
|
||||
|
@ -1016,7 +1026,8 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
|
|||
if ((rq->timestamp) && (rq->complete)) {
|
||||
if ((rq->frag0.tryDecode(RR, tPtr, rq->flowId)) || ((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) {
|
||||
rq->timestamp = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const Address src(rq->frag0.source());
|
||||
if (! RR->topology->getPeer(tPtr, src)) {
|
||||
requestWhois(tPtr, now, src);
|
||||
|
@ -1071,8 +1082,7 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId)
|
|||
|
||||
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr, destination));
|
||||
if (peer) {
|
||||
if ((peer->bondingPolicy() == ZT_BOND_POLICY_BROADCAST)
|
||||
&& (packet.verb() == Packet::VERB_FRAME || packet.verb() == Packet::VERB_EXT_FRAME)) {
|
||||
if ((peer->bondingPolicy() == ZT_BOND_POLICY_BROADCAST) && (packet.verb() == Packet::VERB_FRAME || packet.verb() == Packet::VERB_EXT_FRAME)) {
|
||||
const SharedPtr<Peer> relay(RR->topology->getUpstreamPeer());
|
||||
Mutex::Lock _l(peer->_paths_m);
|
||||
for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
|
||||
|
@ -1082,7 +1092,8 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId)
|
|||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
viaPath = peer->getAppropriatePath(now, false, flowId);
|
||||
if (! viaPath) {
|
||||
peer->tryMemorizedPath(tPtr, now); // periodically attempt memorized or statically defined paths, if any are known
|
||||
|
@ -1117,7 +1128,8 @@ void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path
|
|||
|
||||
if (trustedPathId) {
|
||||
packet.setTrusted(trustedPathId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (! packet.isEncrypted()) {
|
||||
packet.armor(peer->key(), encrypt, false, peer->aesKeysIfSupported(), peer->identity());
|
||||
}
|
||||
|
@ -1148,7 +1160,8 @@ void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path
|
|||
}
|
||||
}
|
||||
|
||||
void Switch::_recordOutgoingPacketMetrics(const Packet &p) {
|
||||
void Switch::_recordOutgoingPacketMetrics(const Packet& p)
|
||||
{
|
||||
switch (p.verb()) {
|
||||
case Packet::VERB_NOP:
|
||||
Metrics::pkt_nop_out++;
|
||||
|
|
|
@ -14,22 +14,22 @@
|
|||
#ifndef ZT_N_SWITCH_HPP
|
||||
#define ZT_N_SWITCH_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "IncomingPacket.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "IncomingPacket.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
|
||||
/* Ethernet frame types that might be relevant to us */
|
||||
#define ZT_ETHERTYPE_IPV4 0x0800
|
||||
|
@ -54,8 +54,7 @@ class Peer;
|
|||
* packets from tap devices, and this sends them where they need to go and
|
||||
* wraps/unwraps accordingly. It also handles queues and timeouts and such.
|
||||
*/
|
||||
class Switch
|
||||
{
|
||||
class Switch {
|
||||
struct ManagedQueue;
|
||||
struct TXQueueEntry;
|
||||
|
||||
|
@ -219,9 +218,10 @@ private:
|
|||
Mutex _lastSentWhoisRequest_m;
|
||||
|
||||
// Packets waiting for WHOIS replies or other decode info or missing fragments
|
||||
struct RXQueueEntry
|
||||
struct RXQueueEntry {
|
||||
RXQueueEntry() : timestamp(0)
|
||||
{
|
||||
RXQueueEntry() : timestamp(0) {}
|
||||
}
|
||||
volatile int64_t timestamp; // 0 if entry is not in use
|
||||
volatile uint64_t packetId;
|
||||
IncomingPacket frag0; // head of packet
|
||||
|
@ -256,15 +256,13 @@ private:
|
|||
}
|
||||
|
||||
// ZeroTier-layer TX queue entry
|
||||
struct TXQueueEntry
|
||||
struct TXQueueEntry {
|
||||
TXQueueEntry()
|
||||
{
|
||||
TXQueueEntry() {}
|
||||
TXQueueEntry(Address d,uint64_t ct,const Packet &p,bool enc,int32_t fid) :
|
||||
dest(d),
|
||||
creationTime(ct),
|
||||
packet(p),
|
||||
encrypt(enc),
|
||||
flowId(fid) {}
|
||||
}
|
||||
TXQueueEntry(Address d, uint64_t ct, const Packet& p, bool enc, int32_t fid) : dest(d), creationTime(ct), packet(p), encrypt(enc), flowId(fid)
|
||||
{
|
||||
}
|
||||
|
||||
Address dest;
|
||||
uint64_t creationTime;
|
||||
|
@ -277,35 +275,39 @@ private:
|
|||
Mutex _aqm_m;
|
||||
|
||||
// Tracks sending of VERB_RENDEZVOUS to relaying peers
|
||||
struct _LastUniteKey
|
||||
struct _LastUniteKey {
|
||||
_LastUniteKey() : x(0), y(0)
|
||||
{
|
||||
_LastUniteKey() : x(0),y(0) {}
|
||||
}
|
||||
_LastUniteKey(const Address& a1, const Address& a2)
|
||||
{
|
||||
if (a1 > a2) {
|
||||
x = a2.toInt();
|
||||
y = a1.toInt();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
x = a1.toInt();
|
||||
y = a2.toInt();
|
||||
}
|
||||
}
|
||||
inline unsigned long hashCode() const { return ((unsigned long)x ^ (unsigned long)y); }
|
||||
inline bool operator==(const _LastUniteKey &k) const { return ((x == k.x)&&(y == k.y)); }
|
||||
inline unsigned long hashCode() const
|
||||
{
|
||||
return ((unsigned long)x ^ (unsigned long)y);
|
||||
}
|
||||
inline bool operator==(const _LastUniteKey& k) const
|
||||
{
|
||||
return ((x == k.x) && (y == k.y));
|
||||
}
|
||||
uint64_t x, y;
|
||||
};
|
||||
Hashtable<_LastUniteKey, uint64_t> _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior
|
||||
Mutex _lastUniteAttempt_m;
|
||||
|
||||
// Queue with additional flow state variables
|
||||
struct ManagedQueue
|
||||
struct ManagedQueue {
|
||||
ManagedQueue(int id) : id(id), byteCredit(ZT_AQM_QUANTUM), byteLength(0), dropping(false)
|
||||
{
|
||||
ManagedQueue(int id) :
|
||||
id(id),
|
||||
byteCredit(ZT_AQM_QUANTUM),
|
||||
byteLength(0),
|
||||
dropping(false)
|
||||
{}
|
||||
}
|
||||
int id;
|
||||
int byteCredit;
|
||||
int byteLength;
|
||||
|
@ -317,8 +319,7 @@ private:
|
|||
std::list<TXQueueEntry*> q;
|
||||
};
|
||||
// To implement fq_codel we need to maintain a queue of queues
|
||||
struct NetworkQoSControlBlock
|
||||
{
|
||||
struct NetworkQoSControlBlock {
|
||||
int _currEnqueuedPackets;
|
||||
std::vector<ManagedQueue*> newQueues;
|
||||
std::vector<ManagedQueue*> oldQueues;
|
||||
|
|
10
node/Tag.cpp
10
node/Tag.cpp
|
@ -12,12 +12,13 @@
|
|||
/****/
|
||||
|
||||
#include "Tag.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
||||
#include "Identity.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -35,7 +36,8 @@ int Tag::verify(const RuntimeEnvironment *RR,void *tPtr) const
|
|||
Buffer<(sizeof(Tag) * 2)> tmp;
|
||||
this->serialize(tmp, true);
|
||||
return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
136
node/Tag.hpp
136
node/Tag.hpp
|
@ -14,18 +14,18 @@
|
|||
#ifndef ZT_TAG_HPP
|
||||
#define ZT_TAG_HPP
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
@ -47,16 +47,14 @@ class RuntimeEnvironment;
|
|||
* Unlike capabilities tags are signed only by the issuer and are never
|
||||
* transferable.
|
||||
*/
|
||||
class Tag : public Credential
|
||||
{
|
||||
class Tag : public Credential {
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; }
|
||||
static inline Credential::Type credentialType()
|
||||
{
|
||||
return Credential::CREDENTIAL_TYPE_TAG;
|
||||
}
|
||||
|
||||
Tag() :
|
||||
_id(0),
|
||||
_value(0),
|
||||
_networkId(0),
|
||||
_ts(0)
|
||||
Tag() : _id(0), _value(0), _networkId(0), _ts(0)
|
||||
{
|
||||
memset(_signature.data, 0, sizeof(_signature.data));
|
||||
}
|
||||
|
@ -68,23 +66,35 @@ public:
|
|||
* @param id Tag ID
|
||||
* @param value Tag value
|
||||
*/
|
||||
Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) :
|
||||
_id(id),
|
||||
_value(value),
|
||||
_networkId(nwid),
|
||||
_ts(ts),
|
||||
_issuedTo(issuedTo),
|
||||
_signedBy()
|
||||
Tag(const uint64_t nwid, const int64_t ts, const Address& issuedTo, const uint32_t id, const uint32_t value) : _id(id), _value(value), _networkId(nwid), _ts(ts), _issuedTo(issuedTo), _signedBy()
|
||||
{
|
||||
memset(_signature.data, 0, sizeof(_signature.data));
|
||||
}
|
||||
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline const uint32_t &value() const { return _value; }
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline int64_t timestamp() const { return _ts; }
|
||||
inline const Address &issuedTo() const { return _issuedTo; }
|
||||
inline const Address &signedBy() const { return _signedBy; }
|
||||
inline uint32_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
inline const uint32_t& value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
inline uint64_t networkId() const
|
||||
{
|
||||
return _networkId;
|
||||
}
|
||||
inline int64_t timestamp() const
|
||||
{
|
||||
return _ts;
|
||||
}
|
||||
inline const Address& issuedTo() const
|
||||
{
|
||||
return _issuedTo;
|
||||
}
|
||||
inline const Address& signedBy() const
|
||||
{
|
||||
return _signedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign this tag
|
||||
|
@ -113,8 +123,7 @@ public:
|
|||
*/
|
||||
int verify(const RuntimeEnvironment* RR, void* tPtr) const;
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, const bool forSign = false) const
|
||||
{
|
||||
if (forSign) {
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
@ -140,8 +149,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
|
||||
|
@ -168,7 +176,8 @@ public:
|
|||
p += 2;
|
||||
memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN);
|
||||
p += ZT_ECC_SIGNATURE_LEN;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p += 2 + b.template at<uint16_t>(p);
|
||||
}
|
||||
|
||||
|
@ -181,23 +190,58 @@ public:
|
|||
}
|
||||
|
||||
// Provides natural sort order by ID
|
||||
inline bool operator<(const Tag &t) const { return (_id < t._id); }
|
||||
inline bool operator<(const Tag& t) const
|
||||
{
|
||||
return (_id < t._id);
|
||||
}
|
||||
|
||||
inline bool operator==(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) == 0); }
|
||||
inline bool operator!=(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) != 0); }
|
||||
inline bool operator==(const Tag& t) const
|
||||
{
|
||||
return (memcmp(this, &t, sizeof(Tag)) == 0);
|
||||
}
|
||||
inline bool operator!=(const Tag& t) const
|
||||
{
|
||||
return (memcmp(this, &t, sizeof(Tag)) != 0);
|
||||
}
|
||||
|
||||
// For searching sorted arrays or lists of Tags by ID
|
||||
struct IdComparePredicate
|
||||
struct IdComparePredicate {
|
||||
inline bool operator()(const Tag& a, const Tag& b) const
|
||||
{
|
||||
inline bool operator()(const Tag &a,const Tag &b) const { return (a.id() < b.id()); }
|
||||
inline bool operator()(const uint32_t a,const Tag &b) const { return (a < b.id()); }
|
||||
inline bool operator()(const Tag &a,const uint32_t b) const { return (a.id() < b); }
|
||||
inline bool operator()(const Tag *a,const Tag *b) const { return (a->id() < b->id()); }
|
||||
inline bool operator()(const Tag *a,const Tag &b) const { return (a->id() < b.id()); }
|
||||
inline bool operator()(const Tag &a,const Tag *b) const { return (a.id() < b->id()); }
|
||||
inline bool operator()(const uint32_t a,const Tag *b) const { return (a < b->id()); }
|
||||
inline bool operator()(const Tag *a,const uint32_t b) const { return (a->id() < b); }
|
||||
inline bool operator()(const uint32_t a,const uint32_t b) const { return (a < b); }
|
||||
return (a.id() < b.id());
|
||||
}
|
||||
inline bool operator()(const uint32_t a, const Tag& b) const
|
||||
{
|
||||
return (a < b.id());
|
||||
}
|
||||
inline bool operator()(const Tag& a, const uint32_t b) const
|
||||
{
|
||||
return (a.id() < b);
|
||||
}
|
||||
inline bool operator()(const Tag* a, const Tag* b) const
|
||||
{
|
||||
return (a->id() < b->id());
|
||||
}
|
||||
inline bool operator()(const Tag* a, const Tag& b) const
|
||||
{
|
||||
return (a->id() < b.id());
|
||||
}
|
||||
inline bool operator()(const Tag& a, const Tag* b) const
|
||||
{
|
||||
return (a.id() < b->id());
|
||||
}
|
||||
inline bool operator()(const uint32_t a, const Tag* b) const
|
||||
{
|
||||
return (a < b->id());
|
||||
}
|
||||
inline bool operator()(const Tag* a, const uint32_t b) const
|
||||
{
|
||||
return (a->id() < b);
|
||||
}
|
||||
inline bool operator()(const uint32_t a, const uint32_t b) const
|
||||
{
|
||||
return (a < b);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -11,24 +11,38 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
#define ZT_DEFAULT_WORLD_LENGTH 570
|
||||
static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x7e,0xe9,0x57,0x60,0xcd,0xb8,0xb3,0x88,0xa4,0x69,0x22,0x14,0x91,0xaa,0x9a,0xcd,0x66,0xcc,0x76,0x4c,0xde,0xfd,0x56,0x03,0x9f,0x10,0x67,0xae,0x15,0xe6,0x9c,0x6f,0xb4,0x2d,0x7b,0x55,0x33,0x0e,0x3f,0xda,0xac,0x52,0x9c,0x07,0x92,0xfd,0x73,0x40,0xa6,0xaa,0x21,0xab,0xa8,0xa4,0x89,0xfd,0xae,0xa4,0x4a,0x39,0xbf,0x2d,0x00,0x65,0x9a,0xc9,0xc8,0x18,0xeb,0x36,0x00,0x92,0x76,0x37,0xef,0x4d,0x14,0x04,0xa4,0x4d,0x54,0x46,0x84,0x85,0x13,0x79,0x75,0x1f,0xaa,0x79,0xb4,0xc4,0xea,0x85,0x04,0x01,0x75,0xea,0x06,0x58,0x60,0x48,0x24,0x02,0xe1,0xeb,0x34,0x20,0x52,0x00,0x0e,0x62,0x90,0x06,0x1a,0x9b,0xe0,0xcd,0x29,0x3c,0x8b,0x55,0xf1,0xc3,0xd2,0x52,0x48,0x08,0xaf,0xc5,0x49,0x22,0x08,0x0e,0x35,0x39,0xa7,0x5a,0xdd,0xc3,0xce,0xf0,0xf6,0xad,0x26,0x0d,0x58,0x82,0x93,0xbb,0x77,0x86,0xe7,0x1e,0xfa,0x4b,0x90,0x57,0xda,0xd9,0x86,0x7a,0xfe,0x12,0xdd,0x04,0xca,0xfe,0x9e,0xfe,0xb9,0x00,0xcc,0xde,0xf7,0x6b,0xc7,0xb9,0x7d,0xed,0x90,0x4e,0xab,0xc5,0xdf,0x09,0x88,0x6d,0x9c,0x15,0x14,0xa6,0x10,0x03,0x6c,0xb9,0x13,0x9c,0xc2,0x14,0x00,0x1a,0x29,0x58,0x97,0x8e,0xfc,0xec,0x15,0x71,0x2d,0xd3,0x94,0x8c,0x6e,0x6b,0x3a,0x8e,0x89,0x3d,0xf0,0x1f,0xf4,0x93,0xd1,0xf8,0xd9,0x80,0x6a,0x86,0x0c,0x54,0x20,0x57,0x1b,0xf0,0x00,0x02,0x04,0x68,0xc2,0x08,0x86,0x27,0x09,0x06,0x26,0x05,0x98,0x80,0x02,0x00,0x12,0x00,0x00,0x30,0x05,0x71,0x0e,0x34,0x00,0x51,0x27,0x09,0x77,0x8c,0xde,0x71,0x90,0x00,0x3f,0x66,0x81,0xa9,0x9e,0x5a,0xd1,0x89,0x5e,0x9f,0xba,0x33,0xe6,0x21,0x2d,0x44,0x54,0xe1,0x68,0xbc,0xec,0x71,0x12,0x10,0x1b,0xf0,0x00,0x95,0x6e,0xd8,0xe9,0x2e,0x42,0x89,0x2c,0xb6,0xf2,0xec,0x41,0x08,0x81,0xa8,0x4a,0xb1,0x9d,0xa5,0x0e,0x12,0x87,0xba,0x3d,0x92,0x6c,0x3a,0x1f,0x75,0x5c,0xcc,0xf2,0x99,0xa1,0x20,0x70,0x55,0x00,0x02,0x04,0x67,0xc3,0x67,0x42,0x27,0x09,0x06,0x26,0x05,0x98,0x80,0x04,0x00,0x00,0xc3,0x02,0x54,0xf2,0xbc,0xa1,0xf7,0x00,0x19,0x27,0x09,0x62,0xf8,0x65,0xae,0x71,0x00,0xe2,0x07,0x6c,0x57,0xde,0x87,0x0e,0x62,0x88,0xd7,0xd5,0xe7,0x40,0x44,0x08,0xb1,0x54,0x5e,0xfc,0xa3,0x7d,0x67,0xf7,0x7b,0x87,0xe9,0xe5,0x41,0x68,0xc2,0x5d,0x3e,0xf1,0xa9,0xab,0xf2,0x90,0x5e,0xa5,0xe7,0x85,0xc0,0x1d,0xff,0x23,0x88,0x7a,0xd4,0x23,0x2d,0x95,0xc7,0xa8,0xfd,0x2c,0x27,0x11,0x1a,0x72,0xbd,0x15,0x93,0x22,0xdc,0x00,0x02,0x04,0x32,0x07,0xfc,0x8a,0x27,0x09,0x06,0x20,0x01,0x49,0xf0,0xd0,0xdb,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0xca,0xfe,0x04,0xeb,0xa9,0x00,0x6c,0x6a,0x9d,0x1d,0xea,0x55,0xc1,0x61,0x6b,0xfe,0x2a,0x2b,0x8f,0x0f,0xf9,0xa8,0xca,0xca,0xf7,0x03,0x74,0xfb,0x1f,0x39,0xe3,0xbe,0xf8,0x1c,0xbf,0xeb,0xef,0x17,0xb7,0x22,0x82,0x68,0xa0,0xa2,0xa2,0x9d,0x34,0x88,0xc7,0x52,0x56,0x5c,0x6c,0x96,0x5c,0xbd,0x65,0x06,0xec,0x24,0x39,0x7c,0xc8,0xa5,0xd9,0xd1,0x52,0x85,0xa8,0x7f,0x00,0x02,0x04,0x54,0x11,0x35,0x9b,0x27,0x09,0x06,0x2a,0x02,0x6e,0xa0,0xd4,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x93,0x27,0x09};
|
||||
static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xea, 0xc9, 0x0a, 0x00, 0x00, 0x01, 0x7e, 0xe9, 0x57, 0x60, 0xcd, 0xb8, 0xb3, 0x88, 0xa4, 0x69, 0x22, 0x14, 0x91, 0xaa, 0x9a, 0xcd, 0x66, 0xcc, 0x76, 0x4c, 0xde, 0xfd, 0x56, 0x03, 0x9f, 0x10,
|
||||
0x67, 0xae, 0x15, 0xe6, 0x9c, 0x6f, 0xb4, 0x2d, 0x7b, 0x55, 0x33, 0x0e, 0x3f, 0xda, 0xac, 0x52, 0x9c, 0x07, 0x92, 0xfd, 0x73, 0x40, 0xa6, 0xaa, 0x21, 0xab, 0xa8, 0xa4, 0x89, 0xfd, 0xae, 0xa4, 0x4a, 0x39, 0xbf, 0x2d, 0x00, 0x65,
|
||||
0x9a, 0xc9, 0xc8, 0x18, 0xeb, 0x36, 0x00, 0x92, 0x76, 0x37, 0xef, 0x4d, 0x14, 0x04, 0xa4, 0x4d, 0x54, 0x46, 0x84, 0x85, 0x13, 0x79, 0x75, 0x1f, 0xaa, 0x79, 0xb4, 0xc4, 0xea, 0x85, 0x04, 0x01, 0x75, 0xea, 0x06, 0x58, 0x60, 0x48,
|
||||
0x24, 0x02, 0xe1, 0xeb, 0x34, 0x20, 0x52, 0x00, 0x0e, 0x62, 0x90, 0x06, 0x1a, 0x9b, 0xe0, 0xcd, 0x29, 0x3c, 0x8b, 0x55, 0xf1, 0xc3, 0xd2, 0x52, 0x48, 0x08, 0xaf, 0xc5, 0x49, 0x22, 0x08, 0x0e, 0x35, 0x39, 0xa7, 0x5a, 0xdd, 0xc3,
|
||||
0xce, 0xf0, 0xf6, 0xad, 0x26, 0x0d, 0x58, 0x82, 0x93, 0xbb, 0x77, 0x86, 0xe7, 0x1e, 0xfa, 0x4b, 0x90, 0x57, 0xda, 0xd9, 0x86, 0x7a, 0xfe, 0x12, 0xdd, 0x04, 0xca, 0xfe, 0x9e, 0xfe, 0xb9, 0x00, 0xcc, 0xde, 0xf7, 0x6b, 0xc7, 0xb9,
|
||||
0x7d, 0xed, 0x90, 0x4e, 0xab, 0xc5, 0xdf, 0x09, 0x88, 0x6d, 0x9c, 0x15, 0x14, 0xa6, 0x10, 0x03, 0x6c, 0xb9, 0x13, 0x9c, 0xc2, 0x14, 0x00, 0x1a, 0x29, 0x58, 0x97, 0x8e, 0xfc, 0xec, 0x15, 0x71, 0x2d, 0xd3, 0x94, 0x8c, 0x6e, 0x6b,
|
||||
0x3a, 0x8e, 0x89, 0x3d, 0xf0, 0x1f, 0xf4, 0x93, 0xd1, 0xf8, 0xd9, 0x80, 0x6a, 0x86, 0x0c, 0x54, 0x20, 0x57, 0x1b, 0xf0, 0x00, 0x02, 0x04, 0x68, 0xc2, 0x08, 0x86, 0x27, 0x09, 0x06, 0x26, 0x05, 0x98, 0x80, 0x02, 0x00, 0x12, 0x00,
|
||||
0x00, 0x30, 0x05, 0x71, 0x0e, 0x34, 0x00, 0x51, 0x27, 0x09, 0x77, 0x8c, 0xde, 0x71, 0x90, 0x00, 0x3f, 0x66, 0x81, 0xa9, 0x9e, 0x5a, 0xd1, 0x89, 0x5e, 0x9f, 0xba, 0x33, 0xe6, 0x21, 0x2d, 0x44, 0x54, 0xe1, 0x68, 0xbc, 0xec, 0x71,
|
||||
0x12, 0x10, 0x1b, 0xf0, 0x00, 0x95, 0x6e, 0xd8, 0xe9, 0x2e, 0x42, 0x89, 0x2c, 0xb6, 0xf2, 0xec, 0x41, 0x08, 0x81, 0xa8, 0x4a, 0xb1, 0x9d, 0xa5, 0x0e, 0x12, 0x87, 0xba, 0x3d, 0x92, 0x6c, 0x3a, 0x1f, 0x75, 0x5c, 0xcc, 0xf2, 0x99,
|
||||
0xa1, 0x20, 0x70, 0x55, 0x00, 0x02, 0x04, 0x67, 0xc3, 0x67, 0x42, 0x27, 0x09, 0x06, 0x26, 0x05, 0x98, 0x80, 0x04, 0x00, 0x00, 0xc3, 0x02, 0x54, 0xf2, 0xbc, 0xa1, 0xf7, 0x00, 0x19, 0x27, 0x09, 0x62, 0xf8, 0x65, 0xae, 0x71, 0x00,
|
||||
0xe2, 0x07, 0x6c, 0x57, 0xde, 0x87, 0x0e, 0x62, 0x88, 0xd7, 0xd5, 0xe7, 0x40, 0x44, 0x08, 0xb1, 0x54, 0x5e, 0xfc, 0xa3, 0x7d, 0x67, 0xf7, 0x7b, 0x87, 0xe9, 0xe5, 0x41, 0x68, 0xc2, 0x5d, 0x3e, 0xf1, 0xa9, 0xab, 0xf2, 0x90, 0x5e,
|
||||
0xa5, 0xe7, 0x85, 0xc0, 0x1d, 0xff, 0x23, 0x88, 0x7a, 0xd4, 0x23, 0x2d, 0x95, 0xc7, 0xa8, 0xfd, 0x2c, 0x27, 0x11, 0x1a, 0x72, 0xbd, 0x15, 0x93, 0x22, 0xdc, 0x00, 0x02, 0x04, 0x32, 0x07, 0xfc, 0x8a, 0x27, 0x09, 0x06, 0x20, 0x01,
|
||||
0x49, 0xf0, 0xd0, 0xdb, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x27, 0x09, 0xca, 0xfe, 0x04, 0xeb, 0xa9, 0x00, 0x6c, 0x6a, 0x9d, 0x1d, 0xea, 0x55, 0xc1, 0x61, 0x6b, 0xfe, 0x2a, 0x2b, 0x8f, 0x0f, 0xf9, 0xa8,
|
||||
0xca, 0xca, 0xf7, 0x03, 0x74, 0xfb, 0x1f, 0x39, 0xe3, 0xbe, 0xf8, 0x1c, 0xbf, 0xeb, 0xef, 0x17, 0xb7, 0x22, 0x82, 0x68, 0xa0, 0xa2, 0xa2, 0x9d, 0x34, 0x88, 0xc7, 0x52, 0x56, 0x5c, 0x6c, 0x96, 0x5c, 0xbd, 0x65, 0x06, 0xec, 0x24,
|
||||
0x39, 0x7c, 0xc8, 0xa5, 0xd9, 0xd1, 0x52, 0x85, 0xa8, 0x7f, 0x00, 0x02, 0x04, 0x54, 0x11, 0x35, 0x9b, 0x27, 0x09, 0x06, 0x2a, 0x02, 0x6e, 0xa0, 0xd4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x93, 0x27, 0x09
|
||||
};
|
||||
|
||||
Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
|
||||
RR(renv),
|
||||
_numConfiguredPhysicalPaths(0),
|
||||
_amUpstream(false)
|
||||
Topology::Topology(const RuntimeEnvironment* renv, void* tPtr) : RR(renv), _numConfiguredPhysicalPaths(0), _amUpstream(false)
|
||||
{
|
||||
uint8_t tmp[ZT_WORLD_MAX_SERIALIZED_LENGTH];
|
||||
uint64_t idtmp[2];
|
||||
|
@ -40,7 +54,9 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
|
|||
World cachedPlanet;
|
||||
cachedPlanet.deserialize(Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH>(tmp, (unsigned int)n), 0);
|
||||
addWorld(tPtr, cachedPlanet, false);
|
||||
} catch ( ... ) {} // ignore invalid cached planets
|
||||
}
|
||||
catch (...) {
|
||||
} // ignore invalid cached planets
|
||||
}
|
||||
|
||||
World defaultPlanet;
|
||||
|
@ -108,7 +124,9 @@ SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
|
|||
}
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
} catch ( ... ) {} // ignore invalid identities or other strange failures
|
||||
}
|
||||
catch (...) {
|
||||
} // ignore invalid identities or other strange failures
|
||||
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
|
@ -117,7 +135,8 @@ Identity Topology::getIdentity(void *tPtr,const Address &zta)
|
|||
{
|
||||
if (zta == RR->identity.address()) {
|
||||
return RR->identity;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Mutex::Lock _l(_peers_m);
|
||||
const SharedPtr<Peer>* const ap = _peers.get(zta);
|
||||
if (ap) {
|
||||
|
@ -255,14 +274,17 @@ bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew)
|
|||
if (existing) {
|
||||
if (existing->shouldBeReplacedBy(newWorld)) {
|
||||
*existing = newWorld;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
} else if (newWorld.type() == World::TYPE_MOON) {
|
||||
}
|
||||
else if (newWorld.type() == World::TYPE_MOON) {
|
||||
if (alwaysAcceptNew) {
|
||||
_moons.push_back(newWorld);
|
||||
existing = &(_moons.back());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (std::vector<std::pair<uint64_t, Address> >::iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) {
|
||||
if (m->first == newWorld.id()) {
|
||||
for (std::vector<World::Root>::const_iterator r(newWorld.roots().begin()); r != newWorld.roots().end(); ++r) {
|
||||
|
@ -282,7 +304,8 @@ bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew)
|
|||
if (! existing) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -293,7 +316,9 @@ bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew)
|
|||
idtmp[0] = existing->id();
|
||||
idtmp[1] = 0;
|
||||
RR->node->stateObjectPut(tPtr, (existing->type() == World::TYPE_PLANET) ? ZT_STATE_OBJECT_PLANET : ZT_STATE_OBJECT_MOON, idtmp, sbuf.data(), sbuf.size());
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
_memoizeUpstreams(tPtr);
|
||||
|
||||
|
@ -315,7 +340,9 @@ void Topology::addMoon(void *tPtr,const uint64_t id,const Address &seed)
|
|||
addWorld(tPtr, w, true);
|
||||
return;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
if (seed) {
|
||||
|
@ -335,7 +362,8 @@ void Topology::removeMoon(void *tPtr,const uint64_t id)
|
|||
for (std::vector<World>::const_iterator m(_moons.begin()); m != _moons.end(); ++m) {
|
||||
if (m->id() != id) {
|
||||
nm.push_back(*m);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
uint64_t idtmp[2];
|
||||
idtmp[0] = id;
|
||||
idtmp[1] = 0;
|
||||
|
@ -394,7 +422,8 @@ void Topology::_memoizeUpstreams(void *tPtr)
|
|||
const Identity& id = i->identity;
|
||||
if (id == RR->identity) {
|
||||
_amUpstream = true;
|
||||
} else if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) == _upstreamAddresses.end()) {
|
||||
}
|
||||
else if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), id.address()) == _upstreamAddresses.end()) {
|
||||
_upstreamAddresses.push_back(id.address());
|
||||
SharedPtr<Peer>& hp = _peers[id.address()];
|
||||
if (! hp) {
|
||||
|
@ -407,7 +436,8 @@ void Topology::_memoizeUpstreams(void *tPtr)
|
|||
for (std::vector<World::Root>::const_iterator i(m->roots().begin()); i != m->roots().end(); ++i) {
|
||||
if (i->identity == RR->identity) {
|
||||
_amUpstream = true;
|
||||
} else if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),i->identity.address()) == _upstreamAddresses.end()) {
|
||||
}
|
||||
else if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), i->identity.address()) == _upstreamAddresses.end()) {
|
||||
_upstreamAddresses.push_back(i->identity.address());
|
||||
SharedPtr<Peer>& hp = _peers[i->identity.address()];
|
||||
if (! hp) {
|
||||
|
@ -429,7 +459,9 @@ void Topology::_savePeer(void *tPtr,const SharedPtr<Peer> &peer)
|
|||
tmpid[0] = peer->address().toInt();
|
||||
tmpid[1] = 0;
|
||||
RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_PEER, tmpid, buf.data(), buf.size());
|
||||
} catch ( ... ) {} // sanity check, discard invalid entries
|
||||
}
|
||||
catch (...) {
|
||||
} // sanity check, discard invalid entries
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -14,25 +14,23 @@
|
|||
#ifndef ZT_TOPOLOGY_HPP
|
||||
#define ZT_TOPOLOGY_HPP
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Address.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "World.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -41,8 +39,7 @@ class RuntimeEnvironment;
|
|||
/**
|
||||
* Database of network topology
|
||||
*/
|
||||
class Topology
|
||||
{
|
||||
class Topology {
|
||||
public:
|
||||
Topology(const RuntimeEnvironment* renv, void* tPtr);
|
||||
~Topology();
|
||||
|
@ -306,8 +303,7 @@ public:
|
|||
* @param f Function to apply
|
||||
* @tparam F Function or function object type
|
||||
*/
|
||||
template<typename F>
|
||||
inline void eachPeer(F f)
|
||||
template <typename F> inline void eachPeer(F f)
|
||||
{
|
||||
Mutex::Lock _l(_peers_m);
|
||||
Hashtable<Address, SharedPtr<Peer> >::Iterator i(_peers);
|
||||
|
@ -330,7 +326,10 @@ public:
|
|||
/**
|
||||
* @return True if I am a root server in a planet or moon
|
||||
*/
|
||||
inline bool amUpstream() const { return _amUpstream; }
|
||||
inline bool amUpstream() const
|
||||
{
|
||||
return _amUpstream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info about a path
|
||||
|
@ -407,7 +406,8 @@ public:
|
|||
{
|
||||
if (! pathNetwork) {
|
||||
_numConfiguredPhysicalPaths = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
std::map<InetAddress, ZT_PhysicalPathConfiguration> cpaths;
|
||||
for (unsigned int i = 0, j = _numConfiguredPhysicalPaths; i < j; ++i) {
|
||||
cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second;
|
||||
|
@ -418,14 +418,17 @@ public:
|
|||
|
||||
if (pc.mtu <= 0) {
|
||||
pc.mtu = ZT_DEFAULT_PHYSMTU;
|
||||
} else if (pc.mtu < ZT_MIN_PHYSMTU) {
|
||||
}
|
||||
else if (pc.mtu < ZT_MIN_PHYSMTU) {
|
||||
pc.mtu = ZT_MIN_PHYSMTU;
|
||||
} else if (pc.mtu > ZT_MAX_PHYSMTU) {
|
||||
}
|
||||
else if (pc.mtu > ZT_MAX_PHYSMTU) {
|
||||
pc.mtu = ZT_MAX_PHYSMTU;
|
||||
}
|
||||
|
||||
cpaths[*(reinterpret_cast<const InetAddress*>(pathNetwork))] = pc;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cpaths.erase(*(reinterpret_cast<const InetAddress*>(pathNetwork)));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,21 +13,22 @@
|
|||
|
||||
// #define ZT_TRACE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Trace.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
|
||||
#include "../include/ZeroTierDebug.h"
|
||||
#include "Capability.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "CertificateOfOwnership.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Revocation.hpp"
|
||||
#include "../include/ZeroTierDebug.h"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -189,7 +190,10 @@ void Trace::outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
|
|||
ZT_LOCAL_TRACE(tPtr, RR, "%.16llx DROP frame %s -> %s etherType %.4x size %u (%s)", network->id(), sourceMac.toString(tmp), destMac.toString(tmp2), etherType, frameLen, (reason) ? reason : "unknown reason");
|
||||
|
||||
std::pair<Address, Trace::Level> byn;
|
||||
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
|
||||
{
|
||||
Mutex::Lock l(_byNet_m);
|
||||
_byNet.get(network->id(), byn);
|
||||
}
|
||||
|
||||
if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) {
|
||||
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
|
||||
|
@ -213,17 +217,37 @@ void Trace::outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
|
|||
}
|
||||
}
|
||||
|
||||
void Trace::incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,bool credentialsRequested)
|
||||
void Trace::incomingNetworkAccessDenied(
|
||||
void* const tPtr,
|
||||
const SharedPtr<Network>& network,
|
||||
const SharedPtr<Path>& path,
|
||||
const uint64_t packetId,
|
||||
const unsigned int packetLength,
|
||||
const Address& source,
|
||||
const Packet::Verb verb,
|
||||
bool credentialsRequested)
|
||||
{
|
||||
char tmp[128];
|
||||
if (! network) {
|
||||
return; // sanity check
|
||||
}
|
||||
|
||||
ZT_LOCAL_TRACE(tPtr,RR,"%.16llx DENIED packet from %.10llx(%s) verb %d size %u%s",network->id(),source.toInt(),(path) ? (path->address().toString(tmp)) : "???",(int)verb,packetLength,credentialsRequested ? " (credentials requested)" : " (credentials not requested)");
|
||||
ZT_LOCAL_TRACE(
|
||||
tPtr,
|
||||
RR,
|
||||
"%.16llx DENIED packet from %.10llx(%s) verb %d size %u%s",
|
||||
network->id(),
|
||||
source.toInt(),
|
||||
(path) ? (path->address().toString(tmp)) : "???",
|
||||
(int)verb,
|
||||
packetLength,
|
||||
credentialsRequested ? " (credentials requested)" : " (credentials not requested)");
|
||||
|
||||
std::pair<Address, Trace::Level> byn;
|
||||
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
|
||||
{
|
||||
Mutex::Lock l(_byNet_m);
|
||||
_byNet.get(network->id(), byn);
|
||||
}
|
||||
|
||||
if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) {
|
||||
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
|
||||
|
@ -246,7 +270,17 @@ void Trace::incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network
|
|||
}
|
||||
}
|
||||
|
||||
void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,const MAC &sourceMac,const MAC &destMac,const char *reason)
|
||||
void Trace::incomingNetworkFrameDropped(
|
||||
void* const tPtr,
|
||||
const SharedPtr<Network>& network,
|
||||
const SharedPtr<Path>& path,
|
||||
const uint64_t packetId,
|
||||
const unsigned int packetLength,
|
||||
const Address& source,
|
||||
const Packet::Verb verb,
|
||||
const MAC& sourceMac,
|
||||
const MAC& destMac,
|
||||
const char* reason)
|
||||
{
|
||||
char tmp[128];
|
||||
if (! network) {
|
||||
|
@ -256,7 +290,10 @@ void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
|
|||
ZT_LOCAL_TRACE(tPtr, RR, "%.16llx DROPPED frame from %.10llx(%s) verb %d size %u", network->id(), source.toInt(), (path) ? (path->address().toString(tmp)) : "???", (int)verb, packetLength);
|
||||
|
||||
std::pair<Address, Trace::Level> byn;
|
||||
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
|
||||
{
|
||||
Mutex::Lock l(_byNet_m);
|
||||
_byNet.get(network->id(), byn);
|
||||
}
|
||||
|
||||
if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) {
|
||||
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
|
||||
|
@ -387,7 +424,10 @@ void Trace::networkFilter(
|
|||
const int accept)
|
||||
{
|
||||
std::pair<Address, Trace::Level> byn;
|
||||
{ Mutex::Lock l(_byNet_m); _byNet.get(network.id(),byn); }
|
||||
{
|
||||
Mutex::Lock l(_byNet_m);
|
||||
_byNet.get(network.id(), byn);
|
||||
}
|
||||
|
||||
if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_RULES)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_RULES))) {
|
||||
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
|
||||
|
|
|
@ -14,21 +14,20 @@
|
|||
#ifndef ZT_TRACE_HPP
|
||||
#define ZT_TRACE_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -49,20 +48,12 @@ class Capability;
|
|||
/**
|
||||
* Remote tracing and trace logging handler
|
||||
*/
|
||||
class Trace
|
||||
{
|
||||
class Trace {
|
||||
public:
|
||||
/**
|
||||
* Trace verbosity level
|
||||
*/
|
||||
enum Level
|
||||
{
|
||||
LEVEL_NORMAL = 0,
|
||||
LEVEL_VERBOSE = 10,
|
||||
LEVEL_RULES = 15,
|
||||
LEVEL_DEBUG = 20,
|
||||
LEVEL_INSANE = 30
|
||||
};
|
||||
enum Level { LEVEL_NORMAL = 0, LEVEL_VERBOSE = 10, LEVEL_RULES = 15, LEVEL_DEBUG = 20, LEVEL_INSANE = 30 };
|
||||
|
||||
/**
|
||||
* Filter rule evaluation result log
|
||||
|
@ -73,10 +64,11 @@ public:
|
|||
* As with four-bit rules an 00 value here means this was not
|
||||
* evaluated or was not relevant.
|
||||
*/
|
||||
class RuleResultLog
|
||||
{
|
||||
class RuleResultLog {
|
||||
public:
|
||||
RuleResultLog() {}
|
||||
RuleResultLog()
|
||||
{
|
||||
}
|
||||
|
||||
inline void log(const unsigned int rn, const uint8_t thisRuleMatches, const uint8_t thisSetMatches)
|
||||
{
|
||||
|
@ -92,16 +84,20 @@ public:
|
|||
memset(_l, 0, sizeof(_l));
|
||||
}
|
||||
|
||||
inline const uint8_t *data() const { return _l; }
|
||||
inline unsigned int sizeBytes() const { return (ZT_MAX_NETWORK_RULES / 2); }
|
||||
inline const uint8_t* data() const
|
||||
{
|
||||
return _l;
|
||||
}
|
||||
inline unsigned int sizeBytes() const
|
||||
{
|
||||
return (ZT_MAX_NETWORK_RULES / 2);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _l[ZT_MAX_NETWORK_RULES / 2];
|
||||
};
|
||||
|
||||
Trace(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_byNet(8)
|
||||
Trace(const RuntimeEnvironment* renv) : RR(renv), _byNet(8)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -119,8 +115,26 @@ public:
|
|||
void incomingPacketDroppedHELLO(void* const tPtr, const SharedPtr<Path>& path, const uint64_t packetId, const Address& source, const char* reason);
|
||||
|
||||
void outgoingNetworkFrameDropped(void* const tPtr, const SharedPtr<Network>& network, const MAC& sourceMac, const MAC& destMac, const unsigned int etherType, const unsigned int vlanId, const unsigned int frameLen, const char* reason);
|
||||
void incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,bool credentialsRequested);
|
||||
void incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,const MAC &sourceMac,const MAC &destMac,const char *reason);
|
||||
void incomingNetworkAccessDenied(
|
||||
void* const tPtr,
|
||||
const SharedPtr<Network>& network,
|
||||
const SharedPtr<Path>& path,
|
||||
const uint64_t packetId,
|
||||
const unsigned int packetLength,
|
||||
const Address& source,
|
||||
const Packet::Verb verb,
|
||||
bool credentialsRequested);
|
||||
void incomingNetworkFrameDropped(
|
||||
void* const tPtr,
|
||||
const SharedPtr<Network>& network,
|
||||
const SharedPtr<Path>& path,
|
||||
const uint64_t packetId,
|
||||
const unsigned int packetLength,
|
||||
const Address& source,
|
||||
const Packet::Verb verb,
|
||||
const MAC& sourceMac,
|
||||
const MAC& destMac,
|
||||
const char* reason);
|
||||
|
||||
void networkConfigRequestSent(void* const tPtr, const Network& network, const Address& controller);
|
||||
void networkFilter(
|
||||
|
|
|
@ -11,23 +11,23 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __UNIX_LIKE__
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#ifdef ZT_ARCH_ARM_HAS_NEON
|
||||
#ifdef __LINUX__
|
||||
#include <sys/auxv.h>
|
||||
|
@ -36,13 +36,13 @@
|
|||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <wincrypt.h>
|
||||
#include <intrin.h>
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
#include "Utils.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
|
@ -55,8 +55,8 @@
|
|||
#ifdef ZT_ARCH_ARM_HAS_NEON
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -116,7 +116,8 @@ Utils::ARMCapabilities::ARMCapabilities() noexcept
|
|||
this->pmull = (hwcaps2 & HWCAP2_PMULL) != 0;
|
||||
this->sha1 = (hwcaps2 & HWCAP2_SHA1) != 0;
|
||||
this->sha2 = (hwcaps2 & HWCAP2_SHA2) != 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
const long hwcaps = getauxval(AT_HWCAP);
|
||||
this->aes = (hwcaps & HWCAP_AES) != 0;
|
||||
|
@ -148,11 +149,7 @@ Utils::CPUIDRegisters::CPUIDRegisters() noexcept
|
|||
ecx = (uint32_t)regs[2];
|
||||
edx = (uint32_t)regs[3];
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
|
||||
: "a"(1), "c"(0)
|
||||
);
|
||||
__asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1), "c"(0));
|
||||
#endif
|
||||
|
||||
rdrand = ((ecx & (1U << 30U)) != 0);
|
||||
|
@ -166,11 +163,7 @@ Utils::CPUIDRegisters::CPUIDRegisters() noexcept
|
|||
ecx = (uint32_t)regs[2];
|
||||
edx = (uint32_t)regs[3];
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
|
||||
: "a"(7), "c"(0)
|
||||
);
|
||||
__asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(7), "c"(0));
|
||||
#endif
|
||||
|
||||
vaes = aes && avx && ((ecx & (1U << 9U)) != 0);
|
||||
|
@ -193,7 +186,10 @@ static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
|
|||
}
|
||||
}
|
||||
static void (*volatile _Utils_doBurn_ptr)(volatile uint8_t*, unsigned int) = _Utils_doBurn;
|
||||
void Utils::burn(void *ptr,unsigned int len) { (_Utils_doBurn_ptr)((volatile uint8_t *)ptr,len); }
|
||||
void Utils::burn(void* ptr, unsigned int len)
|
||||
{
|
||||
(_Utils_doBurn_ptr)((volatile uint8_t*)ptr, len);
|
||||
}
|
||||
|
||||
static unsigned long _Utils_itoa(unsigned long n, char* s)
|
||||
{
|
||||
|
@ -292,7 +288,8 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
|||
exit(1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
247
node/Utils.hpp
247
node/Utils.hpp
|
@ -14,17 +14,16 @@
|
|||
#ifndef ZT_UTILS_HPP
|
||||
#define ZT_UTILS_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/endian.h>
|
||||
|
@ -34,15 +33,9 @@
|
|||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U)))
|
||||
#define ZT_CONST_TO_BE_UINT64(x) ( \
|
||||
(((uint64_t)(x) & 0x00000000000000ffULL) << 56U) | \
|
||||
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40U) | \
|
||||
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24U) | \
|
||||
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8U) | \
|
||||
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8U) | \
|
||||
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24U) | \
|
||||
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40U) | \
|
||||
(((uint64_t)(x) & 0xff00000000000000ULL) >> 56U))
|
||||
#define ZT_CONST_TO_BE_UINT64(x) \
|
||||
((((uint64_t)(x) & 0x00000000000000ffULL) << 56U) | (((uint64_t)(x) & 0x000000000000ff00ULL) << 40U) | (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24U) | (((uint64_t)(x) & 0x00000000ff000000ULL) << 8U) \
|
||||
| (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8U) | (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24U) | (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40U) | (((uint64_t)(x) & 0xff00000000000000ULL) >> 56U))
|
||||
#else
|
||||
#define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x))
|
||||
#define ZT_CONST_TO_BE_UINT64(x) ((uint64_t)(x))
|
||||
|
@ -58,14 +51,12 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Miscellaneous utility functions and global constants
|
||||
*/
|
||||
class Utils
|
||||
{
|
||||
class Utils {
|
||||
public:
|
||||
static const uint64_t ZERO256[4];
|
||||
|
||||
#ifdef ZT_ARCH_ARM_HAS_NEON
|
||||
struct ARMCapabilities
|
||||
{
|
||||
struct ARMCapabilities {
|
||||
ARMCapabilities() noexcept;
|
||||
|
||||
bool aes;
|
||||
|
@ -78,8 +69,7 @@ public:
|
|||
#endif
|
||||
|
||||
#ifdef ZT_ARCH_X64
|
||||
struct CPUIDRegisters
|
||||
{
|
||||
struct CPUIDRegisters {
|
||||
CPUIDRegisters() noexcept;
|
||||
|
||||
bool rdrand;
|
||||
|
@ -241,9 +231,11 @@ public:
|
|||
uint8_t c = 0;
|
||||
if ((hc >= 48) && (hc <= 57)) { // 0..9
|
||||
c = hc - 48;
|
||||
} else if ((hc >= 97)&&(hc <= 102)) { // a..f
|
||||
}
|
||||
else if ((hc >= 97) && (hc <= 102)) { // a..f
|
||||
c = hc - 87;
|
||||
} else if ((hc >= 65)&&(hc <= 70)) { // A..F
|
||||
}
|
||||
else if ((hc >= 65) && (hc <= 70)) { // A..F
|
||||
c = hc - 55;
|
||||
}
|
||||
|
||||
|
@ -255,9 +247,11 @@ public:
|
|||
c <<= 4;
|
||||
if ((hc >= 48) && (hc <= 57)) {
|
||||
c |= hc - 48;
|
||||
} else if ((hc >= 97)&&(hc <= 102)) {
|
||||
}
|
||||
else if ((hc >= 97) && (hc <= 102)) {
|
||||
c |= hc - 87;
|
||||
} else if ((hc >= 65)&&(hc <= 70)) {
|
||||
}
|
||||
else if ((hc >= 65) && (hc <= 70)) {
|
||||
c |= hc - 55;
|
||||
}
|
||||
|
||||
|
@ -282,9 +276,11 @@ public:
|
|||
uint8_t c = 0;
|
||||
if ((hc >= 48) && (hc <= 57)) {
|
||||
c = hc - 48;
|
||||
} else if ((hc >= 97)&&(hc <= 102)) {
|
||||
}
|
||||
else if ((hc >= 97) && (hc <= 102)) {
|
||||
c = hc - 87;
|
||||
} else if ((hc >= 65)&&(hc <= 70)) {
|
||||
}
|
||||
else if ((hc >= 65) && (hc <= 70)) {
|
||||
c = hc - 55;
|
||||
}
|
||||
|
||||
|
@ -299,9 +295,11 @@ public:
|
|||
c <<= 4;
|
||||
if ((hc >= 48) && (hc <= 57)) {
|
||||
c |= hc - 48;
|
||||
} else if ((hc >= 97)&&(hc <= 102)) {
|
||||
}
|
||||
else if ((hc >= 97) && (hc <= 102)) {
|
||||
c |= hc - 87;
|
||||
} else if ((hc >= 65)&&(hc <= 70)) {
|
||||
}
|
||||
else if ((hc >= 65) && (hc <= 70)) {
|
||||
c |= hc - 55;
|
||||
}
|
||||
|
||||
|
@ -345,11 +343,26 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
|
||||
static inline int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
|
||||
static inline unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
|
||||
static inline long strToLong(const char *s) { return strtol(s,(char **)0,10); }
|
||||
static inline double strToDouble(const char *s) { return strtod(s,NULL); }
|
||||
static inline unsigned int strToUInt(const char* s)
|
||||
{
|
||||
return (unsigned int)strtoul(s, (char**)0, 10);
|
||||
}
|
||||
static inline int strToInt(const char* s)
|
||||
{
|
||||
return (int)strtol(s, (char**)0, 10);
|
||||
}
|
||||
static inline unsigned long strToULong(const char* s)
|
||||
{
|
||||
return strtoul(s, (char**)0, 10);
|
||||
}
|
||||
static inline long strToLong(const char* s)
|
||||
{
|
||||
return strtol(s, (char**)0, 10);
|
||||
}
|
||||
static inline double strToDouble(const char* s)
|
||||
{
|
||||
return strtod(s, NULL);
|
||||
}
|
||||
static inline unsigned long long strToU64(const char* s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
|
@ -366,10 +379,22 @@ public:
|
|||
return strtoll(s, (char**)0, 10);
|
||||
#endif
|
||||
}
|
||||
static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
|
||||
static inline int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
|
||||
static inline unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
|
||||
static inline long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
|
||||
static inline unsigned int hexStrToUInt(const char* s)
|
||||
{
|
||||
return (unsigned int)strtoul(s, (char**)0, 16);
|
||||
}
|
||||
static inline int hexStrToInt(const char* s)
|
||||
{
|
||||
return (int)strtol(s, (char**)0, 16);
|
||||
}
|
||||
static inline unsigned long hexStrToULong(const char* s)
|
||||
{
|
||||
return strtoul(s, (char**)0, 16);
|
||||
}
|
||||
static inline long hexStrToLong(const char* s)
|
||||
{
|
||||
return strtol(s, (char**)0, 16);
|
||||
}
|
||||
static inline unsigned long long hexStrToU64(const char* s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
|
@ -476,15 +501,8 @@ public:
|
|||
return (uint64_t)_byteswap_uint64((unsigned __int64)n);
|
||||
#else
|
||||
return (
|
||||
((n & 0x00000000000000ffULL) << 56) |
|
||||
((n & 0x000000000000ff00ULL) << 40) |
|
||||
((n & 0x0000000000ff0000ULL) << 24) |
|
||||
((n & 0x00000000ff000000ULL) << 8) |
|
||||
((n & 0x000000ff00000000ULL) >> 8) |
|
||||
((n & 0x0000ff0000000000ULL) >> 24) |
|
||||
((n & 0x00ff000000000000ULL) >> 40) |
|
||||
((n & 0xff00000000000000ULL) >> 56)
|
||||
);
|
||||
((n & 0x00000000000000ffULL) << 56) | ((n & 0x000000000000ff00ULL) << 40) | ((n & 0x0000000000ff0000ULL) << 24) | ((n & 0x00000000ff000000ULL) << 8) | ((n & 0x000000ff00000000ULL) >> 8) | ((n & 0x0000ff0000000000ULL) >> 24)
|
||||
| ((n & 0x00ff000000000000ULL) >> 40) | ((n & 0xff00000000000000ULL) >> 56));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -529,109 +547,106 @@ public:
|
|||
|
||||
// These are helper adapters to load and swap integer types special cased by size
|
||||
// to work with all typedef'd variants, signed/unsigned, etc.
|
||||
template< typename I, unsigned int S >
|
||||
class _swap_bytes_bysize;
|
||||
template <typename I, unsigned int S> class _swap_bytes_bysize;
|
||||
|
||||
template< typename I >
|
||||
class _swap_bytes_bysize< I, 1 >
|
||||
{
|
||||
template <typename I> class _swap_bytes_bysize<I, 1> {
|
||||
public:
|
||||
static ZT_INLINE I s(const I n) noexcept
|
||||
{ return n; }
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _swap_bytes_bysize< I, 2 >
|
||||
{
|
||||
template <typename I> class _swap_bytes_bysize<I, 2> {
|
||||
public:
|
||||
static ZT_INLINE I s(const I n) noexcept
|
||||
{ return (I)swapBytes((uint16_t)n); }
|
||||
{
|
||||
return (I)swapBytes((uint16_t)n);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _swap_bytes_bysize< I, 4 >
|
||||
{
|
||||
template <typename I> class _swap_bytes_bysize<I, 4> {
|
||||
public:
|
||||
static ZT_INLINE I s(const I n) noexcept
|
||||
{ return (I)swapBytes((uint32_t)n); }
|
||||
{
|
||||
return (I)swapBytes((uint32_t)n);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _swap_bytes_bysize< I, 8 >
|
||||
{
|
||||
template <typename I> class _swap_bytes_bysize<I, 8> {
|
||||
public:
|
||||
static ZT_INLINE I s(const I n) noexcept
|
||||
{ return (I)swapBytes((uint64_t)n); }
|
||||
{
|
||||
return (I)swapBytes((uint64_t)n);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I, unsigned int S >
|
||||
class _load_be_bysize;
|
||||
template <typename I, unsigned int S> class _load_be_bysize;
|
||||
|
||||
template< typename I >
|
||||
class _load_be_bysize< I, 1 >
|
||||
{
|
||||
template <typename I> class _load_be_bysize<I, 1> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return p[0]; }
|
||||
{
|
||||
return p[0];
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_be_bysize< I, 2 >
|
||||
{
|
||||
template <typename I> class _load_be_bysize<I, 2> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]); }
|
||||
{
|
||||
return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_be_bysize< I, 4 >
|
||||
{
|
||||
template <typename I> class _load_be_bysize<I, 4> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]); }
|
||||
{
|
||||
return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_be_bysize< I, 8 >
|
||||
{
|
||||
template <typename I> class _load_be_bysize<I, 8> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]); }
|
||||
{
|
||||
return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I, unsigned int S >
|
||||
class _load_le_bysize;
|
||||
template <typename I, unsigned int S> class _load_le_bysize;
|
||||
|
||||
template< typename I >
|
||||
class _load_le_bysize< I, 1 >
|
||||
{
|
||||
template <typename I> class _load_le_bysize<I, 1> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return p[0]; }
|
||||
{
|
||||
return p[0];
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_le_bysize< I, 2 >
|
||||
{
|
||||
template <typename I> class _load_le_bysize<I, 2> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U)); }
|
||||
{
|
||||
return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_le_bysize< I, 4 >
|
||||
{
|
||||
template <typename I> class _load_le_bysize<I, 4> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U)); }
|
||||
{
|
||||
return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename I >
|
||||
class _load_le_bysize< I, 8 >
|
||||
{
|
||||
template <typename I> class _load_le_bysize<I, 8> {
|
||||
public:
|
||||
static ZT_INLINE I l(const uint8_t* const p) noexcept
|
||||
{ return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U); }
|
||||
{
|
||||
return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -641,8 +656,7 @@ public:
|
|||
* @param n Value to convert
|
||||
* @return Value in big-endian order
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I hton(const I n) noexcept
|
||||
template <typename I> static ZT_INLINE I hton(const I n) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
return _swap_bytes_bysize<I, sizeof(I)>::s(n);
|
||||
|
@ -658,8 +672,7 @@ public:
|
|||
* @param n Value to convert
|
||||
* @return Value in host byte order
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I ntoh(const I n) noexcept
|
||||
template <typename I> static ZT_INLINE I ntoh(const I n) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
return _swap_bytes_bysize<I, sizeof(I)>::s(n);
|
||||
|
@ -675,8 +688,7 @@ public:
|
|||
* @param p Byte stream, must be at least sizeof(I) in size
|
||||
* @return Loaded raw integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadMachineEndian(const void *const p) noexcept
|
||||
template <typename I> static ZT_INLINE I loadMachineEndian(const void* const p) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
I tmp;
|
||||
|
@ -696,8 +708,7 @@ public:
|
|||
* @param p Byte array (must be at least sizeof(I))
|
||||
* @param i Integer to store
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeMachineEndian(void *const p, const I i) noexcept
|
||||
template <typename I> static ZT_INLINE void storeMachineEndian(void* const p, const I i) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
for (unsigned int k = 0; k < sizeof(I); ++k) {
|
||||
|
@ -715,8 +726,7 @@ public:
|
|||
* @param p Byte stream, must be at least sizeof(I) in size
|
||||
* @return Decoded integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadBigEndian(const void *const p) noexcept
|
||||
template <typename I> static ZT_INLINE I loadBigEndian(const void* const p) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
return _load_be_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t*>(p));
|
||||
|
@ -732,8 +742,7 @@ public:
|
|||
* @param p Byte stream to write (must be at least sizeof(I))
|
||||
* #param i Integer to write
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeBigEndian(void *const p, I i) noexcept
|
||||
template <typename I> static ZT_INLINE void storeBigEndian(void* const p, I i) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
storeMachineEndian(p, hton(i));
|
||||
|
@ -749,8 +758,7 @@ public:
|
|||
* @param p Byte stream, must be at least sizeof(I) in size
|
||||
* @return Decoded integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadLittleEndian(const void *const p) noexcept
|
||||
template <typename I> static ZT_INLINE I loadLittleEndian(const void* const p) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS)
|
||||
return _load_le_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t*>(p));
|
||||
|
@ -766,8 +774,7 @@ public:
|
|||
* @param p Byte stream to write (must be at least sizeof(I))
|
||||
* #param i Integer to write
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeLittleEndian(void *const p, const I i) noexcept
|
||||
template <typename I> static ZT_INLINE void storeLittleEndian(void* const p, const I i) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
storeMachineEndian(p, _swap_bytes_bysize<I, sizeof(I)>::s(i));
|
||||
|
@ -787,8 +794,7 @@ public:
|
|||
* @param dest Destination memory
|
||||
* @param src Source memory
|
||||
*/
|
||||
template< unsigned long L >
|
||||
static ZT_INLINE void copy(void *dest, const void *src) noexcept
|
||||
template <unsigned long L> static ZT_INLINE void copy(void* dest, const void* src) noexcept
|
||||
{
|
||||
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
|
||||
uintptr_t l = L;
|
||||
|
@ -820,8 +826,7 @@ public:
|
|||
* @tparam L Size in bytes
|
||||
* @param dest Memory to zero
|
||||
*/
|
||||
template< unsigned long L >
|
||||
static ZT_INLINE void zero(void *dest) noexcept
|
||||
template <unsigned long L> static ZT_INLINE void zero(void* dest) noexcept
|
||||
{
|
||||
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
|
||||
uintptr_t l = L;
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
#ifndef ZT_WORLD_HPP
|
||||
#define ZT_WORLD_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "ECC.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Maximum number of roots (sanity limit, okay to increase)
|
||||
|
@ -76,14 +76,12 @@ namespace ZeroTier {
|
|||
* world ID for Mars and nearby space is defined but not yet used, and a test
|
||||
* world ID is provided for testing purposes.
|
||||
*/
|
||||
class World
|
||||
{
|
||||
class World {
|
||||
public:
|
||||
/**
|
||||
* World type -- do not change IDs
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
enum Type {
|
||||
TYPE_NULL = 0,
|
||||
TYPE_PLANET = 1, // Planets, of which there is currently one (Earth)
|
||||
TYPE_MOON = 127 // Moons, which are user-created and many
|
||||
|
@ -92,53 +90,78 @@ public:
|
|||
/**
|
||||
* Upstream server definition in world/moon
|
||||
*/
|
||||
struct Root
|
||||
{
|
||||
struct Root {
|
||||
Identity identity;
|
||||
std::vector<InetAddress> stableEndpoints;
|
||||
|
||||
inline bool operator==(const Root &r) const { return ((identity == r.identity)&&(stableEndpoints == r.stableEndpoints)); }
|
||||
inline bool operator!=(const Root &r) const { return (!(*this == r)); }
|
||||
inline bool operator<(const Root &r) const { return (identity < r.identity); } // for sorting
|
||||
inline bool operator==(const Root& r) const
|
||||
{
|
||||
return ((identity == r.identity) && (stableEndpoints == r.stableEndpoints));
|
||||
}
|
||||
inline bool operator!=(const Root& r) const
|
||||
{
|
||||
return (! (*this == r));
|
||||
}
|
||||
inline bool operator<(const Root& r) const
|
||||
{
|
||||
return (identity < r.identity);
|
||||
} // for sorting
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an empty / null World
|
||||
*/
|
||||
World() :
|
||||
_id(0),
|
||||
_ts(0),
|
||||
_type(TYPE_NULL) {}
|
||||
World() : _id(0), _ts(0), _type(TYPE_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Root servers for this world and their stable endpoints
|
||||
*/
|
||||
inline const std::vector<World::Root> &roots() const { return _roots; }
|
||||
inline const std::vector<World::Root>& roots() const
|
||||
{
|
||||
return _roots;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return World type: planet or moon
|
||||
*/
|
||||
inline Type type() const { return _type; }
|
||||
inline Type type() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return World unique identifier
|
||||
*/
|
||||
inline uint64_t id() const { return _id; }
|
||||
inline uint64_t id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return World definition timestamp
|
||||
*/
|
||||
inline uint64_t timestamp() const { return _ts; }
|
||||
inline uint64_t timestamp() const
|
||||
{
|
||||
return _ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return C25519 signature
|
||||
*/
|
||||
inline const ECC::Signature &signature() const { return _signature; }
|
||||
inline const ECC::Signature& signature() const
|
||||
{
|
||||
return _signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Public key that must sign next update
|
||||
*/
|
||||
inline const ECC::Public &updatesMustBeSignedBy() const { return _updatesMustBeSignedBy; }
|
||||
inline const ECC::Public& updatesMustBeSignedBy() const
|
||||
{
|
||||
return _updatesMustBeSignedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a world update should replace this one
|
||||
|
@ -162,10 +185,12 @@ public:
|
|||
/**
|
||||
* @return True if this World is non-empty
|
||||
*/
|
||||
inline operator bool() const { return (_type != TYPE_NULL); }
|
||||
inline operator bool() const
|
||||
{
|
||||
return (_type != TYPE_NULL);
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,bool forSign = false) const
|
||||
template <unsigned int C> inline void serialize(Buffer<C>& b, bool forSign = false) const
|
||||
{
|
||||
if (forSign) {
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
@ -195,8 +220,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
|
||||
|
@ -248,8 +272,16 @@ public:
|
|||
return (p - startAt);
|
||||
}
|
||||
|
||||
inline bool operator==(const World &w) const { return ((_id == w._id)&&(_ts == w._ts)&&(memcmp(_updatesMustBeSignedBy.data,w._updatesMustBeSignedBy.data,ZT_ECC_PUBLIC_KEY_SET_LEN) == 0)&&(memcmp(_signature.data,w._signature.data,ZT_ECC_SIGNATURE_LEN) == 0)&&(_roots == w._roots)&&(_type == w._type)); }
|
||||
inline bool operator!=(const World &w) const { return (!(*this == w)); }
|
||||
inline bool operator==(const World& w) const
|
||||
{
|
||||
return (
|
||||
(_id == w._id) && (_ts == w._ts) && (memcmp(_updatesMustBeSignedBy.data, w._updatesMustBeSignedBy.data, ZT_ECC_PUBLIC_KEY_SET_LEN) == 0) && (memcmp(_signature.data, w._signature.data, ZT_ECC_SIGNATURE_LEN) == 0)
|
||||
&& (_roots == w._roots) && (_type == w._type));
|
||||
}
|
||||
inline bool operator!=(const World& w) const
|
||||
{
|
||||
return (! (*this == w));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a World object signed with a key pair
|
||||
|
|
|
@ -11,21 +11,20 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Arp.hpp"
|
||||
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
static const uint8_t ARP_REQUEST_HEADER[8] = { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01 };
|
||||
static const uint8_t ARP_RESPONSE_HEADER[8] = { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02 };
|
||||
|
||||
Arp::Arp() :
|
||||
_cache(256),
|
||||
_lastCleaned(OSUtils::now())
|
||||
Arp::Arp() : _cache(256), _lastCleaned(OSUtils::now())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,7 +62,8 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response
|
|||
responseLen = 28;
|
||||
responseDest.setTo(reinterpret_cast<const uint8_t*>(arp) + 8, 6);
|
||||
}
|
||||
} else if (!memcmp(arp,ARP_RESPONSE_HEADER,8)) {
|
||||
}
|
||||
else if (! memcmp(arp, ARP_RESPONSE_HEADER, 8)) {
|
||||
// Learn cache entries for remote IPs from relevant ARP replies
|
||||
uint32_t responseIp = 0;
|
||||
memcpy(&responseIp, reinterpret_cast<const uint8_t*>(arp) + 14, 4);
|
||||
|
@ -96,21 +96,26 @@ MAC Arp::query(const MAC &localMac,uint32_t localIp,uint32_t targetIp,void *quer
|
|||
|
||||
_ArpEntry& e = _cache[targetIp];
|
||||
|
||||
if ( ((e.mac)&&((now - e.lastResponseReceived) >= (ZT_ARP_EXPIRE / 3))) ||
|
||||
((!e.mac)&&((now - e.lastQuerySent) >= ZT_ARP_QUERY_INTERVAL)) ) {
|
||||
if (((e.mac) && ((now - e.lastResponseReceived) >= (ZT_ARP_EXPIRE / 3))) || ((! e.mac) && ((now - e.lastQuerySent) >= ZT_ARP_QUERY_INTERVAL))) {
|
||||
e.lastQuerySent = now;
|
||||
|
||||
uint8_t* q = reinterpret_cast<uint8_t*>(query);
|
||||
memcpy(q,ARP_REQUEST_HEADER,8); q += 8; // ARP request header information, always the same
|
||||
localMac.copyTo(q,6); q += 6; // sending host MAC address
|
||||
memcpy(q,&localIp,4); q += 4; // sending host IP (IP already in big-endian byte order)
|
||||
memset(q,0,6); q += 6; // sending zeros for target MAC address as thats what we want to find
|
||||
memcpy(q, ARP_REQUEST_HEADER, 8);
|
||||
q += 8; // ARP request header information, always the same
|
||||
localMac.copyTo(q, 6);
|
||||
q += 6; // sending host MAC address
|
||||
memcpy(q, &localIp, 4);
|
||||
q += 4; // sending host IP (IP already in big-endian byte order)
|
||||
memset(q, 0, 6);
|
||||
q += 6; // sending zeros for target MAC address as thats what we want to find
|
||||
memcpy(q, &targetIp, 4); // target IP address for resolution (IP already in big-endian byte order)
|
||||
queryLen = 28;
|
||||
if (e.mac)
|
||||
queryDest = e.mac; // confirmation query, send directly to address holder
|
||||
else queryDest = (uint64_t)0xffffffffffffULL; // broadcast query
|
||||
} else {
|
||||
else
|
||||
queryDest = (uint64_t)0xffffffffffffULL; // broadcast query
|
||||
}
|
||||
else {
|
||||
queryLen = 0;
|
||||
queryDest.zero();
|
||||
}
|
||||
|
|
|
@ -14,14 +14,13 @@
|
|||
#ifndef ZT_ARP_HPP
|
||||
#define ZT_ARP_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Hashtable.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* Maximum possible ARP length
|
||||
*
|
||||
|
@ -67,8 +66,7 @@ namespace ZeroTier {
|
|||
* This class is not thread-safe and must be guarded if used in multi-threaded
|
||||
* code.
|
||||
*/
|
||||
class Arp
|
||||
{
|
||||
class Arp {
|
||||
public:
|
||||
Arp();
|
||||
|
||||
|
@ -125,9 +123,10 @@ public:
|
|||
MAC query(const MAC& localMac, uint32_t localIp, uint32_t targetIp, void* query, unsigned int& queryLen, MAC& queryDest);
|
||||
|
||||
private:
|
||||
struct _ArpEntry
|
||||
struct _ArpEntry {
|
||||
_ArpEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false)
|
||||
{
|
||||
_ArpEntry() : lastQuerySent(0),lastResponseReceived(0),mac(),local(false) {}
|
||||
}
|
||||
uint64_t lastQuerySent; // Time last query was sent or 0 for local IP
|
||||
uint64_t lastResponseReceived; // Time of last ARP response or 0 for local IP
|
||||
MAC mac; // MAC address of device responsible for IP or null if not known yet
|
||||
|
|
|
@ -11,49 +11,46 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "BSDEthernetTap.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <map>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread_np.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <utility>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "BSDEthernetTap.hpp"
|
||||
|
||||
#define ZT_BASE32_CHARS "0123456789abcdefghijklmnopqrstuv"
|
||||
#define ZT_TAP_BUF_SIZE (1024 * 16)
|
||||
|
||||
|
@ -72,17 +69,17 @@ BSDEthernetTap::BSDEthernetTap(
|
|||
uint64_t nwid,
|
||||
const char* friendlyName,
|
||||
void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int),
|
||||
void *arg) :
|
||||
_handler(handler),
|
||||
_concurrency(concurrency),
|
||||
_pinning(pinning),
|
||||
_arg(arg),
|
||||
_nwid(nwid),
|
||||
_mtu(mtu),
|
||||
_metric(metric),
|
||||
_fd(0),
|
||||
_enabled(true),
|
||||
_lastIfAddrsUpdate(0)
|
||||
void* arg)
|
||||
: _handler(handler)
|
||||
, _concurrency(concurrency)
|
||||
, _pinning(pinning)
|
||||
, _arg(arg)
|
||||
, _nwid(nwid)
|
||||
, _mtu(mtu)
|
||||
, _metric(metric)
|
||||
, _fd(0)
|
||||
, _enabled(true)
|
||||
, _lastIfAddrsUpdate(0)
|
||||
{
|
||||
static Mutex globalTapCreateLock;
|
||||
char devpath[64], ethaddr[64], mtustr[32], metstr[32], tmpdevname[32];
|
||||
|
@ -119,10 +116,13 @@ BSDEthernetTap::BSDEthernetTap(
|
|||
#endif
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", tmpdevname, "create", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
} else throw std::runtime_error("fork() failed");
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("fork() failed");
|
||||
|
||||
struct stat stattmp;
|
||||
if (! stat(devpath, &stattmp)) {
|
||||
|
@ -133,18 +133,23 @@ BSDEthernetTap::BSDEthernetTap(
|
|||
#endif
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", tmpdevname, "name", _dev.c_str(), (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
if (exitcode)
|
||||
throw std::runtime_error("ifconfig rename operation failed");
|
||||
} else throw std::runtime_error("fork() failed");
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("fork() failed");
|
||||
|
||||
_fd = ::open(devpath, O_RDWR);
|
||||
if (_fd > 0)
|
||||
break;
|
||||
else throw std::runtime_error("unable to open created tap device");
|
||||
} else {
|
||||
else
|
||||
throw std::runtime_error("unable to open created tap device");
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("cannot find /dev node for newly created tap device");
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +187,8 @@ BSDEthernetTap::BSDEthernetTap(
|
|||
#endif
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "lladdr", ethaddr, "mtu", mtustr, "metric", metstr, "up", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
if (exitcode) {
|
||||
|
@ -212,7 +218,8 @@ BSDEthernetTap::~BSDEthernetTap()
|
|||
#endif
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "destroy", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
}
|
||||
|
@ -242,7 +249,8 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
|
|||
#endif
|
||||
execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "inet", ip.toIpString(ipbuf), "-alias", (const char*)0);
|
||||
_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
waitpid(cpid, &exitcode, 0);
|
||||
return (exitcode == 0);
|
||||
|
@ -275,7 +283,8 @@ bool BSDEthernetTap::addIp(const InetAddress &ip)
|
|||
#endif
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), ip.isV4() ? "inet" : "inet6", ip.toString(tmp), "alias", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
return (exitcode == 0);
|
||||
|
@ -417,15 +426,15 @@ void BSDEthernetTap::setMtu(unsigned int mtu)
|
|||
#endif
|
||||
execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "mtu", tmp, (const char*)0);
|
||||
_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
waitpid(cpid, &exitcode, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BSDEthernetTap::threadMain()
|
||||
throw()
|
||||
void BSDEthernetTap::threadMain() throw()
|
||||
{
|
||||
// Wait for a moment after startup -- wait for Network to finish
|
||||
// constructing itself.
|
||||
|
@ -433,7 +442,6 @@ void BSDEthernetTap::threadMain()
|
|||
|
||||
for (unsigned int i = 0; i < _concurrency; ++i) {
|
||||
_rxThreads.push_back(std::thread([this, i, _pinning] {
|
||||
|
||||
if (_pinning) {
|
||||
int pinCore = i % _concurrency;
|
||||
fprintf(stderr, "Pinning thread %d to core %d\n", i, pinCore);
|
||||
|
@ -443,8 +451,7 @@ void BSDEthernetTap::threadMain()
|
|||
CPU_SET(pinCore, &cpuset);
|
||||
// int rc = sched_setaffinity(self, sizeof(cpu_set_t), &cpuset);
|
||||
int rc = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset);
|
||||
if (rc != 0)
|
||||
{
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Failed to pin thread %d to core %d: %s\n", i, pinCore, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
@ -474,7 +481,8 @@ void BSDEthernetTap::threadMain()
|
|||
if (n < 0) {
|
||||
if ((errno != EINTR) && (errno != ETIMEDOUT))
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Some tap drivers like to send the ethernet frame and the
|
||||
// payload in two chunks, so handle that by accumulating
|
||||
// data until we have at least a frame.
|
||||
|
|
|
@ -14,24 +14,22 @@
|
|||
#ifndef ZT_BSDETHERNETTAP_HPP
|
||||
#define ZT_BSDETHERNETTAP_HPP
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
#include "Thread.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class BSDEthernetTap : public EthernetTap
|
||||
{
|
||||
class BSDEthernetTap : public EthernetTap {
|
||||
public:
|
||||
BSDEthernetTap(
|
||||
const char* homePath,
|
||||
|
@ -57,10 +55,11 @@ public:
|
|||
virtual void setFriendlyName(const char* friendlyName);
|
||||
virtual void scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
|
||||
virtual void setMtu(unsigned int mtu);
|
||||
virtual void setDns(const char *domain, const std::vector<InetAddress> &servers) {}
|
||||
virtual void setDns(const char* domain, const std::vector<InetAddress>& servers)
|
||||
{
|
||||
}
|
||||
|
||||
void threadMain()
|
||||
throw();
|
||||
void threadMain() throw();
|
||||
|
||||
private:
|
||||
void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int);
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
#include <string.h>
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <shlobj.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <netioapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -34,9 +34,9 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __LINUX__
|
||||
#include <linux/if_addr.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if_addr.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#ifndef ZT_BLOCKINGQUEUE_HPP
|
||||
#define ZT_BLOCKINGQUEUE_HPP
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -28,11 +28,11 @@ namespace ZeroTier {
|
|||
*
|
||||
* Do not use in node/ since we have not gone C++11 there yet.
|
||||
*/
|
||||
template <class T>
|
||||
class BlockingQueue
|
||||
{
|
||||
template <class T> class BlockingQueue {
|
||||
public:
|
||||
BlockingQueue(void) : r(true) {}
|
||||
BlockingQueue(void) : r(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline void post(T t)
|
||||
{
|
||||
|
@ -92,12 +92,7 @@ public:
|
|||
return v;
|
||||
}
|
||||
|
||||
enum TimedWaitResult
|
||||
{
|
||||
OK,
|
||||
TIMED_OUT,
|
||||
STOP
|
||||
};
|
||||
enum TimedWaitResult { OK, TIMED_OUT, STOP };
|
||||
|
||||
inline TimedWaitResult get(T& value, const unsigned long ms)
|
||||
{
|
||||
|
@ -116,7 +111,8 @@ public:
|
|||
return OK;
|
||||
}
|
||||
|
||||
inline size_t size() const {
|
||||
inline size_t size() const
|
||||
{
|
||||
return q.size();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
/****/
|
||||
|
||||
#include "EthernetTap.hpp"
|
||||
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -20,15 +21,16 @@
|
|||
#ifdef ZT_SDK
|
||||
|
||||
#include "../controller/EmbeddedNetworkController.hpp"
|
||||
#include "../node/Node.hpp"
|
||||
#include "../include/VirtualTap.hpp"
|
||||
#include "../node/Node.hpp"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
#include "MacEthernetTap.hpp"
|
||||
#include "MacKextEthernetTap.hpp"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#endif // __APPLE__
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
@ -68,7 +70,6 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
|
|||
void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int),
|
||||
void* arg)
|
||||
{
|
||||
|
||||
#ifdef ZT_SDK
|
||||
|
||||
return std::shared_ptr<EthernetTap>(new VirtualTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg));
|
||||
|
@ -86,7 +87,8 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
|
|||
// (Sierra and earlier) must use the a kernel extension.
|
||||
if (strtol(osrelease, (char**)0, 10) < 17) {
|
||||
return std::shared_ptr<EthernetTap>(new MacKextEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return std::shared_ptr<EthernetTap>(new MacEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg));
|
||||
}
|
||||
}
|
||||
|
@ -109,17 +111,7 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
|
|||
{
|
||||
Mutex::Lock l(_comInit_m);
|
||||
if (! _comInit) {
|
||||
hres = CoInitializeSecurity(
|
||||
NULL,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
RPC_C_AUTHN_LEVEL_PKT,
|
||||
RPC_C_IMP_LEVEL_IMPERSONATE,
|
||||
NULL,
|
||||
EOAC_NONE,
|
||||
NULL
|
||||
);
|
||||
hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
|
||||
if (FAILED(hres)) {
|
||||
CoUninitialize();
|
||||
fprintf(stderr, "WinEthernetTap: Failed to initialize security");
|
||||
|
@ -148,8 +140,12 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
|
|||
return std::shared_ptr<EthernetTap>();
|
||||
}
|
||||
|
||||
EthernetTap::EthernetTap() {}
|
||||
EthernetTap::~EthernetTap() {}
|
||||
EthernetTap::EthernetTap()
|
||||
{
|
||||
}
|
||||
EthernetTap::~EthernetTap()
|
||||
{
|
||||
}
|
||||
|
||||
bool EthernetTap::addIps(std::vector<InetAddress> ips)
|
||||
{
|
||||
|
|
|
@ -15,20 +15,19 @@
|
|||
#define ZT_ETHERNETTAP_HPP
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define GETIFADDRS_CACHE_TIME 1000
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class EthernetTap
|
||||
{
|
||||
class EthernetTap {
|
||||
public:
|
||||
static std::shared_ptr<EthernetTap> newInstance(
|
||||
const char* tapDeviceType, // OS-specific, NULL for default
|
||||
|
|
|
@ -11,15 +11,16 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Http.hpp"
|
||||
#include "Phy.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "Phy.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ZT_USE_SYSTEM_HTTP_PARSER
|
||||
#include <http_parser.h>
|
||||
|
@ -45,39 +46,26 @@ static int ShttpOnBody(http_parser *parser,const char *ptr,size_t length);
|
|||
static int ShttpOnMessageComplete(http_parser* parser);
|
||||
|
||||
#if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 1)
|
||||
static const struct http_parser_settings HTTP_PARSER_SETTINGS = {
|
||||
ShttpOnMessageBegin,
|
||||
ShttpOnUrl,
|
||||
ShttpOnStatus,
|
||||
ShttpOnHeaderField,
|
||||
ShttpOnValue,
|
||||
ShttpOnHeadersComplete,
|
||||
ShttpOnBody,
|
||||
ShttpOnMessageComplete
|
||||
};
|
||||
static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnStatus, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete };
|
||||
#else
|
||||
static const struct http_parser_settings HTTP_PARSER_SETTINGS = {
|
||||
ShttpOnMessageBegin,
|
||||
ShttpOnUrl,
|
||||
ShttpOnHeaderField,
|
||||
ShttpOnValue,
|
||||
ShttpOnHeadersComplete,
|
||||
ShttpOnBody,
|
||||
ShttpOnMessageComplete
|
||||
};
|
||||
static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete };
|
||||
#endif
|
||||
|
||||
struct HttpPhyHandler
|
||||
{
|
||||
struct HttpPhyHandler {
|
||||
// not used
|
||||
inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) {}
|
||||
inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) {}
|
||||
inline void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len)
|
||||
{
|
||||
}
|
||||
inline void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from)
|
||||
{
|
||||
}
|
||||
|
||||
inline void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success)
|
||||
{
|
||||
if (success) {
|
||||
phy->setNotifyWritable(sock, true);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*responseBody = "connection failed";
|
||||
error = true;
|
||||
done = true;
|
||||
|
@ -108,12 +96,22 @@ struct HttpPhyHandler
|
|||
phy->setNotifyWritable(sock, false);
|
||||
}
|
||||
|
||||
inline void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) {}
|
||||
inline void phyOnFileDescriptorActivity(PhySocket* sock, void** uptr, bool readable, bool writable)
|
||||
{
|
||||
}
|
||||
#ifdef __UNIX_LIKE__
|
||||
inline void phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {}
|
||||
inline void phyOnUnixClose(PhySocket *sock,void **uptr) {}
|
||||
inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {}
|
||||
inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {}
|
||||
inline void phyOnUnixAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN)
|
||||
{
|
||||
}
|
||||
inline void phyOnUnixClose(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
inline void phyOnUnixData(PhySocket* sock, void** uptr, void* data, unsigned long len)
|
||||
{
|
||||
}
|
||||
inline void phyOnUnixWritable(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
#endif // __UNIX_LIKE__
|
||||
|
||||
http_parser parser;
|
||||
|
@ -240,14 +238,16 @@ unsigned int Http::_do(
|
|||
handler.writeBuf.append("\r\n");
|
||||
if ((requestBody) && (requestBodyLength))
|
||||
handler.writeBuf.append((const char*)requestBody, requestBodyLength);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
responseBody = "request too large";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (maxResponseSize) {
|
||||
handler.maxResponseSize = maxResponseSize;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
handler.maxResponseSize = 2147483647;
|
||||
}
|
||||
handler.responseHeaders = &responseHeaders;
|
||||
|
@ -275,10 +275,12 @@ unsigned int Http::_do(
|
|||
}
|
||||
|
||||
return ((handler.error) ? 0 : ((handler.parser.http_errno != HPE_OK) ? 0 : handler.parser.status_code));
|
||||
} catch (std::exception &exc) {
|
||||
}
|
||||
catch (std::exception& exc) {
|
||||
responseBody = exc.what();
|
||||
return 0;
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch (...) {
|
||||
responseBody = "unknown exception";
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,21 +14,21 @@
|
|||
#ifndef ZT_HTTP_HPP
|
||||
#define ZT_HTTP_HPP
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -36,8 +36,7 @@ namespace ZeroTier {
|
|||
/**
|
||||
* Simple synchronous HTTP client used for updater and cli
|
||||
*/
|
||||
class Http
|
||||
{
|
||||
class Http {
|
||||
public:
|
||||
/**
|
||||
* Make HTTP GET request
|
||||
|
@ -46,8 +45,8 @@ public:
|
|||
*
|
||||
* @return HTTP status code or 0 on error (responseBody will contain error message)
|
||||
*/
|
||||
static inline unsigned int GET(
|
||||
unsigned long maxResponseSize,
|
||||
static inline unsigned int
|
||||
GET(unsigned long maxResponseSize,
|
||||
unsigned long timeout,
|
||||
const struct sockaddr* remoteAddress,
|
||||
const char* path,
|
||||
|
@ -55,17 +54,7 @@ public:
|
|||
std::map<std::string, std::string>& responseHeaders,
|
||||
std::string& responseBody)
|
||||
{
|
||||
return _do(
|
||||
"GET",
|
||||
maxResponseSize,
|
||||
timeout,
|
||||
remoteAddress,
|
||||
path,
|
||||
requestHeaders,
|
||||
(const void *)0,
|
||||
0,
|
||||
responseHeaders,
|
||||
responseBody);
|
||||
return _do("GET", maxResponseSize, timeout, remoteAddress, path, requestHeaders, (const void*)0, 0, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,8 +64,8 @@ public:
|
|||
*
|
||||
* @return HTTP status code or 0 on error (responseBody will contain error message)
|
||||
*/
|
||||
static inline unsigned int DEL(
|
||||
unsigned long maxResponseSize,
|
||||
static inline unsigned int
|
||||
DEL(unsigned long maxResponseSize,
|
||||
unsigned long timeout,
|
||||
const struct sockaddr* remoteAddress,
|
||||
const char* path,
|
||||
|
@ -84,17 +73,7 @@ public:
|
|||
std::map<std::string, std::string>& responseHeaders,
|
||||
std::string& responseBody)
|
||||
{
|
||||
return _do(
|
||||
"DELETE",
|
||||
maxResponseSize,
|
||||
timeout,
|
||||
remoteAddress,
|
||||
path,
|
||||
requestHeaders,
|
||||
(const void *)0,
|
||||
0,
|
||||
responseHeaders,
|
||||
responseBody);
|
||||
return _do("DELETE", maxResponseSize, timeout, remoteAddress, path, requestHeaders, (const void*)0, 0, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,17 +96,7 @@ public:
|
|||
std::map<std::string, std::string>& responseHeaders,
|
||||
std::string& responseBody)
|
||||
{
|
||||
return _do(
|
||||
"POST",
|
||||
maxResponseSize,
|
||||
timeout,
|
||||
remoteAddress,
|
||||
path,
|
||||
requestHeaders,
|
||||
postData,
|
||||
postDataLength,
|
||||
responseHeaders,
|
||||
responseBody);
|
||||
return _do("POST", maxResponseSize, timeout, remoteAddress, path, requestHeaders, postData, postDataLength, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,8 +108,8 @@ public:
|
|||
*
|
||||
* @return HTTP status code or 0 on error (responseBody will contain error message)
|
||||
*/
|
||||
static inline unsigned int PUT(
|
||||
unsigned long maxResponseSize,
|
||||
static inline unsigned int
|
||||
PUT(unsigned long maxResponseSize,
|
||||
unsigned long timeout,
|
||||
const struct sockaddr* remoteAddress,
|
||||
const char* path,
|
||||
|
@ -150,22 +119,12 @@ public:
|
|||
std::map<std::string, std::string>& responseHeaders,
|
||||
std::string& responseBody)
|
||||
{
|
||||
return _do(
|
||||
"PUT",
|
||||
maxResponseSize,
|
||||
timeout,
|
||||
remoteAddress,
|
||||
path,
|
||||
requestHeaders,
|
||||
postData,
|
||||
postDataLength,
|
||||
responseHeaders,
|
||||
responseBody);
|
||||
return _do("PUT", maxResponseSize, timeout, remoteAddress, path, requestHeaders, postData, postDataLength, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
private:
|
||||
static unsigned int _do(
|
||||
const char *method,
|
||||
static unsigned int
|
||||
_do(const char* method,
|
||||
unsigned long maxResponseSize,
|
||||
unsigned long timeout,
|
||||
const struct sockaddr* remoteAddress,
|
||||
|
|
|
@ -19,42 +19,39 @@
|
|||
|
||||
#ifdef __LINUX__
|
||||
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Dictionary.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "LinuxEthernetTap.hpp"
|
||||
#include "LinuxNetLink.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <utility>
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
|
@ -72,7 +69,8 @@ namespace ZeroTier {
|
|||
// the tap devices.
|
||||
//
|
||||
// Returns true if the kernel major version is < 3
|
||||
bool isOldLinuxKernel() {
|
||||
bool isOldLinuxKernel()
|
||||
{
|
||||
struct utsname buffer;
|
||||
char* p;
|
||||
long ver[16];
|
||||
|
@ -88,7 +86,8 @@ bool isOldLinuxKernel() {
|
|||
if (isdigit(*p)) {
|
||||
ver[i] = strtol(p, &p, 10);
|
||||
i++;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
@ -119,23 +118,22 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||
uint64_t nwid,
|
||||
const char* friendlyName,
|
||||
void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int),
|
||||
void *arg) :
|
||||
_handler(handler),
|
||||
_arg(arg),
|
||||
_nwid(nwid),
|
||||
_mac(mac),
|
||||
_homePath(homePath),
|
||||
_mtu(mtu),
|
||||
_fd(0),
|
||||
_enabled(true),
|
||||
_run(true),
|
||||
_lastIfAddrsUpdate(0)
|
||||
void* arg)
|
||||
: _handler(handler)
|
||||
, _arg(arg)
|
||||
, _nwid(nwid)
|
||||
, _mac(mac)
|
||||
, _homePath(homePath)
|
||||
, _mtu(mtu)
|
||||
, _fd(0)
|
||||
, _enabled(true)
|
||||
, _run(true)
|
||||
, _lastIfAddrsUpdate(0)
|
||||
{
|
||||
static std::mutex s_tapCreateLock;
|
||||
char procpath[128], nwids[32];
|
||||
struct stat sbuf;
|
||||
|
||||
|
||||
// Create only one tap at a time globally.
|
||||
std::lock_guard<std::mutex> tapCreateLock(s_tapCreateLock);
|
||||
|
||||
|
@ -165,9 +163,12 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||
char* y = (char*)0;
|
||||
char* saveptr = (char*)0;
|
||||
for (char* f = Utils::stok(buf, "\r\n=", &saveptr); (f); f = Utils::stok((char*)0, "\r\n=", &saveptr)) {
|
||||
if (!x) x = f;
|
||||
else if (!y) y = f;
|
||||
else break;
|
||||
if (! x)
|
||||
x = f;
|
||||
else if (! y)
|
||||
y = f;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((x) && (y) && (x[0]) && (y[0]))
|
||||
globalDeviceMap[x] = y;
|
||||
|
@ -224,7 +225,6 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||
|
||||
for (unsigned int i = 0; i < concurrency; ++i) {
|
||||
_rxThreads.push_back(std::thread([this, i, concurrency, pinning] {
|
||||
|
||||
if (pinning) {
|
||||
int pinCore = i % concurrency;
|
||||
fprintf(stderr, "Pinning tap thread %d to core %d\n", i, pinCore);
|
||||
|
@ -233,8 +233,7 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(pinCore, &cpuset);
|
||||
int rc = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset);
|
||||
if (rc != 0)
|
||||
{
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Failed to pin tap thread %d to core %d: %s\n", i, pinCore, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
@ -407,14 +406,13 @@ bool LinuxEthernetTap::addIps(std::vector<InetAddress> ips)
|
|||
if (ips[i].isV4()) {
|
||||
char iptmp[64], iptmp2[64];
|
||||
std::string numstr4 = ip4_tot > 1 ? std::to_string(ip4) : "";
|
||||
cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString(iptmp)
|
||||
+ "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString(iptmp2)+"\n";
|
||||
cfg_contents += "\nIPADDR" + numstr4 + "=" + ips[i].toIpString(iptmp) + "\nNETMASK" + numstr4 + "=" + ips[i].netmask().toIpString(iptmp2) + "\n";
|
||||
ip4++;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
char iptmp[64], iptmp2[64];
|
||||
std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : "";
|
||||
cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString(iptmp)
|
||||
+ "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString(iptmp2)+"\n";
|
||||
cfg_contents += "\nIPV6ADDR" + numstr6 + "=" + ips[i].toIpString(iptmp) + "\nNETMASK" + numstr6 + "=" + ips[i].netmask().toIpString(iptmp2) + "\n";
|
||||
ip6++;
|
||||
}
|
||||
}
|
||||
|
@ -462,7 +460,6 @@ bool LinuxEthernetTap::removeIp(const InetAddress &ip)
|
|||
|
||||
std::vector<InetAddress> LinuxEthernetTap::ips() const
|
||||
{
|
||||
|
||||
uint64_t now = OSUtils::now();
|
||||
|
||||
if ((now - _lastIfAddrsUpdate) <= GETIFADDRS_CACHE_TIME) {
|
||||
|
|
|
@ -14,24 +14,23 @@
|
|||
#ifndef ZT_LINUXETHERNETTAP_HPP
|
||||
#define ZT_LINUXETHERNETTAP_HPP
|
||||
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "BlockingQueue.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <atomic>
|
||||
#include <array>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
#include "BlockingQueue.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class LinuxEthernetTap : public EthernetTap
|
||||
{
|
||||
class LinuxEthernetTap : public EthernetTap {
|
||||
public:
|
||||
LinuxEthernetTap(
|
||||
const char* homePath,
|
||||
|
@ -58,7 +57,9 @@ public:
|
|||
virtual void setFriendlyName(const char* friendlyName);
|
||||
virtual void scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
|
||||
virtual void setMtu(unsigned int mtu);
|
||||
virtual void setDns(const char *domain, const std::vector<InetAddress> &servers) {}
|
||||
virtual void setDns(const char* domain, const std::vector<InetAddress>& servers)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int);
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
#include "LinuxNetLink.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
|
@ -49,14 +49,7 @@ struct nl_adr_req {
|
|||
char buf[8192];
|
||||
};
|
||||
|
||||
LinuxNetLink::LinuxNetLink()
|
||||
: _t()
|
||||
, _running(false)
|
||||
, _seq(0)
|
||||
, _interfaces()
|
||||
, _if_m()
|
||||
, _fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE))
|
||||
, _la({0})
|
||||
LinuxNetLink::LinuxNetLink() : _t(), _running(false), _seq(0), _interfaces(), _if_m(), _fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)), _la({ 0 })
|
||||
{
|
||||
// set socket timeout to 1 sec so we're not permablocking recv() calls
|
||||
_setSocketTimeout(_fd, 1);
|
||||
|
@ -137,8 +130,7 @@ int LinuxNetLink::_doRecv(int fd)
|
|||
break;
|
||||
}
|
||||
|
||||
if( (nlp->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI || (nlp->nlmsg_type == NLMSG_DONE))
|
||||
{
|
||||
if ((nlp->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI || (nlp->nlmsg_type == NLMSG_DONE)) {
|
||||
if (nlp->nlmsg_type == NLMSG_DONE) {
|
||||
_processMessage(nlp, nll);
|
||||
p = buf;
|
||||
|
@ -165,7 +157,8 @@ int LinuxNetLink::_doRecv(int fd)
|
|||
p = buf;
|
||||
nll = 0;
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -189,10 +182,8 @@ void LinuxNetLink::threadMain() throw()
|
|||
|
||||
void LinuxNetLink::_processMessage(struct nlmsghdr* nlp, int nll)
|
||||
{
|
||||
for(; NLMSG_OK(nlp, nll); nlp=NLMSG_NEXT(nlp, nll))
|
||||
{
|
||||
switch(nlp->nlmsg_type)
|
||||
{
|
||||
for (; NLMSG_OK(nlp, nll); nlp = NLMSG_NEXT(nlp, nll)) {
|
||||
switch (nlp->nlmsg_type) {
|
||||
case RTM_NEWLINK:
|
||||
_linkAdded(nlp);
|
||||
break;
|
||||
|
@ -229,8 +220,7 @@ void LinuxNetLink::_ipAddressAdded(struct nlmsghdr *nlp)
|
|||
char label[40] = { 0 };
|
||||
char bcast[40] = { 0 };
|
||||
|
||||
for(;RTA_OK(rtap, ifal); rtap=RTA_NEXT(rtap,ifal))
|
||||
{
|
||||
for (; RTA_OK(rtap, ifal); rtap = RTA_NEXT(rtap, ifal)) {
|
||||
switch (rtap->rta_type) {
|
||||
case IFA_ADDRESS:
|
||||
inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40);
|
||||
|
@ -263,8 +253,7 @@ void LinuxNetLink::_ipAddressDeleted(struct nlmsghdr *nlp)
|
|||
char label[40] = { 0 };
|
||||
char bcast[40] = { 0 };
|
||||
|
||||
for(;RTA_OK(rtap, ifal); rtap=RTA_NEXT(rtap,ifal))
|
||||
{
|
||||
for (; RTA_OK(rtap, ifal); rtap = RTA_NEXT(rtap, ifal)) {
|
||||
switch (rtap->rta_type) {
|
||||
case IFA_ADDRESS:
|
||||
inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40);
|
||||
|
@ -300,10 +289,8 @@ void LinuxNetLink::_routeAdded(struct nlmsghdr *nlp)
|
|||
Route r;
|
||||
bool wecare = false;
|
||||
|
||||
for(;RTA_OK(rtap, rtl); rtap=RTA_NEXT(rtap, rtl))
|
||||
{
|
||||
switch(rtap->rta_type)
|
||||
{
|
||||
for (; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl)) {
|
||||
switch (rtap->rta_type) {
|
||||
case RTA_DST:
|
||||
switch (rtp->rtm_family) {
|
||||
case AF_INET:
|
||||
|
@ -388,10 +375,8 @@ void LinuxNetLink::_routeDeleted(struct nlmsghdr *nlp)
|
|||
Route r;
|
||||
bool wecare = false;
|
||||
|
||||
for(;RTA_OK(rtap, rtl); rtap=RTA_NEXT(rtap, rtl))
|
||||
{
|
||||
switch(rtap->rta_type)
|
||||
{
|
||||
for (; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl)) {
|
||||
switch (rtap->rta_type) {
|
||||
case RTA_DST:
|
||||
switch (rtp->rtm_family) {
|
||||
case AF_INET:
|
||||
|
@ -472,8 +457,7 @@ void LinuxNetLink::_linkAdded(struct nlmsghdr *nlp)
|
|||
int ifil = RTM_PAYLOAD(nlp);
|
||||
|
||||
const char* ptr = (const char*)0;
|
||||
for(;RTA_OK(rtap, ifil);rtap=RTA_NEXT(rtap, ifil))
|
||||
{
|
||||
for (; RTA_OK(rtap, ifil); rtap = RTA_NEXT(rtap, ifil)) {
|
||||
switch (rtap->rta_type) {
|
||||
case IFLA_ADDRESS:
|
||||
ptr = (const char*)RTA_DATA(rtap);
|
||||
|
@ -494,7 +478,16 @@ void LinuxNetLink::_linkAdded(struct nlmsghdr *nlp)
|
|||
struct iface_entry& entry = _interfaces[ifip->ifi_index];
|
||||
entry.index = ifip->ifi_index;
|
||||
memcpy(entry.ifacename, ifname, sizeof(ifname));
|
||||
snprintf(entry.mac,sizeof(entry.mac),"%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",(unsigned int)mac_bin[0],(unsigned int)mac_bin[1],(unsigned int)mac_bin[2],(unsigned int)mac_bin[3],(unsigned int)mac_bin[4],(unsigned int)mac_bin[5]);
|
||||
snprintf(
|
||||
entry.mac,
|
||||
sizeof(entry.mac),
|
||||
"%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
|
||||
(unsigned int)mac_bin[0],
|
||||
(unsigned int)mac_bin[1],
|
||||
(unsigned int)mac_bin[2],
|
||||
(unsigned int)mac_bin[3],
|
||||
(unsigned int)mac_bin[4],
|
||||
(unsigned int)mac_bin[5]);
|
||||
memcpy(entry.mac_bin, mac_bin, 6);
|
||||
entry.mtu = mtu;
|
||||
}
|
||||
|
@ -510,8 +503,7 @@ void LinuxNetLink::_linkDeleted(struct nlmsghdr *nlp)
|
|||
int ifil = RTM_PAYLOAD(nlp);
|
||||
|
||||
const char* ptr = (const char*)0;
|
||||
for(;RTA_OK(rtap, ifil);rtap=RTA_NEXT(rtap, ifil))
|
||||
{
|
||||
for (; RTA_OK(rtap, ifil); rtap = RTA_NEXT(rtap, ifil)) {
|
||||
switch (rtap->rta_type) {
|
||||
case IFLA_IFNAME:
|
||||
ptr = (const char*)RTA_DATA(rtap);
|
||||
|
@ -690,7 +682,8 @@ void LinuxNetLink::_requestInterfaceList()
|
|||
|
||||
void LinuxNetLink::addRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName)
|
||||
{
|
||||
if (!target) return;
|
||||
if (! target)
|
||||
return;
|
||||
|
||||
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (fd == -1) {
|
||||
|
@ -727,7 +720,8 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c
|
|||
if (target.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&target)->sin_addr, sizeof(struct in_addr));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&target)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
|
@ -756,19 +750,21 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c
|
|||
if (via.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&via)->sin_addr, sizeof(struct in_addr));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&via)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
rtl += rtap->rta_len;
|
||||
} else if (src) {
|
||||
}
|
||||
else if (src) {
|
||||
rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len);
|
||||
rtap->rta_type = RTA_SRC;
|
||||
if (src.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&src)->sin_addr, sizeof(struct in_addr));
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&src)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
|
@ -823,7 +819,8 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c
|
|||
|
||||
void LinuxNetLink::delRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName)
|
||||
{
|
||||
if (!target) return;
|
||||
if (! target)
|
||||
return;
|
||||
|
||||
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (fd == -1) {
|
||||
|
@ -859,7 +856,8 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c
|
|||
if (target.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&target)->sin_addr, sizeof(struct in_addr));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&target)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
|
@ -871,19 +869,21 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c
|
|||
if (via.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&via)->sin_addr, sizeof(struct in_addr));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&via)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
rtl += rtap->rta_len;
|
||||
} else if (src) {
|
||||
}
|
||||
else if (src) {
|
||||
rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len);
|
||||
rtap->rta_type = RTA_SRC;
|
||||
if (src.isV4()) {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&src)->sin_addr, sizeof(struct in_addr));
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&src)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
|
@ -952,7 +952,8 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface)
|
|||
la.nl_pid = 0; // getpid();
|
||||
if (addr.isV4()) {
|
||||
la.nl_groups = RTMGRP_IPV4_IFADDR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
la.nl_groups = RTMGRP_IPV6_IFADDR;
|
||||
}
|
||||
|
||||
|
@ -983,7 +984,8 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface)
|
|||
struct nl_adr_req req;
|
||||
bzero(&req, sizeof(struct nl_adr_req));
|
||||
|
||||
struct rtattr *rtap = (struct rtattr *)req.buf;;
|
||||
struct rtattr* rtap = (struct rtattr*)req.buf;
|
||||
;
|
||||
if (addr.isV4()) {
|
||||
struct sockaddr_in* addr_v4 = (struct sockaddr_in*)&addr;
|
||||
rtap->rta_type = IFA_ADDRESS;
|
||||
|
@ -1006,7 +1008,8 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface)
|
|||
memcpy(RTA_DATA(rtap), &bcast->sin_addr, sizeof(struct in_addr));
|
||||
rtl += rtap->rta_len;
|
||||
}
|
||||
} else { //V6
|
||||
}
|
||||
else { // V6
|
||||
rtap->rta_type = IFA_ADDRESS;
|
||||
struct sockaddr_in6* addr_v6 = (struct sockaddr_in6*)&addr;
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
|
@ -1069,7 +1072,8 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface)
|
|||
la.nl_pid = 0; // getpid();
|
||||
if (addr.isV4()) {
|
||||
la.nl_groups = RTMGRP_IPV4_IFADDR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
la.nl_groups = RTMGRP_IPV6_IFADDR;
|
||||
}
|
||||
if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) {
|
||||
|
@ -1118,7 +1122,8 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface)
|
|||
memcpy(RTA_DATA(rtap), &bcast->sin_addr, sizeof(struct in_addr));
|
||||
rtl += rtap->rta_len;
|
||||
}
|
||||
} else { //V6
|
||||
}
|
||||
else { // V6
|
||||
rtap->rta_type = IFA_ADDRESS;
|
||||
struct sockaddr_in6* addr_v6 = (struct sockaddr_in6*)&addr;
|
||||
rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
|
||||
|
@ -1177,7 +1182,8 @@ bool LinuxNetLink::routeIsSet(const InetAddress &target, const InetAddress &via,
|
|||
const iface_entry* ife = _interfaces.get(ri->ifidx);
|
||||
if ((ife) && (! strncmp(ife->ifacename, ifname, IFNAMSIZ)))
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,30 +18,26 @@
|
|||
|
||||
#ifdef __LINUX__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sys/socket.h>
|
||||
#include <vector>
|
||||
// #include <linux/if.h>
|
||||
|
||||
#include "../node/Hashtable.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "../node/Hashtable.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
|
||||
#include "Thread.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Interface with Linux's RTNETLINK
|
||||
*/
|
||||
class LinuxNetLink
|
||||
{
|
||||
class LinuxNetLink {
|
||||
private:
|
||||
LinuxNetLink();
|
||||
~LinuxNetLink();
|
||||
|
@ -54,20 +50,27 @@ public:
|
|||
int ifidx;
|
||||
|
||||
inline bool operator==(const Route& r) const
|
||||
{ return ((target == r.target)&&(via == r.via)&&(src == r.src)&&(ifidx == r.ifidx)); }
|
||||
{
|
||||
return ((target == r.target) && (via == r.via) && (src == r.src) && (ifidx == r.ifidx));
|
||||
}
|
||||
inline bool operator!=(const Route& r) const
|
||||
{ return (!(*this == r)); }
|
||||
{
|
||||
return (! (*this == r));
|
||||
}
|
||||
inline bool operator<(const Route& r) const
|
||||
{
|
||||
if (target < r.target) {
|
||||
return true;
|
||||
} else if (target == r.target) {
|
||||
}
|
||||
else if (target == r.target) {
|
||||
if (via < r.via) {
|
||||
return true;
|
||||
} else if (via == r.via) {
|
||||
}
|
||||
else if (via == r.via) {
|
||||
if (src < r.src) {
|
||||
return true;
|
||||
} else if (src == r.src) {
|
||||
}
|
||||
else if (src == r.src) {
|
||||
return (ifidx < r.ifidx);
|
||||
}
|
||||
}
|
||||
|
@ -75,11 +78,17 @@ public:
|
|||
return false;
|
||||
}
|
||||
inline bool operator>(const Route& r) const
|
||||
{ return (r < *this); }
|
||||
{
|
||||
return (r < *this);
|
||||
}
|
||||
inline bool operator<=(const Route& r) const
|
||||
{ return !(r < *this); }
|
||||
{
|
||||
return ! (r < *this);
|
||||
}
|
||||
inline bool operator>=(const Route& r) const
|
||||
{ return !(*this < r); }
|
||||
{
|
||||
return ! (*this < r);
|
||||
}
|
||||
};
|
||||
|
||||
static LinuxNetLink& getInstance()
|
||||
|
@ -130,7 +139,9 @@ private:
|
|||
|
||||
struct iface_entry {
|
||||
iface_entry()
|
||||
{ memset(this,0,sizeof(iface_entry)); }
|
||||
{
|
||||
memset(this, 0, sizeof(iface_entry));
|
||||
}
|
||||
int index;
|
||||
char ifacename[16]; // IFNAMSIZ on Linux == 16
|
||||
char mac[18];
|
||||
|
@ -145,7 +156,7 @@ private:
|
|||
struct sockaddr_nl _la;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef MAC_DNS_HELPER
|
||||
#define MAC_DNS_HELPER
|
||||
|
||||
#include <vector>
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class MacDNSHelper
|
||||
{
|
||||
class MacDNSHelper {
|
||||
public:
|
||||
static void setDNS(uint64_t nwid, const char* domain, const std::vector<InetAddress>& servers);
|
||||
static void removeDNS(uint64_t nwid);
|
||||
|
@ -18,6 +18,6 @@ public:
|
|||
static bool removeIps6(uint64_t nwid);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,47 +15,43 @@
|
|||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Dictionary.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "MacDNSHelper.hpp"
|
||||
#include "MacEthernetTap.hpp"
|
||||
#include "MacEthernetTapAgent.h"
|
||||
#include "MacDNSHelper.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
#include <ifaddrs.h>
|
||||
#include <map>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <set>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0);
|
||||
|
||||
|
@ -75,23 +71,23 @@ MacEthernetTap::MacEthernetTap(
|
|||
uint64_t nwid,
|
||||
const char* friendlyName,
|
||||
void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void* data, unsigned int len),
|
||||
void *arg) :
|
||||
_handler(handler),
|
||||
_arg(arg),
|
||||
_nwid(nwid),
|
||||
_homePath(homePath),
|
||||
_mtu(mtu),
|
||||
_metric(metric),
|
||||
_devNo(0),
|
||||
_agentStdin(-1),
|
||||
_agentStdout(-1),
|
||||
_agentStderr(-1),
|
||||
_agentStdin2(-1),
|
||||
_agentStdout2(-1),
|
||||
_agentStderr2(-1),
|
||||
_agentPid(-1),
|
||||
_enabled(true),
|
||||
_lastIfAddrsUpdate(0)
|
||||
void* arg)
|
||||
: _handler(handler)
|
||||
, _arg(arg)
|
||||
, _nwid(nwid)
|
||||
, _homePath(homePath)
|
||||
, _mtu(mtu)
|
||||
, _metric(metric)
|
||||
, _devNo(0)
|
||||
, _agentStdin(-1)
|
||||
, _agentStdout(-1)
|
||||
, _agentStderr(-1)
|
||||
, _agentStdin2(-1)
|
||||
, _agentStdout2(-1)
|
||||
, _agentStderr2(-1)
|
||||
, _agentPid(-1)
|
||||
, _enabled(true)
|
||||
, _lastIfAddrsUpdate(0)
|
||||
{
|
||||
char ethaddr[64], mtustr[16], devnostr[16], devstr[16], metricstr[16];
|
||||
OSUtils::ztsnprintf(ethaddr, sizeof(ethaddr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3], (int)mac[4], (int)mac[5]);
|
||||
|
@ -136,7 +132,8 @@ MacEthernetTap::MacEthernetTap(
|
|||
if (pid == 0) {
|
||||
execv(args[0], const_cast<char**>(args));
|
||||
_exit(-1);
|
||||
} else if (pid > 0) {
|
||||
}
|
||||
else if (pid > 0) {
|
||||
int rv = 0;
|
||||
waitpid(pid, &rv, 0);
|
||||
}
|
||||
|
@ -168,7 +165,8 @@ MacEthernetTap::MacEthernetTap(
|
|||
devNo = (devNo + 1) % 5000;
|
||||
if (devNo < 100)
|
||||
devNo = 100;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_dev = devstr;
|
||||
_devNo = devNo;
|
||||
break;
|
||||
|
@ -196,7 +194,8 @@ MacEthernetTap::MacEthernetTap(
|
|||
long apid = (long)fork();
|
||||
if (apid < 0) {
|
||||
throw std::runtime_error("fork failed");
|
||||
} else if (apid == 0) {
|
||||
}
|
||||
else if (apid == 0) {
|
||||
::dup2(agentStdin[0], STDIN_FILENO);
|
||||
::dup2(agentStdout[1], STDOUT_FILENO);
|
||||
::dup2(agentStderr[1], STDERR_FILENO);
|
||||
|
@ -208,7 +207,8 @@ MacEthernetTap::MacEthernetTap(
|
|||
::close(agentStderr[1]);
|
||||
::execl(agentPath.c_str(), agentPath.c_str(), devnostr, ethaddr, mtustr, metricstr, (char*)0);
|
||||
::_exit(-1);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_agentPid = apid;
|
||||
|
||||
// Wait up to 10 seconds for the subprocess to actually create the device. This prevents
|
||||
|
@ -228,7 +228,8 @@ MacEthernetTap::MacEthernetTap(
|
|||
}
|
||||
if (waitLoops == -1) {
|
||||
break;
|
||||
} else if (waitLoops >= 100) { // 10 seconds
|
||||
}
|
||||
else if (waitLoops >= 100) { // 10 seconds
|
||||
throw std::runtime_error("feth device creation timed out");
|
||||
}
|
||||
Thread::sleep(100);
|
||||
|
@ -288,8 +289,14 @@ MacEthernetTap::~MacEthernetTap()
|
|||
Thread::join(_thread);
|
||||
}
|
||||
|
||||
void MacEthernetTap::setEnabled(bool en) { _enabled = en; }
|
||||
bool MacEthernetTap::enabled() const { return _enabled; }
|
||||
void MacEthernetTap::setEnabled(bool en)
|
||||
{
|
||||
_enabled = en;
|
||||
}
|
||||
bool MacEthernetTap::enabled() const
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
bool MacEthernetTap::addIp(const InetAddress& ip)
|
||||
{
|
||||
|
@ -408,8 +415,13 @@ void MacEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,co
|
|||
}
|
||||
}
|
||||
|
||||
std::string MacEthernetTap::deviceName() const { return _dev; }
|
||||
void MacEthernetTap::setFriendlyName(const char *friendlyName) {}
|
||||
std::string MacEthernetTap::deviceName() const
|
||||
{
|
||||
return _dev;
|
||||
}
|
||||
void MacEthernetTap::setFriendlyName(const char* friendlyName)
|
||||
{
|
||||
}
|
||||
|
||||
void MacEthernetTap::scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed)
|
||||
{
|
||||
|
@ -471,8 +483,7 @@ void MacEthernetTap::setMtu(unsigned int mtu)
|
|||
|
||||
#define ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE 131072
|
||||
|
||||
void MacEthernetTap::threadMain()
|
||||
throw()
|
||||
void MacEthernetTap::threadMain() throw()
|
||||
{
|
||||
char agentReadBuf[ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE];
|
||||
char agentStderrBuf[256];
|
||||
|
@ -514,10 +525,12 @@ void MacEthernetTap::threadMain()
|
|||
|
||||
if (agentReadPtr > (len + 2)) {
|
||||
memmove(agentReadBuf, agentReadBuf + len + 2, agentReadPtr -= (len + 2));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
agentReadPtr = 0;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,24 +15,22 @@
|
|||
#define ZT_OSXETHERNETTAP_HPP
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Thread.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class MacEthernetTap : public EthernetTap
|
||||
{
|
||||
class MacEthernetTap : public EthernetTap {
|
||||
public:
|
||||
MacEthernetTap(
|
||||
const char* homePath,
|
||||
|
@ -58,8 +56,7 @@ public:
|
|||
virtual void setMtu(unsigned int mtu);
|
||||
virtual void setDns(const char* domain, const std::vector<InetAddress>& servers);
|
||||
|
||||
void threadMain()
|
||||
throw();
|
||||
void threadMain() throw();
|
||||
|
||||
private:
|
||||
void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int);
|
||||
|
@ -79,7 +76,6 @@ private:
|
|||
volatile bool _enabled;
|
||||
mutable std::vector<InetAddress> _ifaddrs;
|
||||
mutable uint64_t _lastIfAddrsUpdate;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -11,39 +11,36 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "MacDNSHelper.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/route.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include "MacDNSHelper.hpp"
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// OSX compile fix... in6_var defines this in a struct which namespaces it for C++ ... why?!?
|
||||
struct prf_ra {
|
||||
|
@ -52,8 +49,8 @@ struct prf_ra {
|
|||
u_char reserved : 6;
|
||||
} prf_ra;
|
||||
|
||||
#include <netinet6/nd6.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
// These are KERNEL_PRIVATE... why?
|
||||
#ifndef SIOCAUTOCONF_START
|
||||
|
@ -70,8 +67,7 @@ struct prf_ra {
|
|||
// It's here because OSX 10.6 does not have this convenience function.
|
||||
|
||||
#define SALIGN (sizeof(uint32_t) - 1)
|
||||
#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \
|
||||
(SALIGN + 1))
|
||||
#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
|
||||
#define MAX_SYSCTL_TRY 5
|
||||
#define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA)
|
||||
|
||||
|
@ -146,8 +142,7 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif)
|
|||
icnt++;
|
||||
p = (char*)(ifmam + 1);
|
||||
for (i = 0; i < RTAX_MAX; i++) {
|
||||
if ((RTA_MASKS & ifmam->ifmam_addrs &
|
||||
(1 << i)) == 0)
|
||||
if ((RTA_MASKS & ifmam->ifmam_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
sa = (struct sockaddr*)(void*)p;
|
||||
len = SA_RLEN(sa);
|
||||
|
@ -183,29 +178,25 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif)
|
|||
|
||||
p = (char*)(ifmam + 1);
|
||||
for (i = 0; i < RTAX_MAX; i++) {
|
||||
if ((RTA_MASKS & ifmam->ifmam_addrs &
|
||||
(1 << i)) == 0)
|
||||
if ((RTA_MASKS & ifmam->ifmam_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
sa = (struct sockaddr*)(void*)p;
|
||||
len = SA_RLEN(sa);
|
||||
switch (i) {
|
||||
case RTAX_GATEWAY:
|
||||
ift->ifma_lladdr =
|
||||
(struct sockaddr *)(void *)data;
|
||||
ift->ifma_lladdr = (struct sockaddr*)(void*)data;
|
||||
memcpy(data, p, len);
|
||||
data += len;
|
||||
break;
|
||||
|
||||
case RTAX_IFP:
|
||||
ift->ifma_name =
|
||||
(struct sockaddr *)(void *)data;
|
||||
ift->ifma_name = (struct sockaddr*)(void*)data;
|
||||
memcpy(data, p, len);
|
||||
data += len;
|
||||
break;
|
||||
|
||||
case RTAX_IFA:
|
||||
ift->ifma_addr =
|
||||
(struct sockaddr *)(void *)data;
|
||||
ift->ifma_addr = (struct sockaddr*)(void*)data;
|
||||
memcpy(data, p, len);
|
||||
data += len;
|
||||
break;
|
||||
|
@ -228,7 +219,8 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif)
|
|||
ift--;
|
||||
ift->ifma_next = NULL;
|
||||
*pif = ifa;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*pif = NULL;
|
||||
free(ifa);
|
||||
}
|
||||
|
@ -243,17 +235,17 @@ static inline void _intl_freeifmaddrs(struct _intl_ifmaddrs *ifmp)
|
|||
// --------------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <string>
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Dictionary.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "MacKextEthernetTap.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Dictionary.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "MacKextEthernetTap.hpp"
|
||||
#include <string>
|
||||
|
||||
// ff:ff:ff:ff:ff:ff with no ADI
|
||||
static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0);
|
||||
|
@ -279,7 +271,8 @@ static inline bool _setIpv6Stuff(const char *ifname,bool performNUD,bool acceptR
|
|||
|
||||
if (performNUD)
|
||||
nd.ndi.flags |= ND6_IFF_PERFORMNUD;
|
||||
else nd.ndi.flags &= ~ND6_IFF_PERFORMNUD;
|
||||
else
|
||||
nd.ndi.flags &= ~ND6_IFF_PERFORMNUD;
|
||||
|
||||
if (oldFlags != (unsigned long)nd.ndi.flags) {
|
||||
if (ioctl(s, SIOCSIFINFO_FLAGS, &nd)) {
|
||||
|
@ -312,15 +305,15 @@ MacKextEthernetTap::MacKextEthernetTap(
|
|||
uint64_t nwid,
|
||||
const char* friendlyName,
|
||||
void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void* data, unsigned int len),
|
||||
void *arg) :
|
||||
_handler(handler),
|
||||
_arg(arg),
|
||||
_nwid(nwid),
|
||||
_homePath(homePath),
|
||||
_mtu(mtu),
|
||||
_metric(metric),
|
||||
_fd(0),
|
||||
_enabled(true)
|
||||
void* arg)
|
||||
: _handler(handler)
|
||||
, _arg(arg)
|
||||
, _nwid(nwid)
|
||||
, _homePath(homePath)
|
||||
, _mtu(mtu)
|
||||
, _metric(metric)
|
||||
, _fd(0)
|
||||
, _enabled(true)
|
||||
{
|
||||
char devpath[64], ethaddr[64], mtustr[32], metstr[32], nwids[32];
|
||||
struct stat stattmp;
|
||||
|
@ -336,7 +329,8 @@ MacKextEthernetTap::MacKextEthernetTap(
|
|||
OSUtils::redirectUnixOutputs("/dev/null", (const char*)0);
|
||||
::execl("/sbin/kextload", "/sbin/kextload", "-q", "-repository", homePath, "tap.kext", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (kextpid > 0) {
|
||||
}
|
||||
else if (kextpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(kextpid, &exitcode, 0);
|
||||
}
|
||||
|
@ -355,9 +349,12 @@ MacKextEthernetTap::MacKextEthernetTap(
|
|||
char* y = (char*)0;
|
||||
char* saveptr = (char*)0;
|
||||
for (char* f = Utils::stok(buf, "\r\n=", &saveptr); (f); f = Utils::stok((char*)0, "\r\n=", &saveptr)) {
|
||||
if (!x) x = f;
|
||||
else if (!y) y = f;
|
||||
else break;
|
||||
if (! x)
|
||||
x = f;
|
||||
else if (! y)
|
||||
y = f;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((x) && (y) && (x[0]) && (y[0]))
|
||||
globalDeviceMap[x] = y;
|
||||
|
@ -367,7 +364,8 @@ MacKextEthernetTap::MacKextEthernetTap(
|
|||
bool recalledDevice = false;
|
||||
std::map<std::string, std::string>::const_iterator gdmEntry = globalDeviceMap.find(nwids);
|
||||
if (gdmEntry != globalDeviceMap.end()) {
|
||||
std::string devpath("/dev/"); devpath.append(gdmEntry->second);
|
||||
std::string devpath("/dev/");
|
||||
devpath.append(gdmEntry->second);
|
||||
if (stat(devpath.c_str(), &stattmp) == 0) {
|
||||
_fd = ::open(devpath.c_str(), O_RDWR);
|
||||
if (_fd > 0) {
|
||||
|
@ -409,7 +407,8 @@ MacKextEthernetTap::MacKextEthernetTap(
|
|||
if (cpid == 0) {
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "lladdr", ethaddr, "mtu", mtustr, "metric", metstr, "up", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
if (exitcode) {
|
||||
|
@ -466,7 +465,8 @@ MacKextEthernetTap::~MacKextEthernetTap()
|
|||
OSUtils::redirectUnixOutputs("/dev/null", (const char*)0);
|
||||
::execl("/sbin/kextunload", "/sbin/kextunload", tmp, (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (kextpid > 0) {
|
||||
}
|
||||
else if (kextpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(kextpid, &exitcode, 0);
|
||||
}
|
||||
|
@ -495,7 +495,8 @@ bool MacKextEthernetTap::addIp(const InetAddress &ip)
|
|||
char tmp[128];
|
||||
::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), (ip.ss_family == AF_INET6) ? "inet6" : "inet", ip.toString(tmp), "alias", (const char*)0);
|
||||
::_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(cpid, &exitcode, 0);
|
||||
return (exitcode == 0);
|
||||
|
@ -516,7 +517,8 @@ bool MacKextEthernetTap::removeIp(const InetAddress &ip)
|
|||
char tmp[128];
|
||||
execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), (ip.ss_family == AF_INET6) ? "inet6" : "inet", ip.toIpString(tmp), "-alias", (const char*)0);
|
||||
_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
waitpid(cpid, &exitcode, 0);
|
||||
return (exitcode == 0);
|
||||
|
@ -634,15 +636,15 @@ void MacKextEthernetTap::setMtu(unsigned int mtu)
|
|||
OSUtils::ztsnprintf(tmp, sizeof(tmp), "%u", mtu);
|
||||
execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "mtu", tmp, (const char*)0);
|
||||
_exit(-1);
|
||||
} else if (cpid > 0) {
|
||||
}
|
||||
else if (cpid > 0) {
|
||||
int exitcode = -1;
|
||||
waitpid(cpid, &exitcode, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacKextEthernetTap::threadMain()
|
||||
throw()
|
||||
void MacKextEthernetTap::threadMain() throw()
|
||||
{
|
||||
fd_set readfds, nullfds;
|
||||
MAC to, from;
|
||||
|
@ -669,7 +671,8 @@ void MacKextEthernetTap::threadMain()
|
|||
if (n < 0) {
|
||||
if ((errno != EINTR) && (errno != ETIMEDOUT))
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Some tap drivers like to send the ethernet frame and the
|
||||
// payload in two chunks, so handle that by accumulating
|
||||
// data until we have at least a frame.
|
||||
|
|
|
@ -14,26 +14,23 @@
|
|||
#ifndef ZT_MacKextEthernetTap_HPP
|
||||
#define ZT_MacKextEthernetTap_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
#include "Thread.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
|
||||
#include "Thread.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class MacKextEthernetTap : public EthernetTap
|
||||
{
|
||||
class MacKextEthernetTap : public EthernetTap {
|
||||
public:
|
||||
MacKextEthernetTap(
|
||||
const char* homePath,
|
||||
|
@ -59,9 +56,7 @@ public:
|
|||
virtual void setMtu(unsigned int mtu);
|
||||
virtual void setDns(const char* domain, const std::vector<InetAddress>& servers);
|
||||
|
||||
|
||||
void threadMain()
|
||||
throw();
|
||||
void threadMain() throw();
|
||||
|
||||
private:
|
||||
void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int);
|
||||
|
|
|
@ -20,20 +20,20 @@
|
|||
#include <string.h>
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <netioapi.h>
|
||||
#include <IPHlpApi.h>
|
||||
#include <netioapi.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef __UNIX_LIKE__
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#ifndef ZT_SDK
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
|
@ -45,11 +45,11 @@
|
|||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include "ManagedRoute.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "ManagedRoute.hpp"
|
||||
#include <vector>
|
||||
#ifdef __LINUX__
|
||||
#include "LinuxNetLink.hpp"
|
||||
#endif
|
||||
|
@ -72,24 +72,26 @@ static void _forkTarget(const InetAddress &t,InetAddress &left,InetAddress &righ
|
|||
right = t;
|
||||
reinterpret_cast<struct sockaddr_in*>(&right)->sin_addr.s_addr ^= Utils::hton((uint32_t)(1 << (32 - bits)));
|
||||
right.setPort(bits);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
right.zero();
|
||||
}
|
||||
} else if (t.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (t.ss_family == AF_INET6) {
|
||||
if (bits <= 128) {
|
||||
left.setPort(bits);
|
||||
right = t;
|
||||
uint8_t* b = reinterpret_cast<uint8_t*>(reinterpret_cast<struct sockaddr_in6*>(&right)->sin6_addr.s6_addr);
|
||||
b[bits / 8] ^= 1 << (8 - (bits % 8));
|
||||
right.setPort(bits);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
right.zero();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct _RTE
|
||||
{
|
||||
struct _RTE {
|
||||
InetAddress target;
|
||||
InetAddress via;
|
||||
char device[128];
|
||||
|
@ -167,7 +169,8 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
|||
#ifdef __APPLE__
|
||||
isDefault = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && ! (rtm->rtm_flags & RTF_IFSCOPE);
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in* sin4 = (struct sockaddr_in*)sa;
|
||||
isDefault = sin4->sin_addr.s_addr == 0;
|
||||
}
|
||||
|
@ -193,10 +196,12 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
|||
unsigned char c = (unsigned char)((const struct sockaddr_in6*)sa)->sin6_addr.s6_addr[i];
|
||||
if (c == 0xff)
|
||||
bits += 8;
|
||||
else break;
|
||||
else
|
||||
break;
|
||||
}
|
||||
sa_t.setPort(bits);
|
||||
} else if (sa_t.ss_family == AF_INET) {
|
||||
}
|
||||
else if (sa_t.ss_family == AF_INET) {
|
||||
salen = sizeof(struct sockaddr_in);
|
||||
sa_t.setPort((unsigned int)Utils::countBits((uint32_t)((const struct sockaddr_in*)sa)->sin_addr.s_addr));
|
||||
}
|
||||
|
@ -220,10 +225,8 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
|||
saptr += salen;
|
||||
}
|
||||
|
||||
|
||||
deviceIndex = rtm->rtm_index;
|
||||
|
||||
|
||||
if (((contains) && (sa_t.containsAddress(target))) || (sa_t == target)) {
|
||||
rtes.push_back(_RTE());
|
||||
rtes.back().target = sa_t;
|
||||
|
@ -231,7 +234,8 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
|||
rtes.back().isDefault = isDefault;
|
||||
if (deviceIndex >= 0) {
|
||||
if_indextoname(deviceIndex, rtes.back().device);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rtes.back().device[0] = (char)0;
|
||||
}
|
||||
rtes.back().metric = ((int)rtm->rtm_rmx.rmx_hopcount < 0) ? 0 : (int)rtm->rtm_rmx.rmx_hopcount;
|
||||
|
@ -257,7 +261,8 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
|
|||
if (p > 0) {
|
||||
int exitcode = -1;
|
||||
::waitpid(p, &exitcode, 0);
|
||||
} else if (p == 0) {
|
||||
}
|
||||
else if (p == 0) {
|
||||
::close(STDOUT_FILENO);
|
||||
::close(STDERR_FILENO);
|
||||
char ttmp[64];
|
||||
|
@ -268,19 +273,22 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
|
|||
fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s" ZT_EOL_S, ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp));
|
||||
#endif
|
||||
::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, "-ifscope", ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp), (const char*)0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
#ifdef ZT_TRACE
|
||||
fprintf(stderr, "DEBUG: route %s %s %s %s" ZT_EOL_S, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp));
|
||||
#endif
|
||||
::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp), (const char*)0);
|
||||
}
|
||||
} else if ((localInterface)&&(localInterface[0])) {
|
||||
}
|
||||
else if ((localInterface) && (localInterface[0])) {
|
||||
if ((ifscope) && (ifscope[0])) {
|
||||
#ifdef ZT_TRACE
|
||||
fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s -interface %s" ZT_EOL_S, op, ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), localInterface);
|
||||
#endif
|
||||
::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, "-ifscope", ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), "-interface", localInterface, (const char*)0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
#ifdef ZT_TRACE
|
||||
fprintf(stderr, "DEBUG: route %s %s %s -interface %s" ZT_EOL_S, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), localInterface);
|
||||
#endif
|
||||
|
@ -318,7 +326,8 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &
|
|||
rtrow.NextHop.Ipv4.sin_family = AF_INET;
|
||||
rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast<const struct sockaddr_in*>(&via)->sin_addr.S_un.S_addr;
|
||||
}
|
||||
} else if (target.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (target.ss_family == AF_INET6) {
|
||||
rtrow.DestinationPrefix.Prefix.si_family = AF_INET6;
|
||||
rtrow.DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6;
|
||||
memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte, reinterpret_cast<const struct sockaddr_in6*>(&target)->sin6_addr.u.Byte, 16);
|
||||
|
@ -327,7 +336,8 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &
|
|||
rtrow.NextHop.Ipv6.sin6_family = AF_INET6;
|
||||
memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte, reinterpret_cast<const struct sockaddr_in6*>(&via)->sin6_addr.u.Byte, 16);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
rtrow.DestinationPrefix.PrefixLength = target.netmaskBits();
|
||||
|
@ -344,13 +354,16 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &
|
|||
rtrow.Origin = NlroManual;
|
||||
if (del) {
|
||||
return (DeleteIpForwardEntry2(&rtrow) == NO_ERROR);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
NTSTATUS r = CreateIpForwardEntry2(&rtrow);
|
||||
if (r == NO_ERROR) {
|
||||
return true;
|
||||
} else if (r == ERROR_OBJECT_ALREADY_EXISTS) {
|
||||
}
|
||||
else if (r == ERROR_OBJECT_ALREADY_EXISTS) {
|
||||
return (SetIpForwardEntry2(&rtrow) == NO_ERROR);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +384,8 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter
|
|||
rtrow.NextHop.Ipv4.sin_family = AF_INET;
|
||||
rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast<const struct sockaddr_in*>(&via)->sin_addr.S_un.S_addr;
|
||||
}
|
||||
} else if (target.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (target.ss_family == AF_INET6) {
|
||||
rtrow.DestinationPrefix.Prefix.si_family = AF_INET6;
|
||||
rtrow.DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6;
|
||||
memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte, reinterpret_cast<const struct sockaddr_in6*>(&target)->sin6_addr.u.Byte, 16);
|
||||
|
@ -380,7 +394,8 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter
|
|||
rtrow.NextHop.Ipv6.sin6_family = AF_INET6;
|
||||
memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte, reinterpret_cast<const struct sockaddr_in6*>(&via)->sin6_addr.u.Byte, 16);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
rtrow.DestinationPrefix.PrefixLength = target.netmaskBits();
|
||||
|
@ -391,7 +406,8 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter
|
|||
#endif // __WINDOWS__ --------------------------------------------------------
|
||||
|
||||
#ifndef ZT_ROUTING_SUPPORT_FOUND
|
||||
#error "ManagedRoute.cpp has no support for managing routes on this platform! You'll need to check and see if one of the existing ones will work and make sure proper defines are set, or write one. Please do a GitHub pull request if you do this for a new OS."
|
||||
#error \
|
||||
"ManagedRoute.cpp has no support for managing routes on this platform! You'll need to check and see if one of the existing ones will work and make sure proper defines are set, or write one. Please do a GitHub pull request if you do this for a new OS."
|
||||
#endif
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -404,13 +420,15 @@ ManagedRoute::ManagedRoute(const InetAddress &target,const InetAddress &via,cons
|
|||
|
||||
if (_via.ss_family == AF_INET) {
|
||||
_via.setPort(32);
|
||||
} else if (_via.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (_via.ss_family == AF_INET6) {
|
||||
_via.setPort(128);
|
||||
}
|
||||
|
||||
if (_src.ss_family == AF_INET) {
|
||||
_src.setPort(32);
|
||||
} else if (_src.ss_family == AF_INET6) {
|
||||
}
|
||||
else if (_src.ss_family == AF_INET6) {
|
||||
_src.setPort(128);
|
||||
}
|
||||
|
||||
|
@ -449,7 +467,8 @@ bool ManagedRoute::sync()
|
|||
InetAddress leftt, rightt;
|
||||
if (_target.netmaskBits() == 0) // bifurcate only the default route
|
||||
_forkTarget(_target, leftt, rightt);
|
||||
else leftt = _target;
|
||||
else
|
||||
leftt = _target;
|
||||
|
||||
#ifdef __BSD__ // ------------------------------------------------------------
|
||||
|
||||
|
@ -476,13 +495,14 @@ bool ManagedRoute::sync()
|
|||
bool hasRoute = false;
|
||||
for (std::vector<_RTE>::iterator r(rtes.begin()); r != rtes.end(); ++r) {
|
||||
hasRoute = _target == r->target && _via.ipOnly() == r->via.ipOnly() && (strcmp(r->device, _device) == 0);
|
||||
if (hasRoute) { break; }
|
||||
if (hasRoute) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// char buf[255];
|
||||
// fprintf(stderr, "hasRoute %d %s\n", !!hasRoute, _target.toString(buf));
|
||||
|
||||
|
||||
if (! hasRoute) {
|
||||
if (_target && _target.netmaskBits() == 0) { // Allow Default
|
||||
InetAddress newSystemVia;
|
||||
|
@ -506,7 +526,6 @@ bool ManagedRoute::sync()
|
|||
for (std::vector<_RTE>::iterator r(rtes.begin()); r != rtes.end(); ++r) {
|
||||
if (r->via) {
|
||||
if (r->isDefault == 1 && (strcmp(r->device, _device) != 0)) {
|
||||
|
||||
// char buf[255];
|
||||
// fprintf(stderr, "system device1 %s %s\n", r->via.toString(buf), r->device);
|
||||
|
||||
|
@ -517,7 +536,9 @@ bool ManagedRoute::sync()
|
|||
}
|
||||
}
|
||||
|
||||
if (newSystemVia) { _systemVia = newSystemVia; }
|
||||
if (newSystemVia) {
|
||||
_systemVia = newSystemVia;
|
||||
}
|
||||
if (newSystemDevice[0]) {
|
||||
Utils::scopy(_systemDevice, sizeof(_systemDevice), newSystemDevice);
|
||||
}
|
||||
|
@ -537,15 +558,14 @@ bool ManagedRoute::sync()
|
|||
}
|
||||
|
||||
_applied[_target] = true;
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Do Non-Default route commands
|
||||
_applied[_target] = true;
|
||||
_routeCmd("add", leftt, _via, (const char*)0, (_via) ? (const char*)0 : _device);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // __BSD__ ------------------------------------------------------------
|
||||
|
||||
#ifdef __LINUX__ // ----------------------------------------------------------
|
||||
|
@ -599,9 +619,9 @@ void ManagedRoute::remove()
|
|||
_routeCmd("delete", _target, _systemVia, _systemDevice, (const char*)0);
|
||||
|
||||
_routeCmd("add", _target, _systemVia, (const char*)0, (const char*)0);
|
||||
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
_routeCmd("delete", _target, _via, (const char*)0, _via ? (const char*)0 : _device);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -14,25 +14,23 @@
|
|||
#ifndef ZT_MANAGEDROUTE_HPP
|
||||
#define ZT_MANAGEDROUTE_HPP
|
||||
|
||||
#include "../node/AtomicCounter.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/SharedPtr.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/SharedPtr.hpp"
|
||||
#include "../node/AtomicCounter.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A ZT-managed route that used C++ RAII semantics to automatically clean itself up on deallocate
|
||||
*/
|
||||
class ManagedRoute
|
||||
{
|
||||
class ManagedRoute {
|
||||
friend class SharedPtr<ManagedRoute>;
|
||||
|
||||
public:
|
||||
|
@ -58,14 +56,31 @@ public:
|
|||
*/
|
||||
void remove();
|
||||
|
||||
inline const InetAddress &target() const { return _target; }
|
||||
inline const InetAddress &via() const { return _via; }
|
||||
inline const InetAddress &src() const { return _src; }
|
||||
inline const char *device() const { return _device; }
|
||||
inline const InetAddress& target() const
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
inline const InetAddress& via() const
|
||||
{
|
||||
return _via;
|
||||
}
|
||||
inline const InetAddress& src() const
|
||||
{
|
||||
return _src;
|
||||
}
|
||||
inline const char* device() const
|
||||
{
|
||||
return _device;
|
||||
}
|
||||
|
||||
private:
|
||||
ManagedRoute(const ManagedRoute &) {}
|
||||
inline ManagedRoute &operator=(const ManagedRoute &) { return *this; }
|
||||
ManagedRoute(const ManagedRoute&)
|
||||
{
|
||||
}
|
||||
inline ManagedRoute& operator=(const ManagedRoute&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
InetAddress _target;
|
||||
InetAddress _via;
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
/****/
|
||||
|
||||
#include "NeighborDiscovery.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -59,9 +59,7 @@ struct _pseudo_header {
|
|||
};
|
||||
|
||||
struct _option {
|
||||
_option(int optionType)
|
||||
: type(optionType)
|
||||
, length(8)
|
||||
_option(int optionType) : type(optionType), length(8)
|
||||
{
|
||||
memset(mac, 0, sizeof(mac));
|
||||
}
|
||||
|
@ -72,17 +70,14 @@ struct _option {
|
|||
};
|
||||
|
||||
struct _neighbor_solicitation {
|
||||
_neighbor_solicitation()
|
||||
: type(135)
|
||||
, code(0)
|
||||
, checksum(0)
|
||||
, option(1)
|
||||
_neighbor_solicitation() : type(135), code(0), checksum(0), option(1)
|
||||
{
|
||||
memset(&reserved, 0, sizeof(reserved));
|
||||
memset(target, 0, sizeof(target));
|
||||
}
|
||||
|
||||
void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp) {
|
||||
void calculateChecksum(const sockaddr_storage& sourceIp, const sockaddr_storage& destIp)
|
||||
{
|
||||
_pseudo_header ph;
|
||||
memset(&ph, 0, sizeof(_pseudo_header));
|
||||
const sockaddr_in6* src = (const sockaddr_in6*)&sourceIp;
|
||||
|
@ -113,18 +108,14 @@ struct _neighbor_solicitation {
|
|||
};
|
||||
|
||||
struct _neighbor_advertisement {
|
||||
_neighbor_advertisement()
|
||||
: type(136)
|
||||
, code(0)
|
||||
, checksum(0)
|
||||
, rso(0x40)
|
||||
, option(2)
|
||||
_neighbor_advertisement() : type(136), code(0), checksum(0), rso(0x40), option(2)
|
||||
{
|
||||
memset(padding, 0, sizeof(padding));
|
||||
memset(target, 0, sizeof(target));
|
||||
}
|
||||
|
||||
void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp) {
|
||||
void calculateChecksum(const sockaddr_storage& sourceIp, const sockaddr_storage& destIp)
|
||||
{
|
||||
_pseudo_header ph;
|
||||
memset(&ph, 0, sizeof(_pseudo_header));
|
||||
const sockaddr_in6* src = (const sockaddr_in6*)&sourceIp;
|
||||
|
@ -155,10 +146,9 @@ struct _neighbor_advertisement {
|
|||
_option option;
|
||||
};
|
||||
|
||||
NeighborDiscovery::NeighborDiscovery()
|
||||
: _cache(256)
|
||||
, _lastCleaned(OSUtils::now())
|
||||
{}
|
||||
NeighborDiscovery::NeighborDiscovery() : _cache(256), _lastCleaned(OSUtils::now())
|
||||
{
|
||||
}
|
||||
|
||||
void NeighborDiscovery::addLocal(const sockaddr_storage& address, const MAC& mac)
|
||||
{
|
||||
|
@ -197,7 +187,8 @@ sockaddr_storage NeighborDiscovery::processIncomingND(const uint8_t *nd, unsigne
|
|||
responseLen = sizeof(_neighbor_advertisement);
|
||||
responseDest.setTo(solicitation.option.mac, 6);
|
||||
}
|
||||
} else if (len >= sizeof(_neighbor_advertisement) && nd[0] == 0x88) {
|
||||
}
|
||||
else if (len >= sizeof(_neighbor_advertisement) && nd[0] == 0x88) {
|
||||
_neighbor_advertisement adv;
|
||||
memcpy(&adv, nd, len);
|
||||
InetAddress responseAddress(adv.target, 16, 0);
|
||||
|
@ -235,8 +226,7 @@ MAC NeighborDiscovery::query(const MAC &localMac, const sockaddr_storage &localI
|
|||
|
||||
_NDEntry& e = _cache[targetAddress];
|
||||
|
||||
if ( (e.mac && ((now - e.lastResponseReceived) >= (ZT_ND_EXPIRE / 3))) ||
|
||||
(!e.mac && ((now - e.lastQuerySent) >= ZT_ND_QUERY_INTERVAL))) {
|
||||
if ((e.mac && ((now - e.lastResponseReceived) >= (ZT_ND_EXPIRE / 3))) || (! e.mac && ((now - e.lastQuerySent) >= ZT_ND_QUERY_INTERVAL))) {
|
||||
e.lastQuerySent = now;
|
||||
|
||||
_neighbor_solicitation ns;
|
||||
|
@ -245,10 +235,12 @@ MAC NeighborDiscovery::query(const MAC &localMac, const sockaddr_storage &localI
|
|||
ns.calculateChecksum(localIp, targetIp);
|
||||
if (e.mac) {
|
||||
queryDest = e.mac;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
queryDest = (uint64_t)0xffffffffffffULL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
queryLen = 0;
|
||||
queryDest.zero();
|
||||
}
|
||||
|
@ -256,4 +248,4 @@ MAC NeighborDiscovery::query(const MAC &localMac, const sockaddr_storage &localI
|
|||
return e.mac;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
#define ZT_NEIGHBORDISCOVERY_HPP
|
||||
|
||||
#include "../node/Hashtable.hpp"
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
|
||||
#include "../node/MAC.hpp"
|
||||
|
||||
#define ZT_ND_QUERY_INTERVAL 2000
|
||||
|
||||
|
@ -25,11 +24,9 @@
|
|||
|
||||
#define ZT_ND_EXPIRE 600000
|
||||
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class NeighborDiscovery
|
||||
{
|
||||
class NeighborDiscovery {
|
||||
public:
|
||||
NeighborDiscovery();
|
||||
|
||||
|
@ -53,9 +50,10 @@ public:
|
|||
MAC query(const MAC& localMac, const sockaddr_storage& localIp, const sockaddr_storage& targetIp, uint8_t* query, unsigned int& queryLen, MAC& queryDest);
|
||||
|
||||
private:
|
||||
struct _NDEntry
|
||||
struct _NDEntry {
|
||||
_NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false)
|
||||
{
|
||||
_NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false) {}
|
||||
}
|
||||
uint64_t lastQuerySent;
|
||||
uint64_t lastResponseReceived;
|
||||
MAC mac;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue