summaryrefslogtreecommitdiff
path: root/node/IncomingPacket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/IncomingPacket.cpp')
-rw-r--r--node/IncomingPacket.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index bde5df71..41f3e47d 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -160,7 +160,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
case Packet::ERROR_IDENTITY_COLLISION:
// FIXME: for federation this will need a payload with a signature or something.
- if (RR->topology->isRoot(peer->identity()))
+ if (RR->topology->isUpstream(peer->identity()))
RR->node->postEvent(ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION);
break;
@@ -247,6 +247,10 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
if (peer->identity() != id) {
// Identity is different from the one we already have -- address collision
+ // Check rate limits
+ if (!RR->node->rateGateIdentityVerification(now,_path->address()))
+ return true;
+
uint8_t key[ZT_PEER_SECRET_KEY_LENGTH];
if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) {
if (dearmor(key)) { // ensure packet is authentic, otherwise drop
@@ -275,7 +279,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
// Continue at // VALID
}
- } // else 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
@@ -285,18 +289,23 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
return true;
}
- // Check that identity's address is valid as per the derivation function
- if (!id.locallyValidate()) {
- TRACE("dropped HELLO from %s(%s): identity invalid",id.address().toString().c_str(),_path->address().toString().c_str());
+ // Check rate limits
+ if (!RR->node->rateGateIdentityVerification(now,_path->address()))
return true;
- }
- // Check packet integrity and authentication
+ // 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,RR->identity,id));
if (!dearmor(newPeer->key())) {
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_path->address().toString().c_str());
return true;
}
+
+ // Check that identity's address is valid as per the derivation function
+ if (!id.locallyValidate()) {
+ TRACE("dropped HELLO from %s(%s): identity invalid",id.address().toString().c_str(),_path->address().toString().c_str());
+ return true;
+ }
+
peer = RR->topology->addPeer(newPeer);
// Continue at // VALID
@@ -508,11 +517,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
id.serialize(outp,false);
++count;
} else {
- // If I am not the root and don't know this identity, ask upstream. Downstream
- // peer may re-request in the future and if so we will be able to provide it.
- if (!RR->topology->amRoot())
- RR->sw->requestWhois(addr);
-
+ RR->sw->requestWhois(addr);
#ifdef ZT_ENABLE_CLUSTER
// Distribute WHOIS queries across a cluster if we do not know the ID.
// This may result in duplicate OKs to the querying peer, which is fine.
@@ -666,7 +671,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
}
}
- if ((flags & 0x10) != 0) {
+ if ((flags & 0x10) != 0) { // ACK requested
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
outp.append((uint8_t)Packet::VERB_EXT_FRAME);
outp.append((uint64_t)packetId());