Bit of comment and if nesting cleanup in PacketDecoder.

This commit is contained in:
Adam Ierymenko 2013-08-06 10:39:20 -04:00
parent b342f56bec
commit 499ac2699f

View File

@ -46,8 +46,7 @@
* *
* There's a lot of unnecessary if nesting. It's mostly to allow TRACE to * There's a lot of unnecessary if nesting. It's mostly to allow TRACE to
* print informative messages on every possible reason something gets * print informative messages on every possible reason something gets
* rejected or fails. Sometimes it also makes code more explicit and thus * rejected or fails.
* easier to understand.
*/ */
namespace ZeroTier { namespace ZeroTier {
@ -79,6 +78,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
return true; return true;
} }
// If MAC authentication passed, decrypt and uncompress
if (encrypted()) { if (encrypted()) {
decrypt(peer->cryptKey()); decrypt(peer->cryptKey());
} else { } else {
@ -88,7 +88,6 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
// packets being mistakenly sent in the clear. // 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()); TRACE("ODD: %s from %s(%s) wasn't encrypted",Packet::verbString(verb()),source().toString().c_str(),_remoteAddress.toString().c_str());
} }
if (!uncompress()) { if (!uncompress()) {
TRACE("dropped packet from %s(%s), compressed data invalid",source().toString().c_str(),_remoteAddress.toString().c_str()); TRACE("dropped packet from %s(%s), compressed data invalid",source().toString().c_str(),_remoteAddress.toString().c_str());
return true; return true;
@ -146,41 +145,45 @@ void PacketDecoder::_CBaddPeerFromHello(void *arg,const SharedPtr<Peer> &p,Topol
_CBaddPeerFromHello_Data *req = (_CBaddPeerFromHello_Data *)arg; _CBaddPeerFromHello_Data *req = (_CBaddPeerFromHello_Data *)arg;
const RuntimeEnvironment *_r = req->renv; const RuntimeEnvironment *_r = req->renv;
switch(result) { try {
case Topology::PEER_VERIFY_ACCEPTED_NEW: switch(result) {
case Topology::PEER_VERIFY_ACCEPTED_ALREADY_HAVE: case Topology::PEER_VERIFY_ACCEPTED_NEW:
case Topology::PEER_VERIFY_ACCEPTED_DISPLACED_INVALID_ADDRESS: { case Topology::PEER_VERIFY_ACCEPTED_ALREADY_HAVE:
_r->sw->doAnythingWaitingForPeer(p); case Topology::PEER_VERIFY_ACCEPTED_DISPLACED_INVALID_ADDRESS: {
_r->sw->doAnythingWaitingForPeer(p);
Packet outp(req->source,_r->identity.address(),Packet::VERB_OK); Packet outp(req->source,_r->identity.address(),Packet::VERB_OK);
outp.append((unsigned char)Packet::VERB_HELLO); outp.append((unsigned char)Packet::VERB_HELLO);
outp.append(req->helloPacketId); outp.append(req->helloPacketId);
outp.append(req->helloTimestamp); outp.append(req->helloTimestamp);
outp.encrypt(p->cryptKey()); outp.encrypt(p->cryptKey());
outp.hmacSet(p->macKey()); outp.hmacSet(p->macKey());
_r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1); _r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1);
} break; } break;
case Topology::PEER_VERIFY_REJECTED_INVALID_IDENTITY: { case Topology::PEER_VERIFY_REJECTED_INVALID_IDENTITY: {
Packet outp(req->source,_r->identity.address(),Packet::VERB_ERROR); Packet outp(req->source,_r->identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_HELLO); outp.append((unsigned char)Packet::VERB_HELLO);
outp.append(req->helloPacketId); outp.append(req->helloPacketId);
outp.append((unsigned char)Packet::ERROR_IDENTITY_INVALID); outp.append((unsigned char)Packet::ERROR_IDENTITY_INVALID);
outp.encrypt(p->cryptKey()); outp.encrypt(p->cryptKey());
outp.hmacSet(p->macKey()); outp.hmacSet(p->macKey());
_r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1); _r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1);
} break; } break;
case Topology::PEER_VERIFY_REJECTED_DUPLICATE: case Topology::PEER_VERIFY_REJECTED_DUPLICATE:
case Topology::PEER_VERIFY_REJECTED_DUPLICATE_TRIAGED: { case Topology::PEER_VERIFY_REJECTED_DUPLICATE_TRIAGED: {
Packet outp(req->source,_r->identity.address(),Packet::VERB_ERROR); Packet outp(req->source,_r->identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_HELLO); outp.append((unsigned char)Packet::VERB_HELLO);
outp.append(req->helloPacketId); outp.append(req->helloPacketId);
outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION);
outp.encrypt(p->cryptKey()); outp.encrypt(p->cryptKey());
outp.hmacSet(p->macKey()); outp.hmacSet(p->macKey());
_r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1); _r->demarc->send(req->localPort,req->remoteAddress,outp.data(),outp.size(),-1);
} break; } break;
}
} catch ( ... ) {
TRACE("unexpected exception in addPeer() result callback for peer received via HELLO");
} }
delete req; delete req;
@ -188,14 +191,19 @@ void PacketDecoder::_CBaddPeerFromHello(void *arg,const SharedPtr<Peer> &p,Topol
void PacketDecoder::_CBaddPeerFromWhois(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result) void PacketDecoder::_CBaddPeerFromWhois(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result)
{ {
switch(result) { const RuntimeEnvironment *_r = (const RuntimeEnvironment *)arg;
case Topology::PEER_VERIFY_ACCEPTED_NEW: try {
case Topology::PEER_VERIFY_ACCEPTED_ALREADY_HAVE: switch(result) {
case Topology::PEER_VERIFY_ACCEPTED_DISPLACED_INVALID_ADDRESS: case Topology::PEER_VERIFY_ACCEPTED_NEW:
((const RuntimeEnvironment *)arg)->sw->doAnythingWaitingForPeer(p); case Topology::PEER_VERIFY_ACCEPTED_ALREADY_HAVE:
break; case Topology::PEER_VERIFY_ACCEPTED_DISPLACED_INVALID_ADDRESS:
default: _r->sw->doAnythingWaitingForPeer(p);
break; break;
default:
break;
}
} catch ( ... ) {
TRACE("unexpected exception in addPeer() result callback for peer received via OK(WHOIS)");
} }
} }
@ -377,20 +385,20 @@ bool PacketDecoder::_doWHOIS(const RuntimeEnvironment *_r,const SharedPtr<Peer>
bool PacketDecoder::_doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer) bool PacketDecoder::_doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
{ {
try { try {
// /*
// At the moment, we only obey RENDEZVOUS if it comes from a designated * At the moment, we only obey RENDEZVOUS if it comes from a designated
// supernode. If relay offloading is implemented to scale the net, this * supernode. If relay offloading is implemented to scale the net, this
// will need reconsideration. * will need reconsideration.
// *
// The reason is that RENDEZVOUS could technically be used to cause a * The reason is that RENDEZVOUS could technically be used to cause a
// peer to send a weird encrypted UDP packet to an arbitrary IP:port. * peer to send a weird encrypted UDP packet to an arbitrary IP:port.
// The sender of RENDEZVOUS has no control over the content of this * The sender of RENDEZVOUS has no control over the content of this
// packet, but it's still maybe something we want to not allow just * packet, but it's still maybe something we want to not allow just
// anyone to order due to possible DDOS or network forensic implications. * anyone to order due to possible DDOS or network forensic implications.
// So if we diversify relays, we'll need some way of deciding whether the * So if we diversify relays, we'll need some way of deciding whether the
// sender is someone we should trust with a RENDEZVOUS hint. Or maybe * sender is someone we should trust with a RENDEZVOUS hint. Or maybe
// we just need rate limiting to prevent DDOS and amplification attacks. * we just need rate limiting to prevent DDOS and amplification attacks.
// */
if (_r->topology->isSupernode(source())) { if (_r->topology->isSupernode(source())) {
Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
SharedPtr<Peer> withPeer(_r->topology->getPeer(with)); SharedPtr<Peer> withPeer(_r->topology->getPeer(with));
@ -455,20 +463,15 @@ bool PacketDecoder::_doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedP
while ((ptr + 18) <= size()) { while ((ptr + 18) <= size()) {
uint64_t nwid = at<uint64_t>(ptr); ptr += 8; uint64_t nwid = at<uint64_t>(ptr); ptr += 8;
SharedPtr<Network> network(_r->nc->network(nwid)); SharedPtr<Network> network(_r->nc->network(nwid));
if (network) { if ((network)&&(network->isAllowed(source()))) {
if (network->isAllowed(source())) { MAC mac(field(ptr,6)); ptr += 6;
MAC mac(field(ptr,6)); ptr += 6; uint32_t adi = at<uint32_t>(ptr); ptr += 4;
uint32_t adi = at<uint32_t>(ptr); ptr += 4; //TRACE("peer %s likes multicast group %s:%.8lx on network %llu",source().toString().c_str(),mac.toString().c_str(),(unsigned long)adi,nwid);
//TRACE("peer %s likes multicast group %s:%.8lx on network %llu",source().toString().c_str(),mac.toString().c_str(),(unsigned long)adi,nwid); _r->multicaster->likesMulticastGroup(nwid,MulticastGroup(mac,adi),source(),now);
_r->multicaster->likesMulticastGroup(nwid,MulticastGroup(mac,adi),source(),now); ++numAccepted;
++numAccepted;
} else {
ptr += 10;
TRACE("ignored MULTICAST_LIKE from %s(%s): not a member of closed network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
}
} else { } else {
ptr += 10; ptr += 10;
TRACE("ignored MULTICAST_LIKE from %s(%s): network %.16llx unknown or we are not a member",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid); TRACE("ignored MULTICAST_LIKE from %s(%s): network %.16llx unknown, or sender is not a member of network",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
} }
} }