RouterInfo.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #ifndef ROUTER_INFO_H__
  2. #define ROUTER_INFO_H__
  3. #include <inttypes.h>
  4. #include <string>
  5. #include <map>
  6. #include <vector>
  7. #include <list>
  8. #include <iostream>
  9. #include <boost/asio.hpp>
  10. #include <boost/shared_ptr.hpp>
  11. #include "Identity.h"
  12. #include "Profiling.h"
  13. namespace i2p
  14. {
  15. namespace data
  16. {
  17. const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
  18. const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
  19. const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
  20. const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
  21. const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";
  22. const char CAPS_FLAG_FLOODFILL = 'f';
  23. const char CAPS_FLAG_HIDDEN = 'H';
  24. const char CAPS_FLAG_REACHABLE = 'R';
  25. const char CAPS_FLAG_UNREACHABLE = 'U';
  26. /* bandwidth flags */
  27. const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; /* < 12 KBps */
  28. const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; /* 12-48 KBps */
  29. const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M'; /* 48-64 KBps */
  30. const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N'; /* 64-128 KBps */
  31. const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */
  32. const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
  33. const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */
  34. const char CAPS_FLAG_SSU_TESTING = 'B';
  35. const char CAPS_FLAG_SSU_INTRODUCER = 'C';
  36. const int MAX_RI_BUFFER_SIZE = 2048; // if RouterInfo exceeds 2048 we consider it as malformed, might be changed later
  37. class RouterInfo: public RoutingDestination
  38. {
  39. public:
  40. enum SupportedTranports
  41. {
  42. eNTCPV4 = 0x01,
  43. eNTCPV6 = 0x02,
  44. eSSUV4 = 0x04,
  45. eSSUV6 = 0x08,
  46. eNTCP2V4 = 0x10,
  47. eNTCP2V6 = 0x20
  48. };
  49. enum Caps
  50. {
  51. eFloodfill = 0x01,
  52. eHighBandwidth = 0x02,
  53. eExtraBandwidth = 0x04,
  54. eReachable = 0x08,
  55. eSSUTesting = 0x10,
  56. eSSUIntroducer = 0x20,
  57. eHidden = 0x40,
  58. eUnreachable = 0x80
  59. };
  60. enum TransportStyle
  61. {
  62. eTransportUnknown = 0,
  63. eTransportNTCP,
  64. eTransportSSU
  65. };
  66. typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
  67. struct Introducer
  68. {
  69. Introducer (): iExp (0) {};
  70. boost::asio::ip::address iHost;
  71. int iPort;
  72. IntroKey iKey;
  73. uint32_t iTag;
  74. uint32_t iExp;
  75. };
  76. struct SSUExt
  77. {
  78. int mtu;
  79. IntroKey key; // intro key for SSU
  80. std::vector<Introducer> introducers;
  81. };
  82. struct NTCP2Ext
  83. {
  84. Tag<32> staticKey;
  85. Tag<16> iv;
  86. bool isPublished = false;
  87. bool isNTCP2Only = false;
  88. };
  89. struct Address
  90. {
  91. TransportStyle transportStyle;
  92. boost::asio::ip::address host;
  93. int port;
  94. uint64_t date;
  95. uint8_t cost;
  96. std::unique_ptr<SSUExt> ssu; // not null for SSU
  97. std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2
  98. bool IsCompatible (const boost::asio::ip::address& other) const
  99. {
  100. return (host.is_v4 () && other.is_v4 ()) ||
  101. (host.is_v6 () && other.is_v6 ());
  102. }
  103. bool operator==(const Address& other) const
  104. {
  105. return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
  106. host == other.host && port == other.port;
  107. }
  108. bool operator!=(const Address& other) const
  109. {
  110. return !(*this == other);
  111. }
  112. bool IsNTCP2 () const { return (bool)ntcp2; };
  113. bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
  114. bool IsNTCP2Only () const { return ntcp2 && ntcp2->isNTCP2Only; };
  115. };
  116. typedef std::list<std::shared_ptr<Address> > Addresses;
  117. RouterInfo ();
  118. RouterInfo (const std::string& fullPath);
  119. RouterInfo (const RouterInfo& ) = default;
  120. RouterInfo& operator=(const RouterInfo& ) = default;
  121. RouterInfo (const uint8_t * buf, int len);
  122. ~RouterInfo ();
  123. std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
  124. void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
  125. std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
  126. uint64_t GetTimestamp () const { return m_Timestamp; };
  127. Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
  128. std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const;
  129. std::shared_ptr<const Address> GetNTCP2Address (bool publishedOnly, bool v4only = true) const;
  130. std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
  131. std::shared_ptr<const Address> GetSSUV6Address () const;
  132. void AddNTCPAddress (const char * host, int port);
  133. void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
  134. void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0);
  135. bool AddIntroducer (const Introducer& introducer);
  136. bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
  137. void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
  138. void DeleteProperty (const std::string& key); // called from RouterContext only
  139. std::string GetProperty (const std::string& key) const; // called from RouterContext only
  140. void ClearProperties () { m_Properties.clear (); };
  141. bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
  142. bool IsReachable () const { return m_Caps & Caps::eReachable; };
  143. bool IsNTCP (bool v4only = true) const;
  144. bool IsSSU (bool v4only = true) const;
  145. bool IsSSUV6 () const;
  146. bool IsNTCP2 (bool v4only = true) const;
  147. bool IsV6 () const;
  148. bool IsV4 () const;
  149. void EnableV6 ();
  150. void DisableV6 ();
  151. void EnableV4 ();
  152. void DisableV4 ();
  153. bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
  154. bool HasValidAddresses () const { return m_SupportedTransports; };
  155. bool UsesIntroducer () const;
  156. bool IsIntroducer () const { return m_Caps & eSSUIntroducer; };
  157. bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
  158. bool IsHidden () const { return m_Caps & eHidden; };
  159. bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
  160. bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
  161. uint8_t GetCaps () const { return m_Caps; };
  162. void SetCaps (uint8_t caps);
  163. void SetCaps (const char * caps);
  164. void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
  165. bool IsUnreachable () const { return m_IsUnreachable; };
  166. const uint8_t * GetBuffer () const { return m_Buffer; };
  167. const uint8_t * LoadBuffer (); // load if necessary
  168. int GetBufferLen () const { return m_BufferLen; };
  169. void CreateBuffer (const PrivateKeys& privateKeys);
  170. bool IsUpdated () const { return m_IsUpdated; };
  171. void SetUpdated (bool updated) { m_IsUpdated = updated; };
  172. bool SaveToFile (const std::string& fullPath);
  173. std::shared_ptr<RouterProfile> GetProfile () const;
  174. void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
  175. void Update (const uint8_t * buf, size_t len);
  176. void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
  177. bool IsNewer (const uint8_t * buf, size_t len) const;
  178. /** return true if we are in a router family and the signature is valid */
  179. bool IsFamily(const std::string & fam) const;
  180. // implements RoutingDestination
  181. std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
  182. void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
  183. bool IsDestination () const { return false; };
  184. private:
  185. bool LoadFile ();
  186. void ReadFromFile ();
  187. void ReadFromStream (std::istream& s);
  188. void ReadFromBuffer (bool verifySignature);
  189. void WriteToStream (std::ostream& s) const;
  190. size_t ReadString (char* str, size_t len, std::istream& s) const;
  191. void WriteString (const std::string& str, std::ostream& s) const;
  192. void ExtractCaps (const char * value);
  193. template<typename Filter>
  194. std::shared_ptr<const Address> GetAddress (Filter filter) const;
  195. void UpdateCapsProperty ();
  196. private:
  197. std::string m_FullPath, m_Family;
  198. std::shared_ptr<const IdentityEx> m_RouterIdentity;
  199. uint8_t * m_Buffer;
  200. size_t m_BufferLen;
  201. uint64_t m_Timestamp;
  202. boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
  203. std::map<std::string, std::string> m_Properties;
  204. bool m_IsUpdated, m_IsUnreachable;
  205. uint8_t m_SupportedTransports, m_Caps;
  206. mutable std::shared_ptr<RouterProfile> m_Profile;
  207. };
  208. }
  209. }
  210. #endif