From df4b1e9b12fcd397ec23eb4f05870f08d703b4e8 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 7 Feb 2020 00:02:29 -0800 Subject: [PATCH] Yet more work on VL1/VL2 --- {node => attic}/RingBuffer.hpp | 0 include/ZeroTierCore.h | 9 +- node/CMakeLists.txt | 2 +- node/OS.hpp | 7 + node/Protocol.cpp | 74 +++--- node/Protocol.hpp | 40 +++- node/Trace.cpp | 7 - node/Utils.cpp | 1 + node/Utils.hpp | 5 + node/VL1.cpp | 418 ++++++++++++++++++--------------- node/VL1.hpp | 18 +- node/VL2.cpp | 67 ++++++ node/VL2.hpp | 24 +- 13 files changed, 422 insertions(+), 250 deletions(-) rename {node => attic}/RingBuffer.hpp (100%) create mode 100644 node/VL2.cpp diff --git a/node/RingBuffer.hpp b/attic/RingBuffer.hpp similarity index 100% rename from node/RingBuffer.hpp rename to attic/RingBuffer.hpp diff --git a/include/ZeroTierCore.h b/include/ZeroTierCore.h index 85bc402d0..002e52391 100644 --- a/include/ZeroTierCore.h +++ b/include/ZeroTierCore.h @@ -350,10 +350,11 @@ enum ZT_TracePacketDropReason ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD = 1, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET = 2, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED = 3, - ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED = 4, - ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT = 5, - ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA = 6, - ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB = 7 + ZT_TRACE_PACKET_DROP_REASON_NOT_TRUSTED_PATH = 4, + ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED = 5, + ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT = 6, + ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA = 7, + ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB = 8 }; /** diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index 6469c7619..ff2a72e93 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -33,7 +33,6 @@ set(core_headers Peer.hpp Poly1305.hpp Protocol.hpp - RingBuffer.hpp RuntimeEnvironment.hpp Salsa20.hpp ScopedPtr.hpp @@ -81,6 +80,7 @@ set(core_src Trace.cpp Utils.cpp VL1.cpp + VL2.cpp ) add_library(${PROJECT_NAME} STATIC ${core_src} ${core_headers}) diff --git a/node/OS.hpp b/node/OS.hpp index 49c87aa6f..85dada3ea 100644 --- a/node/OS.hpp +++ b/node/OS.hpp @@ -172,4 +172,11 @@ #define ZT_ALWAYS_INLINE inline #endif +// Macro to avoid calling hton() on values known at compile time. +#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))) +#else +#define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x)) +#endif + #endif diff --git a/node/Protocol.cpp b/node/Protocol.cpp index 7236eff10..e4606267c 100644 --- a/node/Protocol.cpp +++ b/node/Protocol.cpp @@ -66,53 +66,71 @@ uint64_t getPacketId() #endif } -#if 0 -void _armor(Buf< Header > &packet,const unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],const uint8_t cipherSuite) +void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite) { - packet.data.fields.flags = (packet.data.fields.flags & 0xc7U) | ((cipherSuite << 3U) & 0x38U); // FFCCCHHH - if (cipherSuite == ZT_PROTO_CIPHER_SUITE__AES_GCM) { - // TODO - } else if (cipherSuite != ZT_PROTO_CIPHER_SUITE__NONE) { - uint8_t mangledKey[ZT_PEER_SECRET_KEY_LENGTH],macKey[ZT_POLY1305_KEY_LEN]; - uint64_t mac[2]; + Protocol::Header &ph = pkt.as(); + ph.flags = (ph.flags & 0xc7U) | ((cipherSuite << 3U) & 0x38U); // flags: FFCCCHHH where CCC is cipher - _salsa20MangleKey(key,mangledKey,packet,packetSize); - Salsa20 s20(mangledKey,&(packet.data.fields.packetId)); - s20.crypt12(ZEROES32,macKey,sizeof(macKey)); + switch(cipherSuite) { + case ZT_PROTO_CIPHER_SUITE__POLY1305_NONE: { + uint8_t perPacketKey[ZT_PEER_SECRET_KEY_LENGTH]; + salsa2012DeriveKey(key,perPacketKey,pkt,packetSize); + Salsa20 s20(perPacketKey,&ph.packetId); - uint8_t *payload = packet.data.bytes + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START; - const unsigned int payloadLen = packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START; + uint8_t macKey[ZT_POLY1305_KEY_LEN]; + s20.crypt12(Utils::ZERO256,macKey,ZT_POLY1305_KEY_LEN); - if (cipherSuite == ZT_PROTO_CIPHER_SUITE__POLY1305_SALSA2012) - s20.crypt12(payload,payload,payloadLen); + // only difference here is that we don't encrypt the payload - poly1305(mac,payload,payloadLen,macKey); - packet.data.fields.mac = mac[0]; + uint64_t mac[2]; + poly1305(mac,pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,macKey); + ph.mac = mac[0]; + } break; + + case ZT_PROTO_CIPHER_SUITE__POLY1305_SALSA2012: { + uint8_t perPacketKey[ZT_PEER_SECRET_KEY_LENGTH]; + salsa2012DeriveKey(key,perPacketKey,pkt,packetSize); + Salsa20 s20(perPacketKey,&ph.packetId); + + uint8_t macKey[ZT_POLY1305_KEY_LEN]; + s20.crypt12(Utils::ZERO256,macKey,ZT_POLY1305_KEY_LEN); + + const unsigned int encLen = packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START; + s20.crypt12(pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,encLen); + + uint64_t mac[2]; + poly1305(mac,pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,encLen,macKey); + ph.mac = mac[0]; + } break; + + case ZT_PROTO_CIPHER_SUITE__AES_GCM_NRH: { + } break; } } -unsigned int _compress(Buf< Header > &packet,const unsigned int packetSize) +unsigned int compress(SharedPtr &pkt,unsigned int packetSize) { - uint8_t tmp[ZT_BUF_MEM_SIZE + 32]; - - if ((packet.data.fields.verb & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0) // sanity check for multiple calls to compress() + if (packetSize <= 128) return packetSize; + SharedPtr pkt2(Buf::get()); + if (!pkt2) return packetSize; + const unsigned int uncompressedLen = packetSize - ZT_PROTO_PACKET_PAYLOAD_START; const int compressedLen = LZ4_compress_fast( - reinterpret_cast(packet.data.bytes + ZT_PROTO_PACKET_PAYLOAD_START), - reinterpret_cast(tmp), + reinterpret_cast(pkt->b + ZT_PROTO_PACKET_PAYLOAD_START), + reinterpret_cast(pkt2->b + ZT_PROTO_PACKET_PAYLOAD_START), (int)uncompressedLen, - sizeof(tmp) - ZT_PROTO_PACKET_PAYLOAD_START); - if ((compressedLen > 0)&&(compressedLen < uncompressedLen)) { - packet.data.fields.verb |= ZT_PROTO_VERB_FLAG_COMPRESSED; - memcpy(packet.data.bytes + ZT_PROTO_PACKET_PAYLOAD_START,tmp,compressedLen); + ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START); + if ((compressedLen > 0)&&(compressedLen < (int)uncompressedLen)) { + memcpy(pkt2->b,pkt->b,ZT_PROTO_PACKET_PAYLOAD_START); + pkt.swap(pkt2); + pkt->as().verb |= ZT_PROTO_VERB_FLAG_COMPRESSED; return (unsigned int)compressedLen + ZT_PROTO_PACKET_PAYLOAD_START; } return packetSize; } -#endif } // namespace Protocol } // namespace ZeroTier diff --git a/node/Protocol.hpp b/node/Protocol.hpp index 5f4c56acf..4405ea4e3 100644 --- a/node/Protocol.hpp +++ b/node/Protocol.hpp @@ -146,6 +146,16 @@ */ #define ZT_PROTO_VERB_FLAG_COMPRESSED 0x80U +/** + * Mask to extract just the verb from the verb field, which also includes flags + */ +#define ZT_PROTO_VERB_MASK 0x1fU + +/** + * Key derivation function label for the key used with HMAC-384 in HELLO + */ +#define ZT_PROTO_KDF_KEY_LABEL_HELLO_HMAC 'H' + /** * HELLO exchange meta-data: signed locator for this node */ @@ -240,6 +250,7 @@ enum Verb /** * Announcement of a node's existence and vitals: + * [... HMAC-384 starts here ...] * <[1] protocol version> * <[1] software major version> * <[1] software minor version> @@ -251,8 +262,9 @@ enum Verb * <[2] 16-bit reserved (legacy) field, always 0> * <[2] 16-bit length of meta-data dictionary> * <[...] meta-data dictionary> + * <[2] 16-bit length of any additional fields> + * <[48] HMAC-SHA384 of full plaintext payload> * [... end encrypted region ...] - * <[48] HMAC-SHA384 of all fields to this point (as plaintext)> * * HELLO is sent with authentication but without the usual encryption so * that peers can exchange identities. @@ -967,11 +979,29 @@ ZT_ALWAYS_INLINE void salsa2012DeriveKey(const uint8_t *const in,uint8_t *const */ uint64_t getPacketId(); -void armor(Buf &packet,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite); +/** + * Encrypt and compute packet MAC + * + * @param pkt Packet data to encrypt (in place) + * @param packetSize Packet size, must be at least ZT_PROTO_MIN_PACKET_LENGTH or crash will occur + * @param key Key to use for encryption (not per-packet key) + * @param cipherSuite Cipher suite to use for AEAD encryption or just MAC + */ +void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite); -unsigned int compress(Buf &packet,unsigned int packetSize); - -int uncompress(Buf &packet,unsigned int packetSize); +/** + * Attempt to compress packet payload + * + * This attempts compression and swaps the pointer in 'pkt' for a buffer holding + * compressed data on success. If compression did not shrink the packet, the original + * packet size is returned and 'pkt' remains unchanged. If compression is successful + * the compressed verb flag is also set. + * + * @param pkt Packet buffer value/result parameter: pointer may be swapped if compression is successful + * @param packetSize Total size of packet in bytes (including headers) + * @return New size of packet after compression or original size of compression wasn't helpful + */ +unsigned int compress(SharedPtr &pkt,unsigned int packetSize); } // namespace Protocol } // namespace ZeroTier diff --git a/node/Trace.cpp b/node/Trace.cpp index d49ca3f00..8ae385a3d 100644 --- a/node/Trace.cpp +++ b/node/Trace.cpp @@ -16,13 +16,6 @@ #include "Node.hpp" #include "Peer.hpp" -// Macro to avoid calling hton() on values known at compile time. -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U))) -#else -#define CONST_TO_BE_UINT16(x) ((uint16_t)(x)) -#endif - // NOTE: packet IDs are always handled in network byte order, so no need to convert them. namespace ZeroTier { diff --git a/node/Utils.cpp b/node/Utils.cpp index 0dcf59f46..c7e0c8bf1 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -57,6 +57,7 @@ CPUIDRegisters::CPUIDRegisters() CPUIDRegisters CPUID; #endif +const uint64_t ZERO256[4] = { 0,0,0,0 }; const char HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; bool secureEq(const void *a,const void *b,unsigned int len) diff --git a/node/Utils.hpp b/node/Utils.hpp index 95ef573cd..67a60b284 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -46,6 +46,11 @@ struct CPUIDRegisters extern CPUIDRegisters CPUID; #endif +/** + * 256 zero bits + */ +extern const uint64_t ZERO256[4]; + /** * Hexadecimal characters 0-f */ diff --git a/node/VL1.cpp b/node/VL1.cpp index 3db88f173..0b2b03bb5 100644 --- a/node/VL1.cpp +++ b/node/VL1.cpp @@ -18,160 +18,12 @@ #include "Salsa20.hpp" #include "LZ4.hpp" #include "Poly1305.hpp" +#include "Identity.hpp" +#include "SelfAwareness.hpp" +#include "SHA512.hpp" namespace ZeroTier { -namespace { - -#if 0 -ZT_ALWAYS_INLINE bool _doHELLO(SharedPtr &pkt,int len,const RuntimeEnvironment *const RR,void *const tPtr,const bool alreadyAuthenticated) -{ - if (p.size < sizeof(Protocol::HELLO)) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,Identity(),p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET); - return true; - } - Buf< Protocol::HELLO > &pkt = reinterpret_cast &>(*p.pkt); - - Identity id; - int ptr = sizeof(Protocol::HELLO); - if (pkt.rO(ptr,id) < 0) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,Identity(),p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); - return true; - } - - if (pkt.data.fields.versionProtocol < ZT_PROTO_VERSION_MIN) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD); - return true; - } - if (Address(pkt.data.fields.h.source) != id.address()) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET); - return true; - } - - const int64_t now = RR->node->now(); - - SharedPtr peer(RR->topology->get(tPtr,id.address())); - if (peer) { - // We already have an identity with this address -- check for collisions - if (!alreadyAuthenticated) { - if (peer->identity() != id) { - // Identity is different from the one we already have -- address collision - - // Check rate limits - if (!RR->node->rateGateIdentityVerification(now,p.path->address())) - return true; - - uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]; - if (RR->identity.agree(id,key)) { - if (Protocol::dearmor(pkt,p.size,key) < 0) { // ensure packet is authentic, otherwise drop - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); - return true; - } else { - // TODO: we handle identity collisions differently now - } - } else { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); - return true; - } - - return true; - } else { - // Identity is the same as the one we already have -- check packet integrity - - if (Protocol::dearmor(pkt,p.size,peer->key()) < 0) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); - return true; - } - - // Continue at // VALID - } - } // else if alreadyAuthenticated then continue at // VALID - } else { - // We don't already have an identity with this address -- validate and learn it - - // Sanity check: this basically can't happen - if (alreadyAuthenticated) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,Identity(),p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED); - return true; - } - - // Check rate limits - if (!RR->node->rateGateIdentityVerification(now,p.path->address())) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED); - return true; - } - - // Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap) - SharedPtr newPeer(new Peer(RR)); - if (!newPeer->init(RR->identity,id)) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); - return true; - } - if (Protocol::dearmor(pkt,p.size,newPeer->key())) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); - return true; - } - - // Check that identity's address is valid as per the derivation function - if (!id.locallyValidate()) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); - return true; - } - - peer = RR->topology->add(tPtr,newPeer); - - // Continue at // VALID - } - - // VALID -- if we made it here, packet passed identity and authenticity checks! - - // Get address to which this packet was sent to learn our external surface address if packet was direct. - InetAddress externalSurfaceAddress; - if (ptr < p.size) { - if (pkt.rO(ptr,externalSurfaceAddress) < 0) { - RR->t->incomingPacketDropped(tPtr,p.idBE,0,id,p.path->address(),p.hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); - return true; - } - if ((p.hops == 0)&&(externalSurfaceAddress)) - RR->sa->iam(tPtr,id,p.path->localSocket(),p.path->address(),externalSurfaceAddress,RR->topology->isRoot(id),now); - } - - // Send OK(HELLO) with an echo of the packet's timestamp and some of the same - // information about us: version, sent-to address, etc. - - ZT_GET_NEW_BUF(outp,Protocol::OK::HELLO); - - outp->data.fields.h.packetId = Protocol::getPacketId(); - peer->address().copyTo(outp->data.fields.h.destination); - RR->identity.address().copyTo(outp->data.fields.h.source); - outp->data.fields.h.flags = 0; - outp->data.fields.h.verb = Protocol::VERB_OK; - - outp->data.fields.oh.inReVerb = Protocol::VERB_HELLO; - outp->data.fields.oh.inRePacketId = p.idBE; - - outp->data.fields.timestampEcho = pkt.data.fields.timestamp; - outp->data.fields.versionProtocol = ZT_PROTO_VERSION; - outp->data.fields.versionMajor = ZEROTIER_ONE_VERSION_MAJOR; - outp->data.fields.versionMinor = ZEROTIER_ONE_VERSION_MINOR; - outp->data.fields.versionRev = CONST_TO_BE_UINT16(ZEROTIER_ONE_VERSION_REVISION); - - int outl = sizeof(Protocol::OK::HELLO); - outp->wO(outl,p.path->address()); - if (!Buf<>::writeOverflow(outl)) { - Protocol::armor(*outp,outl,peer->key(),ZT_PROTO_CIPHER_SUITE__POLY1305_SALSA2012); - p.path->send(RR,tPtr,outp->data.bytes,outl,RR->node->now()); - } - - peer->setRemoteVersion(pkt.data.fields.versionProtocol,pkt.data.fields.versionMajor,pkt.data.fields.versionMinor,Utils::ntoh(pkt.data.fields.versionRev)); - peer->received(tPtr,p.path,p.hops,p.idBE,p.size,Protocol::VERB_HELLO,0,Protocol::VERB_NOP,0); - - return true; -} -#endif - -} // anonymous namespace - VL1::VL1(const RuntimeEnvironment *renv) : RR(renv), _vl2(nullptr) @@ -184,7 +36,6 @@ VL1::~VL1() void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAddress &fromAddr,SharedPtr &data,const unsigned int len) { - static const uint64_t ZEROES32[4] = { 0,0,0,0 }; const int64_t now = RR->node->now(); const SharedPtr path(RR->topology->getPath(localSocket,fromAddr)); path->received(now); @@ -339,11 +190,11 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd uint8_t perPacketKey[ZT_PEER_SECRET_KEY_LENGTH]; uint8_t macKey[ZT_POLY1305_KEY_LEN]; Protocol::salsa2012DeriveKey(peer->key(),perPacketKey,*pktv[0].b,packetSize); - Salsa20(perPacketKey,&ph->packetId).crypt12(ZEROES32,macKey,ZT_POLY1305_KEY_LEN); + Salsa20(perPacketKey,&ph->packetId).crypt12(Utils::ZERO256,macKey,ZT_POLY1305_KEY_LEN); // Verify packet MAC. uint64_t mac[2]; - poly1305(mac,pkt.b->b,pkt.e,macKey); + poly1305(mac,pkt.b->b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,macKey); if (ph->mac != mac[0]) { RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); return; @@ -361,7 +212,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd // Do one Salsa20 block to generate the one-time-use Poly1305 key. uint8_t macKey[ZT_POLY1305_KEY_LEN]; - s20.crypt12(ZEROES32,macKey,ZT_POLY1305_KEY_LEN); + s20.crypt12(Utils::ZERO256,macKey,ZT_POLY1305_KEY_LEN); // Get a buffer to store the decrypted and fully contiguous packet. pkt.b = Buf::get(); @@ -397,7 +248,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd // Verify packet MAC. uint64_t mac[2]; - poly1305(mac,pkt.b->b,pkt.e,macKey); + poly1305(mac,pkt.b->b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,macKey); if (ph->mac != mac[0]) { RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); return; @@ -423,7 +274,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd authenticated = true; } else { if (peer) - RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); + RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_NOT_TRUSTED_PATH); return; } } break; @@ -445,7 +296,12 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd pktv.clear(); // Decompress packet payload if compressed. - if (((ph->verb & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0)&&(authenticated)) { + if ((ph->verb & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0) { + if (!authenticated) { + RR->t->incomingPacketDropped(tPtr,ph->packetId,0,Identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET); + return; + } + SharedPtr nb(Buf::get()); if (!nb) // can only happen if we're out of memory return; @@ -461,35 +317,35 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd pkt.e = packetSize = (unsigned int)uncompressedLen; } else { if (peer) - RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,(Protocol::Verb)(ph->verb & 0x1fU),ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA); + RR->t->incomingPacketDropped(tPtr,ph->packetId,0,peer->identity(),path->address(),hops,(Protocol::Verb)(ph->verb & ZT_PROTO_VERB_MASK),ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA); return; } } - const Protocol::Verb verb = (Protocol::Verb)(ph->verb & 0x1fU); + const Protocol::Verb verb = (Protocol::Verb)(ph->verb & ZT_PROTO_VERB_MASK); switch(verb) { case Protocol::VERB_NOP: peer->received(tPtr,path,hops,ph->packetId,packetSize - ZT_PROTO_PACKET_PAYLOAD_START,Protocol::VERB_NOP,0,Protocol::VERB_NOP,0); break; - case Protocol::VERB_HELLO: _HELLO(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_ERROR: _ERROR(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_OK: _OK(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_WHOIS: _WHOIS(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_RENDEZVOUS: _RENDEZVOUS(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_FRAME: _vl2->_FRAME(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_EXT_FRAME: _vl2->_EXT_FRAME(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_ECHO: _ECHO(tPtr,path,peer,*pkt.b,packetSize,authenticated); - case Protocol::VERB_MULTICAST_LIKE: _vl2->_MULTICAST_LIKE(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_NETWORK_CREDENTIALS: _vl2->_NETWORK_CREDENTIALS(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_NETWORK_CONFIG_REQUEST: _vl2->_NETWORK_CONFIG_REQUEST(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_NETWORK_CONFIG: _vl2->_NETWORK_CONFIG(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_MULTICAST_GATHER: _vl2->_MULTICAST_LIKE(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_MULTICAST_FRAME_deprecated: _vl2->_MULTICAST_FRAME_deprecated(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_PUSH_DIRECT_PATHS: _PUSH_DIRECT_PATHS(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_USER_MESSAGE: _USER_MESSAGE(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_MULTICAST: _vl2->_MULTICAST(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; - case Protocol::VERB_ENCAP: _ENCAP(tPtr,path,peer,*pkt.b,packetSize,authenticated); break; + case Protocol::VERB_HELLO: _HELLO(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_ERROR: _ERROR(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_OK: _OK(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_WHOIS: _WHOIS(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_RENDEZVOUS: _RENDEZVOUS(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_FRAME: _vl2->_FRAME(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_EXT_FRAME: _vl2->_EXT_FRAME(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_ECHO: _ECHO(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); + case Protocol::VERB_MULTICAST_LIKE: _vl2->_MULTICAST_LIKE(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_NETWORK_CREDENTIALS: _vl2->_NETWORK_CREDENTIALS(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_NETWORK_CONFIG_REQUEST: _vl2->_NETWORK_CONFIG_REQUEST(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_NETWORK_CONFIG: _vl2->_NETWORK_CONFIG(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_MULTICAST_GATHER: _vl2->_MULTICAST_GATHER(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_MULTICAST_FRAME_deprecated: _vl2->_MULTICAST_FRAME_deprecated(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_PUSH_DIRECT_PATHS: _PUSH_DIRECT_PATHS(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_USER_MESSAGE: _USER_MESSAGE(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_MULTICAST: _vl2->_MULTICAST(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; + case Protocol::VERB_ENCAP: _ENCAP(tPtr,path,peer,*pkt.b,(int)packetSize,authenticated); break; default: if (peer) @@ -515,31 +371,223 @@ void VL1::_sendPendingWhois() // assume _whoisQueue_l locked } -void VL1::_HELLO(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_HELLO(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ + if (packetSize < sizeof(Protocol::HELLO)) { + RR->t->incomingPacketDropped(tPtr,0,0,Identity(),path->address(),0,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET); + return; + } + + Protocol::HELLO &p = pkt.as(); + const uint8_t hops = Protocol::packetHops(p.h); + int ptr = sizeof(Protocol::HELLO); + + if (p.versionProtocol < ZT_PROTO_VERSION_MIN) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,Identity(),path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD); + return; + } + + Identity id; + if (pkt.rO(ptr,id) < 0) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,Identity(),path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); + return; + } + if (Address(p.h.source) != id.address()) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); + return; + } + + // Get long-term static key for this node. + uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]; + if ((peer)&&(id == peer->identity())) { + memcpy(key,peer->key(),ZT_PEER_SECRET_KEY_LENGTH); + } else { + peer.zero(); + if (!RR->identity.agree(id,key)) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); + return; + } + } + + // Verify packet using Poly1305. For v2.x+ HELLOs this will be the first of two MACs for HELLO. + { + uint8_t perPacketKey[ZT_PEER_SECRET_KEY_LENGTH]; + uint8_t macKey[ZT_POLY1305_KEY_LEN]; + Protocol::salsa2012DeriveKey(peer->key(),perPacketKey,pkt,packetSize); + Salsa20(perPacketKey,&p.h.packetId).crypt12(Utils::ZERO256,macKey,ZT_POLY1305_KEY_LEN); + uint64_t mac[2]; + poly1305(mac,pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,macKey); + if (p.h.mac != mac[0]) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); + return; + } + } + + InetAddress externalSurfaceAddress; + Dictionary nodeMetaData; + + // Get external surface address if present. + if (ptr < packetSize) { + if (pkt.rO(ptr,externalSurfaceAddress) < 0) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); + return; + } + } + + if (ptr < packetSize) { + // NOTE to auditors: + // Anything after the external surface address is encrypted using Salsa20/12. + // The key for this is un-mangled static peer key. This is a bit of a legacy + // thing and isn't absolutely necessary, but does help conceal information + // that does not need to be in plaintext. This should not be considered + // a required part of the security/authentication model since leakage of + // this information would have no impact on either authentication or actual + // payload encryption. + uint8_t iv[8]; + for(int i=0;i<8;++i) iv[i] = pkt.b[i]; + iv[7] &= 0xf8U; + Salsa20 s20(key,iv); + s20.crypt12(pkt.b + ptr,pkt.b + ptr,packetSize - ptr); + + ptr += pkt.rI16(ptr); // this field is zero in v2.0+ but can indicate data between this point and dictionary + if (ptr < packetSize) { + const unsigned int dictionarySize = pkt.rI16(ptr); + const void *const dictionaryBytes = pkt.b + ptr; + if ((ptr += (int)dictionarySize) > packetSize) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); + return; + } + + ptr += pkt.rI16(ptr); // skip any additional fields, currently always 0 + if (ptr > packetSize) { + RR->t->incomingPacketDropped(tPtr,0,0,Identity(),path->address(),0,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET); + return; + } + + if ((ptr + ZT_SHA384_DIGEST_LEN) <= packetSize) { + uint8_t hmacKey[ZT_PEER_SECRET_KEY_LENGTH],mac[ZT_HMACSHA384_LEN]; + KBKDFHMACSHA384(key,ZT_PROTO_KDF_KEY_LABEL_HELLO_HMAC,0,0,hmacKey); + HMACSHA384(hmacKey,pkt.b + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,mac); + if (!Utils::secureEq(pkt.b + ptr,mac,ZT_HMACSHA384_LEN)) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,peer->identity(),path->address(),hops,Protocol::VERB_NOP,ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED); + return; + } + } + + if (dictionarySize) { + if (!nodeMetaData.decode(dictionaryBytes,dictionarySize)) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); + return; + } + } + } + } + + const int64_t now = RR->node->now(); + + if (!peer) { + if (!RR->node->rateGateIdentityVerification(now,path->address())) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED); + return; + } + if (!id.locallyValidate()) { + RR->t->incomingPacketDropped(tPtr,p.h.packetId,0,id,path->address(),hops,Protocol::VERB_HELLO,ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT); + return; + } + peer.set(new Peer(RR)); + if (!peer) + return; + peer->init(RR->identity,id); + peer = RR->topology->add(tPtr,peer); + } + + if ((hops == 0)&&(externalSurfaceAddress)) + RR->sa->iam(tPtr,id,path->localSocket(),path->address(),externalSurfaceAddress,RR->topology->isRoot(id),now); + + // Send OK(HELLO) with an echo of the packet's timestamp and some of the same + // information about us: version, sent-to address, etc. + + SharedPtr outp(Buf::get()); + if (!outp) return; + Protocol::OK::HELLO &ok = outp->as(); + + ok.h.packetId = Protocol::getPacketId(); + id.address().copyTo(ok.h.destination); + RR->identity.address().copyTo(ok.h.source); + ok.h.flags = 0; + ok.h.verb = Protocol::VERB_OK; + + ok.oh.inReVerb = Protocol::VERB_HELLO; + ok.oh.inRePacketId = p.h.packetId; + + ok.timestampEcho = p.timestamp; + ok.versionProtocol = ZT_PROTO_VERSION; + ok.versionMajor = ZEROTIER_ONE_VERSION_MAJOR; + ok.versionMinor = ZEROTIER_ONE_VERSION_MINOR; + ok.versionRev = ZT_CONST_TO_BE_UINT16(ZEROTIER_ONE_VERSION_REVISION); + + int outl = sizeof(Protocol::OK::HELLO); + outp->wO(outl,path->address()); + +#if 0 + ZT_GET_NEW_BUF(outp,Protocol::OK::HELLO); + + outp->data.fields.h.packetId = Protocol::getPacketId(); + peer->address().copyTo(outp->data.fields.h.destination); + RR->identity.address().copyTo(outp->data.fields.h.source); + outp->data.fields.h.flags = 0; + outp->data.fields.h.verb = Protocol::VERB_OK; + + outp->data.fields.oh.inReVerb = Protocol::VERB_HELLO; + outp->data.fields.oh.inRePacketId = p.idBE; + + outp->data.fields.timestampEcho = pkt.data.fields.timestamp; + outp->data.fields.versionProtocol = ZT_PROTO_VERSION; + outp->data.fields.versionMajor = ZEROTIER_ONE_VERSION_MAJOR; + outp->data.fields.versionMinor = ZEROTIER_ONE_VERSION_MINOR; + outp->data.fields.versionRev = CONST_TO_BE_UINT16(ZEROTIER_ONE_VERSION_REVISION); + + int outl = sizeof(Protocol::OK::HELLO); + outp->wO(outl,p.path->address()); + if (!Buf<>::writeOverflow(outl)) { + Protocol::armor(*outp,outl,peer->key(),ZT_PROTO_CIPHER_SUITE__POLY1305_SALSA2012); + p.path->send(RR,tPtr,outp->data.bytes,outl,RR->node->now()); + } +#endif + + peer->setRemoteVersion(p.versionProtocol,p.versionMajor,p.versionMinor,Utils::ntoh(p.versionRev)); + peer->received(tPtr,path,hops,p.h.packetId,packetSize - ZT_PROTO_PACKET_PAYLOAD_START,Protocol::VERB_HELLO,0,Protocol::VERB_NOP,0); +} + +void VL1::_ERROR(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_ERROR(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_OK(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_OK(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_WHOIS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_WHOIS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_RENDEZVOUS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_ECHO(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_USER_MESSAGE(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } -void VL1::_ENCAP(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated) +void VL1::_USER_MESSAGE(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL1::_ENCAP(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) { } diff --git a/node/VL1.hpp b/node/VL1.hpp index b0e0e0fb6..464997a37 100644 --- a/node/VL1.hpp +++ b/node/VL1.hpp @@ -56,15 +56,15 @@ private: void _sendPendingWhois(); // Handlers for VL1 verbs - void _HELLO(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _ERROR(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _OK(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _WHOIS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _RENDEZVOUS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _ECHO(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _USER_MESSAGE(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _ENCAP(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); + void _HELLO(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _ERROR(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _OK(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _WHOIS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _RENDEZVOUS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _ECHO(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _USER_MESSAGE(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _ENCAP(void *tPtr,const SharedPtr &path,const SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); const RuntimeEnvironment *RR; VL2 *const _vl2; diff --git a/node/VL2.cpp b/node/VL2.cpp new file mode 100644 index 000000000..86d35225e --- /dev/null +++ b/node/VL2.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2024-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "VL2.hpp" +#include "RuntimeEnvironment.hpp" +#include "VL1.hpp" +#include "Topology.hpp" +#include "Peer.hpp" +#include "Path.hpp" + +namespace ZeroTier { + +VL2::VL2(const RuntimeEnvironment *renv) +{ +} + +VL2::~VL2() +{ +} + +void VL2::_FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_EXT_FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_MULTICAST_LIKE(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_NETWORK_CREDENTIALS(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_NETWORK_CONFIG(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_MULTICAST_GATHER(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +void VL2::_MULTICAST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated) +{ +} + +} // namespace ZeroTier diff --git a/node/VL2.hpp b/node/VL2.hpp index 027a9e44e..360b1b8be 100644 --- a/node/VL2.hpp +++ b/node/VL2.hpp @@ -24,6 +24,8 @@ namespace ZeroTier { +class Path; +class Peer; class RuntimeEnvironment; class VL1; @@ -32,19 +34,19 @@ class VL2 friend class VL1; public: - VL1(const RuntimeEnvironment *renv); - ~VL1(); + VL2(const RuntimeEnvironment *renv); + ~VL2(); protected: - void _FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _EXT_FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _MULTICAST_LIKE(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _NETWORK_CREDENTIALS(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _NETWORK_CONFIG(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _MULTICAST_GATHER(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); - void _MULTICAST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,unsigned int len,bool authenticated); + void _FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _EXT_FRAME(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _MULTICAST_LIKE(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _NETWORK_CREDENTIALS(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _NETWORK_CONFIG(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _MULTICAST_GATHER(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); + void _MULTICAST(void *tPtr,const SharedPtr &path,SharedPtr &peer,Buf &pkt,int packetSize,bool authenticated); private: };