Topology.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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: 2024-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. #ifndef ZT_TOPOLOGY_HPP
  14. #define ZT_TOPOLOGY_HPP
  15. #include "Constants.hpp"
  16. #include "Address.hpp"
  17. #include "Identity.hpp"
  18. #include "Peer.hpp"
  19. #include "Path.hpp"
  20. #include "Mutex.hpp"
  21. #include "InetAddress.hpp"
  22. #include "SharedPtr.hpp"
  23. #include "ScopedPtr.hpp"
  24. #include "Fingerprint.hpp"
  25. #include "Blob.hpp"
  26. #include "FCV.hpp"
  27. #include "Certificate.hpp"
  28. #include "Containers.hpp"
  29. namespace ZeroTier {
  30. class RuntimeEnvironment;
  31. /**
  32. * Database of network topology
  33. */
  34. class Topology
  35. {
  36. public:
  37. Topology(const RuntimeEnvironment *renv, void *tPtr, int64_t now);
  38. /**
  39. * Add peer to database
  40. *
  41. * This will not replace existing peers. In that case the existing peer
  42. * record is returned.
  43. *
  44. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  45. * @param peer Peer to add
  46. * @return New or existing peer (should replace 'peer')
  47. */
  48. SharedPtr< Peer > add(void *tPtr, const SharedPtr< Peer > &peer);
  49. /**
  50. * Get a peer from its address
  51. *
  52. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  53. * @param zta ZeroTier address of peer
  54. * @param loadFromCached If false do not load from cache if not in memory (default: true)
  55. * @return Peer or NULL if not found
  56. */
  57. ZT_INLINE SharedPtr< Peer > peer(void *tPtr, const Address &zta, const bool loadFromCached = true)
  58. {
  59. {
  60. RWMutex::RLock l(m_peers_l);
  61. Map< Address, SharedPtr< Peer > >::const_iterator ap(m_peers.find(zta));
  62. if (likely(ap != m_peers.end()))
  63. return ap->second;
  64. }
  65. if (loadFromCached)
  66. return m_peerFromCached(tPtr, zta);
  67. return SharedPtr< Peer >();
  68. }
  69. /**
  70. * Get a Path object for a given local and remote physical address, creating if needed
  71. *
  72. * @param l Local socket
  73. * @param r Remote address
  74. * @return Pointer to canonicalized Path object or NULL on error
  75. */
  76. ZT_INLINE SharedPtr< Path > path(const int64_t l, const InetAddress &r)
  77. {
  78. const UniqueID k(r.key());
  79. {
  80. RWMutex::RLock lck(m_paths_l);
  81. Map< UniqueID, SharedPtr< Path > >::const_iterator p(m_paths.find(k));
  82. if (likely(p != m_paths.end()))
  83. return p->second;
  84. }
  85. {
  86. SharedPtr< Path > p(new Path(l, r));
  87. RWMutex::Lock lck(m_paths_l);
  88. SharedPtr< Path > &p2 = m_paths[k];
  89. if (p2)
  90. return p2;
  91. p2 = p;
  92. return p;
  93. }
  94. }
  95. /**
  96. * @return Current best root server
  97. */
  98. ZT_INLINE SharedPtr< Peer > root() const
  99. {
  100. RWMutex::RLock l(m_roots_l);
  101. if (unlikely(m_rootPeers.empty()))
  102. return SharedPtr< Peer >();
  103. return m_rootPeers.front();
  104. }
  105. /**
  106. * @param id Identity to check
  107. * @return True if this identity corresponds to a root
  108. */
  109. ZT_INLINE bool isRoot(const Identity &id) const
  110. {
  111. RWMutex::RLock l(m_roots_l);
  112. return (m_roots.find(id) != m_roots.end());
  113. }
  114. /**
  115. * Apply a function or function object to all peers
  116. *
  117. * This locks the peer map during execution, so calls to get() etc. during
  118. * eachPeer() will deadlock.
  119. *
  120. * @param f Function to apply
  121. * @tparam F Function or function object type
  122. */
  123. template< typename F >
  124. ZT_INLINE void eachPeer(F f) const
  125. {
  126. RWMutex::RLock l(m_peers_l);
  127. for (Map< Address, SharedPtr< Peer > >::const_iterator i(m_peers.begin()); i != m_peers.end(); ++i)
  128. f(i->second);
  129. }
  130. /**
  131. * @param allPeers vector to fill with all current peers
  132. */
  133. ZT_INLINE void getAllPeers(Vector< SharedPtr< Peer > > &allPeers) const
  134. {
  135. allPeers.clear();
  136. RWMutex::RLock l(m_peers_l);
  137. allPeers.reserve(m_peers.size());
  138. for (Map< Address, SharedPtr< Peer > >::const_iterator i(m_peers.begin()); i != m_peers.end(); ++i)
  139. allPeers.push_back(i->second);
  140. }
  141. /**
  142. * @param allPeers vector to fill with all current peers
  143. */
  144. ZT_INLINE void getAllPeers(Vector< SharedPtr< Peer > > &allPeers, Vector< SharedPtr< Peer > > &rootPeers) const
  145. {
  146. allPeers.clear();
  147. RWMutex::RLock l(m_peers_l);
  148. allPeers.reserve(m_peers.size());
  149. for (Map< Address, SharedPtr< Peer > >::const_iterator i(m_peers.begin()); i != m_peers.end(); ++i)
  150. allPeers.push_back(i->second);
  151. rootPeers = m_rootPeers;
  152. }
  153. /**
  154. * Flag a peer as a root, adding the peer if it is not known
  155. *
  156. * @param tPtr Thread pointer
  157. * @param id Root identity (will be locally validated)
  158. * @return Root peer or NULL if some problem occurred
  159. */
  160. SharedPtr< Peer > addRoot(void *tPtr, const Identity &id);
  161. /**
  162. * Remove a root server's identity from the root server set
  163. *
  164. * @param tPtr Thread pointer
  165. * @param address Root address
  166. * @return True if root found and removed, false if not found
  167. */
  168. bool removeRoot(void *tPtr, Address address);
  169. /**
  170. * Sort roots in ascending order of apparent latency
  171. *
  172. * @param now Current time
  173. */
  174. void rankRoots();
  175. /**
  176. * Do periodic tasks such as database cleanup
  177. *
  178. * @param tPtr Thread pointer
  179. * @param now Current time
  180. */
  181. void doPeriodicTasks(void *tPtr, int64_t now);
  182. /**
  183. * Save all currently known peers to data store
  184. *
  185. * @param tPtr Thread pointer
  186. */
  187. void saveAll(void *tPtr);
  188. /**
  189. * Add a certificate to the local certificate store
  190. *
  191. * @param tPtr Thread pointer
  192. * @param cert Certificate to add (a copy will be made if added)
  193. * @param now Current time
  194. * @param localTrust Local trust bit flags
  195. * @param writeToLocalStore If true, write to local object store (via API callbacks)
  196. * @param refreshRootSets If true, refresh root sets in case a root set changed (default: true)
  197. * @param verify If true, verify certificate and certificate chain (default: true)
  198. * @return Error or 0 on success
  199. */
  200. ZT_CertificateError addCertificate(void *tPtr, const Certificate &cert, const int64_t now, unsigned int localTrust, bool writeToLocalStore, bool refreshRootSets = true, bool verify = true);
  201. private:
  202. void m_eraseCertificate_l_certs(const SharedPtr< const Certificate > &cert);
  203. bool m_cleanCertificates_l_certs(int64_t now);
  204. bool m_verifyCertificateChain_l_certs(const Certificate *current, const int64_t now) const;
  205. ZT_CertificateError m_verifyCertificate_l_certs(const Certificate &cert, const int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
  206. void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
  207. SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
  208. void m_updateRootPeers_l_roots_certs(void *tPtr);
  209. void m_writeTrustStore_l_roots_certs(void *tPtr) const;
  210. const RuntimeEnvironment *const RR;
  211. RWMutex m_paths_l; // m_paths
  212. RWMutex m_peers_l; // m_peers
  213. RWMutex m_roots_l; // m_roots, m_rootPeers
  214. Mutex m_certs_l; // m_certs, m_certsBySubjectIdentity
  215. Map< UniqueID, SharedPtr< Path > > m_paths;
  216. Map< Address, SharedPtr< Peer > > m_peers;
  217. Map< Identity, Set< SharedPtr< const Certificate > > > m_roots;
  218. Vector< SharedPtr< Peer > > m_rootPeers;
  219. Map< SHA384Hash, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certs;
  220. Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectIdentity;
  221. SortedMap< Vector< uint8_t >, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectUniqueId;
  222. };
  223. } // namespace ZeroTier
  224. #endif