Topology.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. #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. return m_newPath(l, r, k);
  86. }
  87. /**
  88. * @return Current best root (lowest latency active root)
  89. */
  90. ZT_INLINE SharedPtr< Peer > root(const int64_t now)
  91. {
  92. RWMutex::RMaybeWLock l(m_roots_l);
  93. if (unlikely(m_roots.empty()))
  94. return SharedPtr< Peer >();
  95. if (unlikely((now - m_lastRankedRoots) > (ZT_PATH_KEEPALIVE_PERIOD / 2))) {
  96. l.writing();
  97. m_rankRoots(now);
  98. }
  99. return m_roots.front();
  100. }
  101. /**
  102. * @param allPeers vector to fill with all current peers
  103. */
  104. void allPeers(Vector< SharedPtr< Peer > > &allPeers, Vector< SharedPtr< Peer > > &rootPeers) const;
  105. /**
  106. * Do periodic tasks such as database cleanup
  107. *
  108. * @param tPtr Thread pointer
  109. * @param now Current time
  110. */
  111. void doPeriodicTasks(void *tPtr, int64_t now);
  112. /**
  113. * Save all currently known peers to data store
  114. *
  115. * @param tPtr Thread pointer
  116. */
  117. void saveAll(void *tPtr);
  118. /**
  119. * Add a certificate to the local certificate store
  120. *
  121. * @param tPtr Thread pointer
  122. * @param cert Certificate to add (a copy will be made if added)
  123. * @param now Current time
  124. * @param localTrust Local trust bit flags
  125. * @param writeToLocalStore If true, write to local object store (via API callbacks)
  126. * @param refreshRootSets If true, refresh root sets in case a root set changed (default: true)
  127. * @param verify If true, verify certificate and certificate chain (default: true)
  128. * @return Error or 0 on success
  129. */
  130. ZT_CertificateError addCertificate(
  131. void *tPtr,
  132. const Certificate &cert,
  133. int64_t now,
  134. unsigned int localTrust,
  135. bool writeToLocalStore,
  136. bool refreshRootSets = true,
  137. bool verify = true);
  138. /**
  139. * Delete certificate
  140. *
  141. * @param tPtr Thread pointer
  142. * @param serialNo Serial number to delete
  143. * @return Number of deleted certificates
  144. */
  145. unsigned int deleteCertificate(void *tPtr,const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]);
  146. /**
  147. * Fill vectors with all certificates and their corresponding local trust flags
  148. *
  149. * @param c Certificate vector
  150. * @param t Local trust vector
  151. */
  152. void allCerts(Vector< SharedPtr<const Certificate> > &c,Vector< unsigned int > &t) const noexcept;
  153. private:
  154. void m_rankRoots(int64_t now);
  155. void m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate > &cert, const SHA384Hash *uniqueIdHash);
  156. bool m_cleanCertificates(void *tPtr, int64_t now);
  157. bool m_verifyCertificateChain(const Certificate *current, int64_t now) const;
  158. ZT_CertificateError m_verifyCertificate(const Certificate &cert, int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
  159. void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
  160. SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
  161. SharedPtr< Path > m_newPath(int64_t l, const InetAddress &r, const UniqueID &k);
  162. void m_updateRootPeers(void *tPtr, int64_t now);
  163. void m_writeTrustStore(void *tPtr);
  164. const RuntimeEnvironment *const RR;
  165. int64_t m_lastRankedRoots;
  166. Vector< SharedPtr< Peer > > m_roots;
  167. Map< Address, SharedPtr< Peer > > m_peers;
  168. Map< UniqueID, SharedPtr< Path > > m_paths;
  169. struct p_CertEntry
  170. {
  171. ZT_INLINE p_CertEntry() :
  172. certificate(),
  173. localTrust(0)
  174. {}
  175. SharedPtr< const Certificate > certificate;
  176. unsigned int localTrust;
  177. };
  178. Map< SHA384Hash, p_CertEntry > m_certs;
  179. Map< SHA384Hash, p_CertEntry > m_certsBySubjectUniqueID;
  180. Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectIdentity;
  181. RWMutex m_paths_l; // m_paths
  182. RWMutex m_peers_l; // m_peers
  183. RWMutex m_roots_l; // m_roots and m_lastRankedRoots
  184. Mutex m_certs_l; // m_certs and friends
  185. };
  186. } // namespace ZeroTier
  187. #endif