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