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