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