mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Yet more work on VL1/VL2
This commit is contained in:
parent
c3d3605f70
commit
df4b1e9b12
13 changed files with 422 additions and 250 deletions
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Protocol::Header>();
|
||||
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<Buf> &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<Buf> 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<const char *>(packet.data.bytes + ZT_PROTO_PACKET_PAYLOAD_START),
|
||||
reinterpret_cast<char *>(tmp),
|
||||
reinterpret_cast<const char *>(pkt->b + ZT_PROTO_PACKET_PAYLOAD_START),
|
||||
reinterpret_cast<char *>(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<Protocol::Header>().verb |= ZT_PROTO_VERB_FLAG_COMPRESSED;
|
||||
return (unsigned int)compressedLen + ZT_PROTO_PACKET_PAYLOAD_START;
|
||||
}
|
||||
|
||||
return packetSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Protocol
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -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<Buf> &pkt,unsigned int packetSize);
|
||||
|
||||
} // namespace Protocol
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -46,6 +46,11 @@ struct CPUIDRegisters
|
|||
extern CPUIDRegisters CPUID;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 256 zero bits
|
||||
*/
|
||||
extern const uint64_t ZERO256[4];
|
||||
|
||||
/**
|
||||
* Hexadecimal characters 0-f
|
||||
*/
|
||||
|
|
418
node/VL1.cpp
418
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<Buf> &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<Buf< Protocol::HELLO > &>(*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> 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<Peer> 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<Buf> &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> 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<Buf> 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> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_HELLO(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &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<Protocol::HELLO>();
|
||||
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<Buf> outp(Buf::get());
|
||||
if (!outp) return;
|
||||
Protocol::OK::HELLO &ok = outp->as<Protocol::OK::HELLO>();
|
||||
|
||||
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> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_ERROR(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_OK(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_OK(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_WHOIS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_WHOIS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_RENDEZVOUS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_ECHO(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_USER_MESSAGE(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_ENCAP(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated)
|
||||
void VL1::_USER_MESSAGE(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::_ENCAP(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
18
node/VL1.hpp
18
node/VL1.hpp
|
@ -56,15 +56,15 @@ private:
|
|||
void _sendPendingWhois();
|
||||
|
||||
// Handlers for VL1 verbs
|
||||
void _HELLO(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _ERROR(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _OK(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _WHOIS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _RENDEZVOUS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _ECHO(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _USER_MESSAGE(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _ENCAP(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _HELLO(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _ERROR(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _OK(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _WHOIS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _RENDEZVOUS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _ECHO(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _USER_MESSAGE(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _ENCAP(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
|
||||
const RuntimeEnvironment *RR;
|
||||
VL2 *const _vl2;
|
||||
|
|
67
node/VL2.cpp
Normal file
67
node/VL2.cpp
Normal file
|
@ -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> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_EXT_FRAME(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_MULTICAST_LIKE(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_NETWORK_CREDENTIALS(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_NETWORK_CONFIG(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_MULTICAST_GATHER(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
void VL2::_MULTICAST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
24
node/VL2.hpp
24
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> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _EXT_FRAME(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _MULTICAST_LIKE(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _NETWORK_CREDENTIALS(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _NETWORK_CONFIG(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _MULTICAST_GATHER(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _MULTICAST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,unsigned int len,bool authenticated);
|
||||
void _FRAME(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _EXT_FRAME(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _MULTICAST_LIKE(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _NETWORK_CREDENTIALS(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _NETWORK_CONFIG_REQUEST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _NETWORK_CONFIG(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _MULTICAST_GATHER(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _MULTICAST_FRAME_deprecated(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
void _MULTICAST(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Buf &pkt,int packetSize,bool authenticated);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue