1 /*
2  * Copyright (c)2013-2020 ZeroTier, Inc.
3  *
4  * Use of this software is governed by the Business Source License included
5  * in the LICENSE.TXT file in the project's root directory.
6  *
7  * Change Date: 2025-01-01
8  *
9  * On the date above, in accordance with the Business Source License, use
10  * of this software will be governed by version 2.0 of the Apache License.
11  */
12 /****/
13 
14 #ifndef ZT_INCOMINGPACKET_HPP
15 #define ZT_INCOMINGPACKET_HPP
16 
17 #include <stdexcept>
18 
19 #include "Packet.hpp"
20 #include "Path.hpp"
21 #include "Utils.hpp"
22 #include "MulticastGroup.hpp"
23 #include "Peer.hpp"
24 
25 /*
26  * The big picture:
27  *
28  * tryDecode gets called for a given fully-assembled packet until it returns
29  * true or the packet's time to live has been exceeded, in which case it is
30  * discarded as failed decode. Any exception thrown by tryDecode also causes
31  * the packet to be discarded.
32  *
33  * Thus a return of false from tryDecode() indicates that it should be called
34  * again. Logic is very simple as to when, and it's in doAnythingWaitingForPeer
35  * in Switch. This might be expanded to be more fine grained in the future.
36  *
37  * A return value of true indicates that the packet is done. tryDecode must
38  * never be called again after that.
39  */
40 
41 namespace ZeroTier {
42 
43 class RuntimeEnvironment;
44 class Network;
45 
46 /**
47  * Subclass of packet that handles the decoding of it
48  */
49 class IncomingPacket : public Packet
50 {
51 public:
IncomingPacket()52 	IncomingPacket() :
53 		Packet(),
54 		_receiveTime(0)
55 	{
56 	}
57 
58 	/**
59 	 * Create a new packet-in-decode
60 	 *
61 	 * @param data Packet data
62 	 * @param len Packet length
63 	 * @param path Path over which packet arrived
64 	 * @param now Current time
65 	 * @throws std::out_of_range Range error processing packet
66 	 */
IncomingPacket(const void * data,unsigned int len,const SharedPtr<Path> & path,int64_t now)67 	IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
68 		Packet(data,len),
69 		_receiveTime(now),
70 		_path(path)
71 	{
72 	}
73 
74 	/**
75 	 * Init packet-in-decode in place
76 	 *
77 	 * @param data Packet data
78 	 * @param len Packet length
79 	 * @param path Path over which packet arrived
80 	 * @param now Current time
81 	 * @throws std::out_of_range Range error processing packet
82 	 */
init(const void * data,unsigned int len,const SharedPtr<Path> & path,int64_t now)83 	inline void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now)
84 	{
85 		copyFrom(data,len);
86 		_receiveTime = now;
87 		_path = path;
88 	}
89 
90 	/**
91 	 * Attempt to decode this packet
92 	 *
93 	 * Note that this returns 'true' if processing is complete. This says nothing
94 	 * about whether the packet was valid. A rejection is 'complete.'
95 	 *
96 	 * Once true is returned, this must not be called again. The packet's state
97 	 * may no longer be valid.
98 	 *
99 	 * @param RR Runtime environment
100 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
101 	 * @return True if decoding and processing is complete, false if caller should try again
102 	 */
103 	bool tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t flowId);
104 
105 	/**
106 	 * @return Time of packet receipt / start of decode
107 	 */
receiveTime() const108 	inline uint64_t receiveTime() const { return _receiveTime; }
109 
110 private:
111 	// These are called internally to handle packet contents once it has
112 	// been authenticated, decrypted, decompressed, and classified.
113 	bool _doERROR(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
114 	bool _doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated);
115 	bool _doQOS_MEASUREMENT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
116 	bool _doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
117 	bool _doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
118 	bool _doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
119 	bool _doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,int32_t flowId);
120 	bool _doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,int32_t flowId);
121 	bool _doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
122 	bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
123 	bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
124 	bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
125 	bool _doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
126 	bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
127 	bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
128 	bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
129 	bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
130 	bool _doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
131 	bool _doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
132 
133 	void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid);
134 
135 	uint64_t _receiveTime;
136 	SharedPtr<Path> _path;
137 };
138 
139 } // namespace ZeroTier
140 
141 #endif
142