Work in progress...

This commit is contained in:
Adam Ierymenko 2013-09-25 10:55:27 -04:00
parent 5557a8192d
commit f3128a18fe
12 changed files with 218 additions and 138 deletions

View file

@ -37,20 +37,6 @@
#include "Filter.hpp"
#include "Service.hpp"
/*
* The big picture:
*
* tryDecode() gets called for a given fully-assembled packet until it returns
* true or the packet's time to live has been exceeded. The state machine must
* therefore be re-entrant if it ever returns false. Take care here!
*
* Stylistic note:
*
* There's a lot of unnecessary if nesting. It's mostly to allow TRACE to
* print informative messages on every possible reason something gets
* rejected or fails.
*/
namespace ZeroTier {
bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
@ -58,15 +44,15 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
{
if ((!encrypted())&&(verb() == Packet::VERB_HELLO)) {
// Unencrypted HELLOs are handled here since they are used to
// populate our identity cache in the first place. Thus we might get
// a HELLO for someone for whom we don't have a Peer record.
// populate our identity cache in the first place. _doHELLO() is special
// in that it contains its own authentication logic.
TRACE("HELLO from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
return _doHELLO(_r);
}
SharedPtr<Peer> peer = _r->topology->getPeer(source());
if (peer) {
// Resume saved state?
// Resume saved intermediate decode state?
if (_step == DECODE_WAITING_FOR_MULTICAST_FRAME_ORIGINAL_SENDER_LOOKUP) {
// In this state we have already authenticated and decrypted the
// packet and are waiting for the lookup of the original sender
@ -74,22 +60,10 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
return _doMULTICAST_FRAME(_r,peer);
}
// No saved state? Verify MAC before we proceed.
if (!macVerify(peer->macKey())) {
TRACE("dropped packet from %s(%s), authentication failed (size: %u)",source().toString().c_str(),_remoteAddress.toString().c_str(),size());
if (!dearmor(peer->key())) {
TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",source().toString().c_str(),_remoteAddress.toString().c_str(),size());
return true;
}
// If MAC authentication passed, decrypt and uncompress
if (encrypted()) {
decrypt(peer->cryptKey());
} else {
// Unencrypted is tolerated in case we want to run this on
// devices where squeezing out cycles matters. MAC is
// what's really important. But log it in debug to catch any
// packets being mistakenly sent in the clear.
TRACE("ODD: %s from %s(%s) wasn't encrypted",Packet::verbString(verb()),source().toString().c_str(),_remoteAddress.toString().c_str());
}
if (!uncompress()) {
TRACE("dropped packet from %s(%s), compressed data invalid",source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
@ -107,7 +81,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
TRACE("NOP from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
case Packet::VERB_HELLO:
return _doHELLO(_r);
return _doHELLO(_r); // legal, but why? :)
case Packet::VERB_ERROR:
return _doERROR(_r,peer);
case Packet::VERB_OK:
@ -120,6 +94,8 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
return _doFRAME(_r,peer);
case Packet::VERB_MULTICAST_LIKE:
return _doMULTICAST_LIKE(_r,peer);
case Packet::VERB_MULTICAST_GOT:
return _doMULTICAST_GOT(_r,peer);
case Packet::VERB_MULTICAST_FRAME:
return _doMULTICAST_FRAME(_r,peer);
case Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE:
@ -474,6 +450,25 @@ bool PacketDecoder::_doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedP
} catch ( ... ) {
TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
}
return true;
}
bool PacketDecoder::_doMULTICAST_GOT(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
{
// Right now only supernodes act as propagation hubs
if (!_r->topology->amSupernode()) {
TRACE("dropped MULTICAST_GOT from %s: I am not a supernode",source().toString().c_str());
return true;
}
try {
} catch (std::exception &ex) {
TRACE("dropped MULTICAST_GOT from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
TRACE("dropped MULTICAST_GOT from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
}
return true;
}