summaryrefslogtreecommitdiff
path: root/zto/node/IncomingPacket.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'zto/node/IncomingPacket.hpp')
-rw-r--r--zto/node/IncomingPacket.hpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/zto/node/IncomingPacket.hpp b/zto/node/IncomingPacket.hpp
new file mode 100644
index 0000000..febff28
--- /dev/null
+++ b/zto/node/IncomingPacket.hpp
@@ -0,0 +1,144 @@
+/*
+ * ZeroTier One - Network Virtualization Everywhere
+ * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ZT_INCOMINGPACKET_HPP
+#define ZT_INCOMINGPACKET_HPP
+
+#include <stdexcept>
+
+#include "Packet.hpp"
+#include "Path.hpp"
+#include "Utils.hpp"
+#include "MulticastGroup.hpp"
+#include "Peer.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, in which case it is
+ * discarded as failed decode. Any exception thrown by tryDecode also causes
+ * the packet to be discarded.
+ *
+ * Thus a return of false from tryDecode() indicates that it should be called
+ * again. Logic is very simple as to when, and it's in doAnythingWaitingForPeer
+ * in Switch. This might be expanded to be more fine grained in the future.
+ *
+ * A return value of true indicates that the packet is done. tryDecode must
+ * never be called again after that.
+ */
+
+namespace ZeroTier {
+
+class RuntimeEnvironment;
+class Network;
+
+/**
+ * Subclass of packet that handles the decoding of it
+ */
+class IncomingPacket : public Packet
+{
+public:
+ IncomingPacket() :
+ Packet(),
+ _receiveTime(0)
+ {
+ }
+
+ /**
+ * Create a new packet-in-decode
+ *
+ * @param data Packet data
+ * @param len Packet length
+ * @param path Path over which packet arrived
+ * @param now Current time
+ * @throws std::out_of_range Range error processing packet
+ */
+ IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,uint64_t now) :
+ Packet(data,len),
+ _receiveTime(now),
+ _path(path)
+ {
+ }
+
+ /**
+ * Init packet-in-decode in place
+ *
+ * @param data Packet data
+ * @param len Packet length
+ * @param path Path over which packet arrived
+ * @param now Current time
+ * @throws std::out_of_range Range error processing packet
+ */
+ inline void init(const void *data,unsigned int len,const SharedPtr<Path> &path,uint64_t now)
+ {
+ copyFrom(data,len);
+ _receiveTime = now;
+ _path = path;
+ }
+
+ /**
+ * Attempt to decode this packet
+ *
+ * Note that this returns 'true' if processing is complete. This says nothing
+ * about whether the packet was valid. A rejection is 'complete.'
+ *
+ * Once true is returned, this must not be called again. The packet's state
+ * may no longer be valid.
+ *
+ * @param RR Runtime environment
+ * @return True if decoding and processing is complete, false if caller should try again
+ */
+ bool tryDecode(const RuntimeEnvironment *RR);
+
+ /**
+ * @return Time of packet receipt / start of decode
+ */
+ inline uint64_t receiveTime() const throw() { return _receiveTime; }
+
+private:
+ // These are called internally to handle packet contents once it has
+ // been authenticated, decrypted, decompressed, and classified.
+ bool _doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doHELLO(const RuntimeEnvironment *RR,const bool alreadyAuthenticated);
+ bool _doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doFRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doNETWORK_CONFIG(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+
+ void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid);
+
+ uint64_t _receiveTime;
+ SharedPtr<Path> _path;
+};
+
+} // namespace ZeroTier
+
+#endif