1 /* 2 * Copyright (c) 2013-2021, The PurpleI2P Project 3 * 4 * This file is part of Purple i2pd project and licensed under BSD3 5 * 6 * See full license text in LICENSE file at top of project tree 7 */ 8 9 #ifndef TUNNEL_ENDPOINT_H__ 10 #define TUNNEL_ENDPOINT_H__ 11 12 #include <inttypes.h> 13 #include <vector> 14 #include <string> 15 #include <unordered_map> 16 #include "I2NPProtocol.h" 17 #include "TunnelBase.h" 18 19 namespace i2p 20 { 21 namespace tunnel 22 { 23 class TunnelEndpoint 24 { 25 struct TunnelMessageBlockEx: public TunnelMessageBlock 26 { 27 uint64_t receiveTime; // milliseconds since epoch 28 uint8_t nextFragmentNum; 29 }; 30 31 struct Fragment 32 { FragmentFragment33 Fragment (bool last, uint64_t t, size_t size): isLastFragment (last), receiveTime (t), data (size) {}; 34 bool isLastFragment; 35 uint64_t receiveTime; // milliseconds since epoch 36 std::vector<uint8_t> data; 37 }; 38 39 public: 40 TunnelEndpoint(bool isInbound)41 TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0), m_CurrentMsgID (0) {}; 42 ~TunnelEndpoint (); GetNumReceivedBytes()43 size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; 44 void Cleanup (); 45 46 void HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg); 47 48 private: 49 50 void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, uint8_t fragmentNum, const uint8_t * fragment, size_t size); 51 bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success 52 void HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment); 53 void HandleNextMessage (const TunnelMessageBlock& msg); 54 55 void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, const uint8_t * fragment, size_t size); 56 bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added 57 void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg); 58 void AddIncompleteCurrentMessage (); 59 60 private: 61 62 std::unordered_map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages; 63 std::unordered_map<uint64_t, std::unique_ptr<Fragment> > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment 64 bool m_IsInbound; 65 size_t m_NumReceivedBytes; 66 TunnelMessageBlockEx m_CurrentMessage; 67 uint32_t m_CurrentMsgID; 68 }; 69 } 70 } 71 72 #endif 73