Topology.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*
  2. * Copyright (c)2019 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: 2023-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 <stdio.h>
  16. #include <string.h>
  17. #include <vector>
  18. #include <stdexcept>
  19. #include <algorithm>
  20. #include <utility>
  21. #include <set>
  22. #include "Constants.hpp"
  23. #include "../include/ZeroTierOne.h"
  24. #include "Address.hpp"
  25. #include "Identity.hpp"
  26. #include "Peer.hpp"
  27. #include "Path.hpp"
  28. #include "Mutex.hpp"
  29. #include "InetAddress.hpp"
  30. #include "Hashtable.hpp"
  31. #include "Locator.hpp"
  32. #include "SharedPtr.hpp"
  33. #include "ScopedPtr.hpp"
  34. namespace ZeroTier {
  35. class RuntimeEnvironment;
  36. /**
  37. * Database of network topology
  38. */
  39. class Topology
  40. {
  41. private:
  42. struct _RootRankingFunction
  43. {
  44. ZT_ALWAYS_INLINE _RootRankingFunction() : bestRoot(),bestRootLatency(0xffff) {}
  45. ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &phy)
  46. {
  47. const unsigned int lat = peer->latency(now);
  48. if ((!bestRoot)||((lat <= bestRootLatency)&&(peer->getAppropriatePath(now,false)))) {
  49. bestRoot = peer;
  50. bestRootLatency = lat;
  51. }
  52. return true;
  53. }
  54. int64_t now;
  55. SharedPtr<Peer> bestRoot;
  56. unsigned int bestRootLatency;
  57. };
  58. ZT_ALWAYS_INLINE void _updateDynamicRootIdentities()
  59. {
  60. // assumes _roots_l is locked
  61. _rootIdentities.clear();
  62. Hashtable< Str,Locator >::Iterator i(_roots);
  63. Str *k = (Str *)0;
  64. Locator *v = (Locator *)0;
  65. while (i.next(k,v)) {
  66. if (*v)
  67. _rootIdentities.set(v->id(),true);
  68. }
  69. }
  70. public:
  71. ZT_ALWAYS_INLINE Topology(const RuntimeEnvironment *renv,const Identity &myId) :
  72. RR(renv),
  73. _myIdentity(myId),
  74. _numConfiguredPhysicalPaths(0),
  75. _peers(64),
  76. _paths(128),
  77. _roots(8),
  78. _rootIdentities(8),
  79. _lastUpdatedBestRoot(0) {}
  80. ZT_ALWAYS_INLINE ~Topology() {}
  81. /**
  82. * Add a peer to database
  83. *
  84. * This will not replace existing peers. In that case the existing peer
  85. * record is returned.
  86. *
  87. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  88. * @param peer Peer to add
  89. * @return New or existing peer (should replace 'peer')
  90. */
  91. ZT_ALWAYS_INLINE SharedPtr<Peer> add(const SharedPtr<Peer> &peer)
  92. {
  93. SharedPtr<Peer> np;
  94. {
  95. Mutex::Lock _l(_peers_l);
  96. SharedPtr<Peer> &hp = _peers[peer->address()];
  97. if (!hp)
  98. hp = peer;
  99. np = hp;
  100. }
  101. return np;
  102. }
  103. /**
  104. * Get a peer from its address
  105. *
  106. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  107. * @param zta ZeroTier address of peer
  108. * @return Peer or NULL if not found
  109. */
  110. ZT_ALWAYS_INLINE SharedPtr<Peer> get(const Address &zta)
  111. {
  112. if (zta == _myIdentity.address())
  113. return SharedPtr<Peer>();
  114. Mutex::Lock l1(_peers_l);
  115. const SharedPtr<Peer> *const ap = _peers.get(zta);
  116. if (ap)
  117. return *ap;
  118. return SharedPtr<Peer>();
  119. }
  120. /**
  121. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  122. * @param zta ZeroTier address of peer
  123. * @return Identity or NULL identity if not found
  124. */
  125. ZT_ALWAYS_INLINE Identity getIdentity(void *tPtr,const Address &zta)
  126. {
  127. if (zta == _myIdentity.address()) {
  128. return _myIdentity;
  129. } else {
  130. Mutex::Lock _l(_peers_l);
  131. const SharedPtr<Peer> *const ap = _peers.get(zta);
  132. if (ap)
  133. return (*ap)->identity();
  134. }
  135. return Identity();
  136. }
  137. /**
  138. * Get a Path object for a given local and remote physical address, creating if needed
  139. *
  140. * @param l Local socket
  141. * @param r Remote address
  142. * @return Pointer to canonicalized Path object
  143. */
  144. ZT_ALWAYS_INLINE SharedPtr<Path> getPath(const int64_t l,const InetAddress &r)
  145. {
  146. Mutex::Lock _l(_paths_l);
  147. SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
  148. if (!p)
  149. p.set(new Path(l,r));
  150. return p;
  151. }
  152. /**
  153. * @param id Identity to check
  154. * @return True if this identity corresponds to a root
  155. */
  156. ZT_ALWAYS_INLINE bool isRoot(const Identity &id) const
  157. {
  158. Mutex::Lock l(_roots_l);
  159. return _rootIdentities.contains(id);
  160. }
  161. /**
  162. * Do periodic tasks such as database cleanup
  163. */
  164. ZT_ALWAYS_INLINE void doPeriodicTasks(int64_t now)
  165. {
  166. {
  167. Mutex::Lock _l1(_peers_l);
  168. Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
  169. Address *a = (Address *)0;
  170. SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
  171. while (i.next(a,p)) {
  172. if (!(*p)->alive(now)) {
  173. _peers.erase(*a);
  174. }
  175. }
  176. }
  177. {
  178. Mutex::Lock _l(_paths_l);
  179. Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
  180. Path::HashKey *k = (Path::HashKey *)0;
  181. SharedPtr<Path> *p = (SharedPtr<Path> *)0;
  182. while (i.next(k,p)) {
  183. if (p->references() <= 1)
  184. _paths.erase(*k);
  185. }
  186. }
  187. }
  188. /**
  189. * @param now Current time
  190. * @return Number of peers with active direct paths
  191. */
  192. inline unsigned long countActive(int64_t now) const
  193. {
  194. unsigned long cnt = 0;
  195. Mutex::Lock _l(_peers_l);
  196. Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
  197. Address *a = (Address *)0;
  198. SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
  199. while (i.next(a,p)) {
  200. const SharedPtr<Path> pp((*p)->getAppropriatePath(now,false));
  201. if (pp)
  202. ++cnt;
  203. }
  204. return cnt;
  205. }
  206. /**
  207. * Apply a function or function object to all peers
  208. *
  209. * This locks the peer map during execution, so calls to get() etc. during
  210. * eachPeer() will deadlock.
  211. *
  212. * @param f Function to apply
  213. * @tparam F Function or function object type
  214. */
  215. template<typename F>
  216. ZT_ALWAYS_INLINE void eachPeer(F f)
  217. {
  218. Mutex::Lock l(_peers_l);
  219. Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
  220. Address *a = (Address *)0;
  221. SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
  222. while (i.next(a,p)) {
  223. if (!f(*((const SharedPtr<Peer> *)p)))
  224. break;
  225. }
  226. }
  227. /**
  228. * Apply a function or function object to all roots
  229. *
  230. * This locks the root list during execution but other operations
  231. * are fine.
  232. *
  233. * @param f Function to apply f(peer,IPs)
  234. * @tparam F function or function object type
  235. */
  236. template<typename F>
  237. ZT_ALWAYS_INLINE void eachRoot(F f)
  238. {
  239. Mutex::Lock l(_roots_l);
  240. Hashtable< Str,Locator >::Iterator i(_roots);
  241. Str *k = (Str *)0;
  242. Locator *v = (Locator *)0;
  243. while (i.next(k,v)) {
  244. if (*v) {
  245. for(std::vector<Identity>::const_iterator id(v->virt().begin());id!=v->virt().end();++id) {
  246. const SharedPtr<Peer> *ap;
  247. {
  248. Mutex::Lock l2(_peers_l);
  249. ap = _peers.get(id->address());
  250. }
  251. if (ap) {
  252. if (!f(*ap,v->phy()))
  253. return;
  254. } else {
  255. SharedPtr<Peer> p(new Peer(RR,_myIdentity,*id));
  256. {
  257. Mutex::Lock l2(_peers_l);
  258. _peers.set(id->address(),p);
  259. }
  260. if (!f(p,v->phy()))
  261. return;
  262. }
  263. }
  264. }
  265. }
  266. }
  267. /**
  268. * @return Current best root (updated automatically each second)
  269. */
  270. inline SharedPtr<Peer> root(const int64_t now)
  271. {
  272. Mutex::Lock l(_bestRoot_l);
  273. if ((!_bestRoot)||((now - _lastUpdatedBestRoot) > 1000)) {
  274. _lastUpdatedBestRoot = now;
  275. _RootRankingFunction rrf;
  276. rrf.now = now;
  277. eachRoot(rrf);
  278. _bestRoot = rrf.bestRoot;
  279. }
  280. return _bestRoot;
  281. }
  282. /**
  283. * Iterate through all root names
  284. *
  285. * @param f Function of (Str,Locator)
  286. */
  287. template<typename F>
  288. ZT_ALWAYS_INLINE void eachRootName(F f) const
  289. {
  290. Mutex::Lock l(_roots_l);
  291. Str *k = (Str *)0;
  292. Locator *v = (Locator *)0;
  293. Hashtable< Str,Locator >::Iterator i(const_cast<Topology *>(this)->_roots);
  294. while (i.next(k,v)) {
  295. if (!f(*k,*v))
  296. break;
  297. }
  298. }
  299. /**
  300. * Set or update dynamic root if new locator is newer
  301. *
  302. * This does not check signatures or internal validity of the locator.
  303. *
  304. * @param name DNS name used to retrive root or simply the address for static roots
  305. * @param latestLocator Latest locator
  306. * @return True if locator is newer or if a new entry was created
  307. */
  308. inline bool setRoot(const Str &name,const Locator &latestLocator)
  309. {
  310. Mutex::Lock l(_roots_l);
  311. if (latestLocator) {
  312. Locator &ll = _roots[name];
  313. if (ll.timestamp() < latestLocator.timestamp()) {
  314. ll = latestLocator;
  315. _updateDynamicRootIdentities();
  316. return true;
  317. }
  318. } else if (!_roots.contains(name)) {
  319. _roots[name];
  320. return true;
  321. }
  322. return false;
  323. }
  324. /**
  325. * Remove a dynamic root entry
  326. */
  327. inline void removeRoot(const Str &name)
  328. {
  329. Mutex::Lock l(_roots_l);
  330. _roots.erase(name);
  331. _updateDynamicRootIdentities();
  332. }
  333. /**
  334. * @param Current time
  335. * @return ZT_RootList as returned by the external CAPI
  336. */
  337. inline ZT_RootList *apiRoots(const int64_t now) const
  338. {
  339. ScopedPtr< Buffer<65536> > lbuf(new Buffer<65536>());
  340. Mutex::Lock l2(_roots_l);
  341. ZT_RootList *rl = (ZT_RootList *)malloc(sizeof(ZT_RootList) + (sizeof(ZT_Root) * _roots.size()) + (256 * _roots.size()) + (65536 * _roots.size()));
  342. if (!rl)
  343. return nullptr;
  344. char *nptr = ((char *)rl) + sizeof(ZT_RootList) + (sizeof(ZT_Root) * _roots.size());
  345. uint8_t *lptr = ((uint8_t *)nptr) + (256 * _roots.size());
  346. unsigned int c = 0;
  347. Str *k = (Str *)0;
  348. Locator *v = (Locator *)0;
  349. Hashtable< Str,Locator >::Iterator i(const_cast<Topology *>(this)->_roots);
  350. while (i.next(k,v)) {
  351. Utils::scopy(nptr,256,k->c_str());
  352. rl->roots[c].name = nptr;
  353. nptr += 256;
  354. lbuf->clear();
  355. v->serialize(*lbuf);
  356. memcpy(lptr,lbuf->unsafeData(),lbuf->size());
  357. rl->roots[c].locator = lptr;
  358. rl->roots[c].locatorSize = lbuf->size();
  359. lptr += 65536;
  360. ++c;
  361. }
  362. rl->count = c;
  363. return rl;
  364. }
  365. /**
  366. * Get the best relay to a given address, which may or may not be a root
  367. *
  368. * @param now Current time
  369. * @param toAddr Destination address
  370. * @return Best current relay or NULL if none
  371. */
  372. ZT_ALWAYS_INLINE SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr)
  373. {
  374. // TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root)
  375. return root(now);
  376. }
  377. /**
  378. * @param allPeers vector to fill with all current peers
  379. */
  380. ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
  381. {
  382. Mutex::Lock l(_peers_l);
  383. allPeers.clear();
  384. allPeers.reserve(_peers.size());
  385. Hashtable< Address,SharedPtr<Peer> >::Iterator i(*(const_cast<Hashtable< Address,SharedPtr<Peer> > *>(&_peers)));
  386. Address *a = (Address *)0;
  387. SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
  388. while (i.next(a,p)) {
  389. allPeers.push_back(*p);
  390. }
  391. }
  392. /**
  393. * Get info about a path
  394. *
  395. * The supplied result variables are not modified if no special config info is found.
  396. *
  397. * @param physicalAddress Physical endpoint address
  398. * @param mtu Variable set to MTU
  399. * @param trustedPathId Variable set to trusted path ID
  400. */
  401. ZT_ALWAYS_INLINE void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId)
  402. {
  403. for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
  404. if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) {
  405. trustedPathId = _physicalPathConfig[i].second.trustedPathId;
  406. mtu = _physicalPathConfig[i].second.mtu;
  407. return;
  408. }
  409. }
  410. }
  411. /**
  412. * Get the payload MTU for an outbound physical path (returns default if not configured)
  413. *
  414. * @param physicalAddress Physical endpoint address
  415. * @return MTU
  416. */
  417. ZT_ALWAYS_INLINE unsigned int getOutboundPathMtu(const InetAddress &physicalAddress)
  418. {
  419. for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
  420. if (_physicalPathConfig[i].first.containsAddress(physicalAddress))
  421. return _physicalPathConfig[i].second.mtu;
  422. }
  423. return ZT_DEFAULT_PHYSMTU;
  424. }
  425. /**
  426. * Get the outbound trusted path ID for a physical address, or 0 if none
  427. *
  428. * @param physicalAddress Physical address to which we are sending the packet
  429. * @return Trusted path ID or 0 if none (0 is not a valid trusted path ID)
  430. */
  431. ZT_ALWAYS_INLINE uint64_t getOutboundPathTrust(const InetAddress &physicalAddress)
  432. {
  433. for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
  434. if (_physicalPathConfig[i].first.containsAddress(physicalAddress))
  435. return _physicalPathConfig[i].second.trustedPathId;
  436. }
  437. return 0;
  438. }
  439. /**
  440. * Check whether in incoming trusted path marked packet is valid
  441. *
  442. * @param physicalAddress Originating physical address
  443. * @param trustedPathId Trusted path ID from packet (from MAC field)
  444. */
  445. ZT_ALWAYS_INLINE bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId)
  446. {
  447. for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
  448. if ((_physicalPathConfig[i].second.trustedPathId == trustedPathId)&&(_physicalPathConfig[i].first.containsAddress(physicalAddress)))
  449. return true;
  450. }
  451. return false;
  452. }
  453. /**
  454. * Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
  455. */
  456. inline void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
  457. {
  458. if (!pathNetwork) {
  459. _numConfiguredPhysicalPaths = 0;
  460. } else {
  461. std::map<InetAddress,ZT_PhysicalPathConfiguration> cpaths;
  462. for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i)
  463. cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second;
  464. if (pathConfig) {
  465. ZT_PhysicalPathConfiguration pc(*pathConfig);
  466. if (pc.mtu <= 0)
  467. pc.mtu = ZT_DEFAULT_PHYSMTU;
  468. else if (pc.mtu < ZT_MIN_PHYSMTU)
  469. pc.mtu = ZT_MIN_PHYSMTU;
  470. else if (pc.mtu > ZT_MAX_PHYSMTU)
  471. pc.mtu = ZT_MAX_PHYSMTU;
  472. cpaths[*(reinterpret_cast<const InetAddress *>(pathNetwork))] = pc;
  473. } else {
  474. cpaths.erase(*(reinterpret_cast<const InetAddress *>(pathNetwork)));
  475. }
  476. unsigned int cnt = 0;
  477. for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::const_iterator i(cpaths.begin());((i!=cpaths.end())&&(cnt<ZT_MAX_CONFIGURABLE_PATHS));++i) {
  478. _physicalPathConfig[cnt].first = i->first;
  479. _physicalPathConfig[cnt].second = i->second;
  480. ++cnt;
  481. }
  482. _numConfiguredPhysicalPaths = cnt;
  483. }
  484. }
  485. private:
  486. const RuntimeEnvironment *const RR;
  487. const Identity _myIdentity;
  488. std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
  489. unsigned int _numConfiguredPhysicalPaths;
  490. Hashtable< Address,SharedPtr<Peer> > _peers;
  491. Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
  492. Hashtable< Str,Locator > _roots;
  493. Hashtable< Identity,bool > _rootIdentities;
  494. int64_t _lastUpdatedBestRoot;
  495. SharedPtr<Peer> _bestRoot;
  496. Mutex _peers_l;
  497. Mutex _paths_l;
  498. Mutex _roots_l;
  499. Mutex _bestRoot_l;
  500. };
  501. } // namespace ZeroTier
  502. #endif