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: 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 14 #ifndef ZT_SELFAWARENESS_HPP 15 #define ZT_SELFAWARENESS_HPP 16 17 #include "Constants.hpp" 18 #include "InetAddress.hpp" 19 #include "Hashtable.hpp" 20 #include "Address.hpp" 21 #include "Mutex.hpp" 22 23 namespace ZeroTier { 24 25 class RuntimeEnvironment; 26 27 /** 28 * Tracks changes to this peer's real world addresses 29 */ 30 class SelfAwareness 31 { 32 public: 33 SelfAwareness(const RuntimeEnvironment *renv); 34 35 /** 36 * Called when a trusted remote peer informs us of our external network address 37 * 38 * @param reporter ZeroTier address of reporting peer 39 * @param receivedOnLocalAddress Local address on which report was received 40 * @param reporterPhysicalAddress Physical address that reporting peer seems to have 41 * @param myPhysicalAddress Physical address that peer says we have 42 * @param trusted True if this peer is trusted as an authority to inform us of external address changes 43 * @param now Current time 44 */ 45 void iam(void *tPtr,const Address &reporter,const int64_t receivedOnLocalSocket,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,int64_t now); 46 47 /** 48 * Clean up database periodically 49 * 50 * @param now Current time 51 */ 52 void clean(int64_t now); 53 54 private: 55 struct PhySurfaceKey 56 { 57 Address reporter; 58 int64_t receivedOnLocalSocket; 59 InetAddress reporterPhysicalAddress; 60 InetAddress::IpScope scope; 61 PhySurfaceKeyZeroTier::SelfAwareness::PhySurfaceKey62 PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {} PhySurfaceKeyZeroTier::SelfAwareness::PhySurfaceKey63 PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {} 64 hashCodeZeroTier::SelfAwareness::PhySurfaceKey65 inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); } operator ==ZeroTier::SelfAwareness::PhySurfaceKey66 inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); } 67 }; 68 struct PhySurfaceEntry 69 { 70 InetAddress mySurface; 71 uint64_t ts; 72 bool trusted; 73 PhySurfaceEntryZeroTier::SelfAwareness::PhySurfaceEntry74 PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {} PhySurfaceEntryZeroTier::SelfAwareness::PhySurfaceEntry75 PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {} 76 }; 77 78 const RuntimeEnvironment *RR; 79 80 Hashtable< PhySurfaceKey,PhySurfaceEntry > _phy; 81 Mutex _phy_m; 82 }; 83 84 } // namespace ZeroTier 85 86 #endif 87