mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-21 05:53:09 +00:00
Chunking of network config replies.
This commit is contained in:
parent
2ba9343607
commit
bcd05fbdfa
@ -23,6 +23,7 @@
|
|||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
#include "Address.hpp"
|
#include "Address.hpp"
|
||||||
|
#include "C25519.hpp"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -443,6 +444,39 @@ public:
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign this Dictionary, replacing any previous signature
|
||||||
|
*
|
||||||
|
* @param sigKey Key to use for signature in dictionary
|
||||||
|
* @param kp Key pair to sign with
|
||||||
|
*/
|
||||||
|
inline void wrapWithSignature(const char *sigKey,const C25519::Pair &kp)
|
||||||
|
{
|
||||||
|
this->erase(sigKey);
|
||||||
|
C25519::Signature sig(C25519::sign(kp,this->data(),this->sizeBytes()));
|
||||||
|
this->add(sigKey,sig.data,ZT_C25519_SIGNATURE_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify signature (and erase signature key)
|
||||||
|
*
|
||||||
|
* This erases this Dictionary's signature key (if present) and verifies
|
||||||
|
* the signature. The key is erased to render the Dictionary into the
|
||||||
|
* original unsigned form it was signed in for verification purposes.
|
||||||
|
*
|
||||||
|
* @param sigKey Key to use for signature in dictionary
|
||||||
|
* @param pk Public key to check against
|
||||||
|
* @return True if signature was present and valid
|
||||||
|
*/
|
||||||
|
inline bool unwrapAndVerify(const char *sigKey,const C25519::Public &pk)
|
||||||
|
{
|
||||||
|
char sig[ZT_C25519_SIGNATURE_LEN+1];
|
||||||
|
if (this->get(sigKey,sig,sizeof(sig)) != ZT_C25519_SIGNATURE_LEN)
|
||||||
|
return false;
|
||||||
|
this->erase(sigKey);
|
||||||
|
return C25519::verify(pk,this->data(),this->sizeBytes(),sig);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Dictionary data as a 0-terminated C-string
|
* @return Dictionary data as a 0-terminated C-string
|
||||||
*/
|
*/
|
||||||
|
@ -719,35 +719,46 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
const char *metaDataBytes = (const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength);
|
const char *metaDataBytes = (const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength);
|
||||||
const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> metaData(metaDataBytes,metaDataLength);
|
const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> metaData(metaDataBytes,metaDataLength);
|
||||||
|
|
||||||
//const uint64_t haveRevision = ((ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength + 8) <= size()) ? at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength) : 0ULL;
|
|
||||||
|
|
||||||
const unsigned int h = hops();
|
const unsigned int h = hops();
|
||||||
const uint64_t pid = packetId();
|
const uint64_t requestPacketId = packetId();
|
||||||
peer->received(_localAddress,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
|
peer->received(_localAddress,_remoteAddress,h,requestPacketId,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
|
||||||
|
|
||||||
if (RR->localNetworkController) {
|
if (RR->localNetworkController) {
|
||||||
NetworkConfig netconf;
|
NetworkConfig netconf;
|
||||||
switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,netconf)) {
|
switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,netconf)) {
|
||||||
|
|
||||||
case NetworkController::NETCONF_QUERY_OK: {
|
case NetworkController::NETCONF_QUERY_OK: {
|
||||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> dconf;
|
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||||
if (netconf.toDictionary(dconf,metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6)) {
|
try {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
if (netconf.toDictionary(*dconf,metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6)) {
|
||||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
const unsigned int totalSize = dconf->sizeBytes();
|
||||||
outp.append(pid);
|
unsigned int chunkPtr = 0;
|
||||||
outp.append(nwid);
|
while (chunkPtr < totalSize) {
|
||||||
const unsigned int dlen = dconf.sizeBytes();
|
const unsigned int chunkLen = std::min(totalSize - chunkPtr,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PROTO_MIN_PACKET_LENGTH + 32)));
|
||||||
outp.append((uint16_t)dlen);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
||||||
outp.append((const void *)dconf.data(),dlen);
|
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||||
outp.compress();
|
outp.append(requestPacketId);
|
||||||
RR->sw->send(outp,true,0);
|
outp.append(nwid);
|
||||||
|
outp.append((uint16_t)chunkLen);
|
||||||
|
outp.append((const void *)(dconf->data() + chunkPtr),chunkLen);
|
||||||
|
outp.append((uint32_t)totalSize);
|
||||||
|
outp.append((uint32_t)chunkPtr);
|
||||||
|
outp.compress();
|
||||||
|
RR->sw->send(outp,true,0);
|
||||||
|
chunkPtr += chunkLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete dconf;
|
||||||
|
} catch ( ... ) {
|
||||||
|
delete dconf;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND: {
|
case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND: {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
||||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||||
outp.append(pid);
|
outp.append(requestPacketId);
|
||||||
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
|
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
@ -757,7 +768,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
case NetworkController::NETCONF_QUERY_ACCESS_DENIED: {
|
case NetworkController::NETCONF_QUERY_ACCESS_DENIED: {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
||||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||||
outp.append(pid);
|
outp.append(requestPacketId);
|
||||||
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
|
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
@ -765,7 +776,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR:
|
case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR:
|
||||||
// TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NetworkController::NETCONF_QUERY_IGNORE:
|
case NetworkController::NETCONF_QUERY_IGNORE:
|
||||||
@ -779,7 +789,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
} else {
|
} else {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
||||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||||
outp.append(pid);
|
outp.append(requestPacketId);
|
||||||
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
|
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
|
@ -135,6 +135,8 @@ namespace ZeroTier {
|
|||||||
#define ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES "CAP"
|
#define ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES "CAP"
|
||||||
// tags (binary blobs)
|
// tags (binary blobs)
|
||||||
#define ZT_NETWORKCONFIG_DICT_KEY_TAGS "TAG"
|
#define ZT_NETWORKCONFIG_DICT_KEY_TAGS "TAG"
|
||||||
|
// curve25519 signature
|
||||||
|
#define ZT_NETWORKCONFIG_DICT_KEY_SIGNATURE "C25519"
|
||||||
|
|
||||||
// Legacy fields -- these are obsoleted but are included when older clients query
|
// Legacy fields -- these are obsoleted but are included when older clients query
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ public:
|
|||||||
* <[8] 64-bit network ID>
|
* <[8] 64-bit network ID>
|
||||||
* <[2] 16-bit length of request meta-data dictionary>
|
* <[2] 16-bit length of request meta-data dictionary>
|
||||||
* <[...] string-serialized request meta-data>
|
* <[...] string-serialized request meta-data>
|
||||||
* [<[8] 64-bit timestamp of netconf we currently have>]
|
* <[8] 64-bit timestamp of netconf we currently have>
|
||||||
*
|
*
|
||||||
* This message requests network configuration from a node capable of
|
* This message requests network configuration from a node capable of
|
||||||
* providing it. If the optional revision is included, a response is
|
* providing it. If the optional revision is included, a response is
|
||||||
@ -732,14 +732,10 @@ public:
|
|||||||
*
|
*
|
||||||
* OK response payload:
|
* OK response payload:
|
||||||
* <[8] 64-bit network ID>
|
* <[8] 64-bit network ID>
|
||||||
* <[2] 16-bit length of network configuration dictionary field>
|
* <[2] 16-bit length of network configuration dictionary chunk>
|
||||||
* <[...] network configuration dictionary (or fragment)>
|
* <[...] network configuration dictionary (may be incomplete)>
|
||||||
* [<[4] 32-bit total length of assembled dictionary>]
|
* <[4] 32-bit total length of assembled dictionary>
|
||||||
* [<[4] 32-bit index of fragment in this reply>]
|
* <[4] 32-bit index of chunk in this reply>
|
||||||
*
|
|
||||||
* Fields after the dictionary are extensions to support multipart
|
|
||||||
* sending of large network configs. If they are not present the
|
|
||||||
* sent config must be assumed to be whole.
|
|
||||||
*
|
*
|
||||||
* ERROR response payload:
|
* ERROR response payload:
|
||||||
* <[8] 64-bit network ID>
|
* <[8] 64-bit network ID>
|
||||||
|
Loading…
Reference in New Issue
Block a user