summaryrefslogtreecommitdiff
path: root/node/Network.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-09 13:14:38 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-09 13:14:38 -0700
commit4d498b3765695f1b82a2448f0e8efe698b33667d (patch)
tree191eb30f716498587808d1789e73d744137b1577 /node/Network.cpp
parentbcd05fbdfa7e340ef4df962773bb7c32cf5013c2 (diff)
downloadinfinitytier-4d498b3765695f1b82a2448f0e8efe698b33667d.tar.gz
infinitytier-4d498b3765695f1b82a2448f0e8efe698b33667d.zip
Handling of multi-part chunked network configs on the inbound side.
Diffstat (limited to 'node/Network.cpp')
-rw-r--r--node/Network.cpp48
1 files changed, 47 insertions, 1 deletions
diff --git a/node/Network.cpp b/node/Network.cpp
index 0fbdf5ba..b84756aa 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -343,6 +343,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
_id(nwid),
_mac(renv->identity.address(),nwid),
_portInitialized(false),
+ _inboundConfigPacketId(0),
_lastConfigUpdate(0),
_destroyed(false),
_netconfFailure(NETCONF_FAILURE_NONE),
@@ -364,7 +365,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
std::string conf(RR->node->dataStoreGet(confn));
if (conf.length()) {
dconf->load(conf.c_str());
- if (nconf->fromDictionary(*dconf)) {
+ if (nconf->fromDictionary(Identity(),*dconf)) {
this->setConfiguration(*nconf,false);
_lastConfigUpdate = 0; // we still want to re-request a new config from the network
gotConf = true;
@@ -589,6 +590,47 @@ int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
return 0;
}
+void Network::handleInboundConfigChunk(const uint64_t inRePacketId,const void *data,unsigned int chunkSize,unsigned int chunkIndex,unsigned int totalSize)
+{
+ std::string newConfig;
+ if ((_inboundConfigPacketId == inRePacketId)&&(totalSize < ZT_NETWORKCONFIG_DICT_CAPACITY)&&((chunkIndex + chunkSize) < totalSize)) {
+ Mutex::Lock _l(_lock);
+ TRACE("got %u bytes at position %u of network config request %.16llx, total expected length %u",chunkSize,chunkIndex,inRePacketId,totalSize);
+ _inboundConfigChunks[chunkIndex].append((const char *)data,chunkSize);
+ unsigned int totalWeHave = 0;
+ for(std::map<unsigned int,std::string>::iterator c(_inboundConfigChunks.begin());c!=_inboundConfigChunks.end();++c)
+ totalWeHave += (unsigned int)c->second.length();
+ if (totalWeHave == totalSize) {
+ TRACE("have all chunks for network config request %.16llx, assembling...",inRePacketId);
+ for(std::map<unsigned int,std::string>::iterator c(_inboundConfigChunks.begin());c!=_inboundConfigChunks.end();++c)
+ newConfig.append(c->second);
+ _inboundConfigPacketId = 0;
+ _inboundConfigChunks.clear();
+ } else if (totalWeHave > totalSize) {
+ _inboundConfigPacketId = 0;
+ _inboundConfigChunks.clear();
+ }
+ }
+
+ if (newConfig.length() > 0) {
+ if (newConfig.length() < ZT_NETWORKCONFIG_DICT_CAPACITY) {
+ Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dict = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>(newConfig.c_str());
+ try {
+ Identity controllerId(RR->topology->getIdentity(this->controller()));
+ if (controllerId) {
+ NetworkConfig nc;
+ if (nc.fromDictionary(controllerId,*dict))
+ this->setConfiguration(nc,true);
+ }
+ delete dict;
+ } catch ( ... ) {
+ delete dict;
+ throw;
+ }
+ }
+ }
+}
+
void Network::requestConfiguration()
{
if (_id == ZT_TEST_NETWORK_ID) // pseudo-network-ID, uses locally generated static config
@@ -637,6 +679,10 @@ void Network::requestConfiguration()
outp.append((_config) ? (uint64_t)_config.revision : (uint64_t)0);
outp.compress();
RR->sw->send(outp,true,0);
+
+ // Expect replies with this in-re packet ID
+ _inboundConfigPacketId = outp.packetId();
+ _inboundConfigChunks.clear();
}
void Network::clean()