diff --git a/node/AntiRecursion.hpp b/node/AntiRecursion.hpp deleted file mode 100644 index 78ee95c2b..000000000 --- a/node/AntiRecursion.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef ZT_ANTIRECURSION_HPP -#define ZT_ANTIRECURSION_HPP - -#include -#include - -#include "Constants.hpp" - -namespace ZeroTier { - -/** - * Size of anti-recursion history - */ -#define ZT_ANTIRECURSION_HISTORY_SIZE 16 - -/** - * Filter to prevent recursion (ZeroTier-over-ZeroTier) - * - * This works by logging ZeroTier packets that we send. It's then invoked - * again against packets read from local Ethernet taps. If the last 32 - * bytes representing the ZeroTier packet match in the tap frame, then - * the frame is a re-injection of a frame that we sent and is rejected. - * - * This means that ZeroTier packets simply will not traverse ZeroTier - * networks, which would cause all sorts of weird problems. - * - * This is highly optimized code since it's checked for every packet. - */ -class AntiRecursion -{ -public: - AntiRecursion() - { - for(int i=0;i(data) + (len - 32),32); -#else - uint64_t *t = _history[++_ptr % ZT_ANTIRECURSION_HISTORY_SIZE].tail; - const uint64_t *p = reinterpret_cast(reinterpret_cast(data) + (len - 32)); - *(t++) = *(p++); - *(t++) = *(p++); - *(t++) = *(p++); - *t = *p; -#endif - } - - /** - * Check an ethernet frame from a local tap against anti-recursion history - * - * @param data Raw frame data - * @param len Length of frame - * @return True if frame is OK to be passed, false if it's a ZT frame that we sent - */ - inline bool checkEthernetFrame(const void *const data,const unsigned int len) const - { - if (len < 32) - return true; - const uint8_t *const pp = reinterpret_cast(data) + (len - 32); - const _ArItem *i = _history; - const _ArItem *const end = i + ZT_ANTIRECURSION_HISTORY_SIZE; - while (i != end) { -#ifdef ZT_NO_TYPE_PUNNING - if (!memcmp(pp,i->tail,32)) { - return false; - } -#else - const uint64_t *t = i->tail; - const uint64_t *p = reinterpret_cast(pp); - uint64_t bits = *(t++) ^ *(p++); - bits |= *(t++) ^ *(p++); - bits |= *(t++) ^ *(p++); - bits |= *t ^ *p; - if (!bits) { - return false; - } -#endif - ++i; - } - return true; - } - -private: - struct _ArItem { uint64_t tail[4]; }; - _ArItem _history[ZT_ANTIRECURSION_HISTORY_SIZE]; - volatile unsigned long _ptr; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index c71c67906..5c9279ddd 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -45,7 +45,6 @@ #include "World.hpp" #include "Cluster.hpp" #include "Node.hpp" -#include "AntiRecursion.hpp" #include "DeferredPackets.hpp" namespace ZeroTier { @@ -163,7 +162,6 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); nconf->com().serialize(outp); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } @@ -250,7 +248,6 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,SharedPtr &peer outp.append((uint64_t)pid); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.armor(key,true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } else { TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); @@ -346,7 +343,6 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,SharedPtr &peer } outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version @@ -484,7 +480,6 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append(packetId()); queried.serialize(outp,false); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } else { #ifdef ZT_ENABLE_CLUSTER @@ -645,7 +640,6 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,const SharedPtr if (size() > ZT_PACKET_IDX_PAYLOAD) outp.append(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); peer->received(_localAddress,_remoteAddress,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP); } catch ( ... ) { @@ -723,7 +717,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { // sanity check TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length()); } else { - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } @@ -736,7 +729,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(nwid); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } break; @@ -747,7 +739,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_); outp.append(nwid); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } break; @@ -770,7 +761,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } catch ( ... ) { @@ -816,7 +806,6 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit); if (gatheredLocally) { outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } @@ -910,7 +899,6 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share outp.append((unsigned char)0x02); // flag 0x02 = contains gather results if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } @@ -1221,7 +1209,6 @@ bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const outp.append((uint16_t)sizeof(result)); outp.append(result,sizeof(result)); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } else { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); @@ -1229,7 +1216,6 @@ bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const outp.append(pid); outp.append((unsigned char)Packet::ERROR_INVALID_REQUEST); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } break; @@ -1335,7 +1321,6 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } diff --git a/node/Node.cpp b/node/Node.cpp index 7e4ad642c..19675bb54 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -39,7 +39,6 @@ #include "NetworkController.hpp" #include "Switch.hpp" #include "Multicaster.hpp" -#include "AntiRecursion.hpp" #include "Topology.hpp" #include "Buffer.hpp" #include "Packet.hpp" @@ -114,7 +113,6 @@ Node::Node( try { RR->sw = new Switch(RR); RR->mc = new Multicaster(RR); - RR->antiRec = new AntiRecursion(); RR->topology = new Topology(RR); RR->sa = new SelfAwareness(RR); RR->dp = new DeferredPackets(RR); @@ -122,7 +120,6 @@ Node::Node( delete RR->dp; delete RR->sa; delete RR->topology; - delete RR->antiRec; delete RR->mc; delete RR->sw; throw; @@ -141,7 +138,6 @@ Node::~Node() delete RR->dp; delete RR->sa; delete RR->topology; - delete RR->antiRec; delete RR->mc; delete RR->sw; #ifdef ZT_ENABLE_CLUSTER diff --git a/node/Path.cpp b/node/Path.cpp index c67352de8..6f595189a 100644 --- a/node/Path.cpp +++ b/node/Path.cpp @@ -26,7 +26,6 @@ */ #include "Path.hpp" -#include "AntiRecursion.hpp" #include "RuntimeEnvironment.hpp" #include "Node.hpp" @@ -34,7 +33,6 @@ namespace ZeroTier { bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - RR->antiRec->logOutgoingZT(data,len); if (RR->node->putPacket(_localAddress,address(),data,len)) { sent(now); return true; diff --git a/node/Peer.cpp b/node/Peer.cpp index 0db3e8a08..04e5bdf0b 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -32,7 +32,6 @@ #include "Node.hpp" #include "Switch.hpp" #include "Network.hpp" -#include "AntiRecursion.hpp" #include "SelfAwareness.hpp" #include "Cluster.hpp" #include "Packet.hpp" @@ -104,7 +103,6 @@ void Peer::received( } outp.append((uint16_t)redirectTo.port()); outp.armor(_key,true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } else { // For older peers we use RENDEZVOUS to coax them into contacting us elsewhere. @@ -120,7 +118,6 @@ void Peer::received( outp.append(redirectTo.rawIpData(),16); } outp.armor(_key,true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } suboptimalPath = true; @@ -199,7 +196,6 @@ void Peer::received( // 1.1.1 and newer nodes support ECHO, which is smaller -- but 1.1.0 has a bug so use HELLO there too Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO); outp.armor(_key,true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } else { sendHELLO(localAddr,remoteAddr,now); @@ -233,7 +229,6 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u outp.append((uint64_t)RR->topology->worldTimestamp()); outp.armor(_key,false); // HELLO is sent in the clear - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size(),ttl); } diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index 4846c9dfa..c9990c4ac 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -41,7 +41,6 @@ class Switch; class Topology; class Node; class Multicaster; -class AntiRecursion; class NetworkController; class SelfAwareness; class Cluster; @@ -59,7 +58,6 @@ public: ,localNetworkController((NetworkController *)0) ,sw((Switch *)0) ,mc((Multicaster *)0) - ,antiRec((AntiRecursion *)0) ,topology((Topology *)0) ,sa((SelfAwareness *)0) ,dp((DeferredPackets *)0) @@ -91,7 +89,6 @@ public: Switch *sw; Multicaster *mc; - AntiRecursion *antiRec; Topology *topology; SelfAwareness *sa; DeferredPackets *dp; diff --git a/node/Switch.cpp b/node/Switch.cpp index a9885a29b..9ef8611aa 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -42,7 +42,6 @@ #include "InetAddress.hpp" #include "Topology.hpp" #include "Peer.hpp" -#include "AntiRecursion.hpp" #include "SelfAwareness.hpp" #include "Packet.hpp" #include "Cluster.hpp" @@ -97,7 +96,6 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from _lastBeaconResponse = now; Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); outp.armor(peer->key(),true); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,fromAddr,outp.data(),outp.size()); } } @@ -125,15 +123,6 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c if (to == network->mac()) return; - /* Check anti-recursion module to ensure that this is not ZeroTier talking over its own links. - * Note: even when we introduce a more purposeful binding of the main UDP port, this can - * still happen because Windows likes to send broadcasts over interfaces that have little - * to do with their intended target audience. :P */ - if (!RR->antiRec->checkEthernetFrame(data,len)) { - TRACE("%.16llx: rejected recursively addressed ZeroTier packet by tail match (type %s, length: %u)",network->id(),etherTypeName(etherType),len); - return; - } - // Check to make sure this protocol is allowed on this network if (!nconf->permitsEtherType(etherType)) { TRACE("%.16llx: ignored tap: %s -> %s: ethertype %s not allowed on network %.16llx",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),(unsigned long long)network->id());