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 
14 #ifndef ZT_PEER_HPP
15 #define ZT_PEER_HPP
16 
17 #include <vector>
18 #include <list>
19 
20 #include "../include/ZeroTierOne.h"
21 
22 #include "Constants.hpp"
23 #include "RuntimeEnvironment.hpp"
24 #include "Node.hpp"
25 #include "Path.hpp"
26 #include "Address.hpp"
27 #include "Utils.hpp"
28 #include "Identity.hpp"
29 #include "InetAddress.hpp"
30 #include "Packet.hpp"
31 #include "SharedPtr.hpp"
32 #include "AtomicCounter.hpp"
33 #include "Hashtable.hpp"
34 #include "Mutex.hpp"
35 #include "Bond.hpp"
36 #include "AES.hpp"
37 
38 #define ZT_PEER_MAX_SERIALIZED_STATE_SIZE (sizeof(Peer) + 32 + (sizeof(Path) * 2))
39 
40 namespace ZeroTier {
41 
42 /**
43  * Peer on P2P Network (virtual layer 1)
44  */
45 class Peer
46 {
47 	friend class SharedPtr<Peer>;
48 	friend class SharedPtr<Bond>;
49 	friend class Switch;
50 	friend class Bond;
51 
52 private:
Peer()53 	Peer() {} // disabled to prevent bugs -- should not be constructed uninitialized
54 
55 public:
~Peer()56 	~Peer() { Utils::burn(_key,sizeof(_key)); }
57 
58 	/**
59 	 * Construct a new peer
60 	 *
61 	 * @param renv Runtime environment
62 	 * @param myIdentity Identity of THIS node (for key agreement)
63 	 * @param peerIdentity Identity of peer
64 	 * @throws std::runtime_error Key agreement with peer's identity failed
65 	 */
66 	Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Identity &peerIdentity);
67 
68 	/**
69 	 * @return This peer's ZT address (short for identity().address())
70 	 */
address() const71 	inline const Address &address() const { return _id.address(); }
72 
73 	/**
74 	 * @return This peer's identity
75 	 */
identity() const76 	inline const Identity &identity() const { return _id; }
77 
78 	/**
79 	 * Log receipt of an authenticated packet
80 	 *
81 	 * This is called by the decode pipe when a packet is proven to be authentic
82 	 * and appears to be valid.
83 	 *
84 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
85 	 * @param path Path over which packet was received
86 	 * @param hops ZeroTier (not IP) hops
87 	 * @param packetId Packet ID
88 	 * @param verb Packet verb
89 	 * @param inRePacketId Packet ID in reply to (default: none)
90 	 * @param inReVerb Verb in reply to (for OK/ERROR, default: VERB_NOP)
91 	 * @param trustEstablished If true, some form of non-trivial trust (like allowed in network) has been established
92 	 * @param networkId Network ID if this pertains to a network, or 0 otherwise
93 	 */
94 	void received(
95 		void *tPtr,
96 		const SharedPtr<Path> &path,
97 		const unsigned int hops,
98 		const uint64_t packetId,
99 		const unsigned int payloadLength,
100 		const Packet::Verb verb,
101 		const uint64_t inRePacketId,
102 		const Packet::Verb inReVerb,
103 		const bool trustEstablished,
104 		const uint64_t networkId,
105 		const int32_t flowId);
106 
107 	/**
108 	 * Check whether we have an active path to this peer via the given address
109 	 *
110 	 * @param now Current time
111 	 * @param addr Remote address
112 	 * @return True if we have an active path to this destination
113 	 */
hasActivePathTo(int64_t now,const InetAddress & addr) const114 	inline bool hasActivePathTo(int64_t now,const InetAddress &addr) const
115 	{
116 		Mutex::Lock _l(_paths_m);
117 		for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
118 			if (_paths[i].p) {
119 				if (((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION)&&(_paths[i].p->address() == addr))
120 					return true;
121 			} else break;
122 		}
123 		return false;
124 	}
125 
126 	/**
127 	 * Send via best direct path
128 	 *
129 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
130 	 * @param data Packet data
131 	 * @param len Packet length
132 	 * @param now Current time
133 	 * @param force If true, send even if path is not alive
134 	 * @return True if we actually sent something
135 	 */
sendDirect(void * tPtr,const void * data,unsigned int len,int64_t now,bool force)136 	inline bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force)
137 	{
138 		SharedPtr<Path> bp(getAppropriatePath(now,force));
139 		if (bp)
140 			return bp->send(RR,tPtr,data,len,now);
141 		return false;
142 	}
143 
144 	/**
145 	 * Record incoming packets to
146 	 *
147 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
148 	 * @param path Path over which packet was received
149 	 * @param packetId Packet ID
150 	 * @param payloadLength Length of packet data payload
151 	 * @param verb Packet verb
152 	 * @param flowId Flow ID
153 	 * @param now Current time
154 	 */
155 	void recordIncomingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
156 		uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
157 
158 	/**
159 	 *
160 	 * @param path Path over which packet is being sent
161 	 * @param packetId Packet ID
162 	 * @param payloadLength Length of packet data payload
163 	 * @param verb Packet verb
164 	 * @param flowId Flow ID
165 	 * @param now Current time
166 	 */
167 	void recordOutgoingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
168 		uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now);
169 
170 	/**
171 	 * Record an invalid incoming packet. This packet failed
172 	 * MAC/compression/cipher checks and will now contribute to a
173 	 * Packet Error Ratio (PER).
174 	 *
175 	 * @param path Path over which packet was received
176 	 */
177 	void recordIncomingInvalidPacket(const SharedPtr<Path>& path);
178 
179 	/**
180 	 * Get the most appropriate direct path based on current multipath and QoS configuration
181 	 *
182 	 * @param now Current time
183 	 * @param includeExpired If true, include even expired paths
184 	 * @return Best current path or NULL if none
185 	 */
186 	SharedPtr<Path> getAppropriatePath(int64_t now, bool includeExpired, int32_t flowId = -1);
187 
188 	/**
189 	 * Send VERB_RENDEZVOUS to this and another peer via the best common IP scope and path
190 	 */
191 	void introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &other) const;
192 
193 	/**
194 	 * Send a HELLO to this peer at a specified physical address
195 	 *
196 	 * No statistics or sent times are updated here.
197 	 *
198 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
199 	 * @param localSocket Local source socket
200 	 * @param atAddress Destination address
201 	 * @param now Current time
202 	 */
203 	void sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now);
204 
205 	/**
206 	 * Send ECHO (or HELLO for older peers) to this peer at the given address
207 	 *
208 	 * No statistics or sent times are updated here.
209 	 *
210 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
211 	 * @param localSocket Local source socket
212 	 * @param atAddress Destination address
213 	 * @param now Current time
214 	 * @param sendFullHello If true, always send a full HELLO instead of just an ECHO
215 	 */
216 	void attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now,bool sendFullHello);
217 
218 	/**
219 	 * Try a memorized or statically defined path if any are known
220 	 *
221 	 * Under the hood this is done periodically based on ZT_TRY_MEMORIZED_PATH_INTERVAL.
222 	 *
223 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
224 	 * @param now Current time
225 	 */
226 	void tryMemorizedPath(void *tPtr,int64_t now);
227 
228 	/**
229 	 * A check to be performed periodically which determines whether multipath communication is
230 	 * possible with this peer. This check should be performed early in the life-cycle of the peer
231 	 * as well as during the process of learning new paths.
232 	 */
233 	void performMultipathStateCheck(void *tPtr, int64_t now);
234 
235 	/**
236 	 * Send pings or keepalives depending on configured timeouts
237 	 *
238 	 * This also cleans up some internal data structures. It's called periodically from Node.
239 	 *
240 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
241 	 * @param now Current time
242 	 * @param inetAddressFamily Keep this address family alive, or -1 for any
243 	 * @return 0 if nothing sent or bit mask: bit 0x1 if IPv4 sent, bit 0x2 if IPv6 sent (0x3 means both sent)
244 	 */
245 	unsigned int doPingAndKeepalive(void *tPtr,int64_t now);
246 
247 	/**
248 	 * Process a cluster redirect sent by this peer
249 	 *
250 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
251 	 * @param originatingPath Path from which redirect originated
252 	 * @param remoteAddress Remote address
253 	 * @param now Current time
254 	 */
255 	void clusterRedirect(void *tPtr,const SharedPtr<Path> &originatingPath,const InetAddress &remoteAddress,const int64_t now);
256 
257 	/**
258 	 * Reset paths within a given IP scope and address family
259 	 *
260 	 * Resetting a path involves sending an ECHO to it and then deactivating
261 	 * it until or unless it responds. This is done when we detect a change
262 	 * to our external IP or another system change that might invalidate
263 	 * many or all current paths.
264 	 *
265 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
266 	 * @param scope IP scope
267 	 * @param inetAddressFamily Family e.g. AF_INET
268 	 * @param now Current time
269 	 */
270 	void resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,int64_t now);
271 
272 	/**
273 	 * @param now Current time
274 	 * @return All known paths to this peer
275 	 */
paths(const int64_t now) const276 	inline std::vector< SharedPtr<Path> > paths(const int64_t now) const
277 	{
278 		std::vector< SharedPtr<Path> > pp;
279 		Mutex::Lock _l(_paths_m);
280 		for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
281 			if (!_paths[i].p) break;
282 			pp.push_back(_paths[i].p);
283 		}
284 		return pp;
285 	}
286 
287 	/**
288 	 * @return Time of last receive of anything, whether direct or relayed
289 	 */
lastReceive() const290 	inline int64_t lastReceive() const { return _lastReceive; }
291 
292 	/**
293 	 * @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
294 	 */
isAlive(const int64_t now) const295 	inline bool isAlive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
296 
297 	/**
298 	 * @return True if this peer has sent us real network traffic recently
299 	 */
isActive(int64_t now) const300 	inline int64_t isActive(int64_t now) const { return ((now - _lastNontrivialReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
301 
302 	/**
303 	 * @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
304 	 */
latency(const int64_t now)305 	inline unsigned int latency(const int64_t now)
306 	{
307 		if (_localMultipathSupported) {
308 			return (int)_lastComputedAggregateMeanLatency;
309 		} else {
310 			SharedPtr<Path> bp(getAppropriatePath(now,false));
311 			if (bp) {
312 				return bp->latency();
313 			}
314 			return 0xffff;
315 		}
316 	}
317 
318 	/**
319 	 * This computes a quality score for relays and root servers
320 	 *
321 	 * If we haven't heard anything from these in ZT_PEER_ACTIVITY_TIMEOUT, they
322 	 * receive the worst possible quality (max unsigned int). Otherwise the
323 	 * quality is a product of latency and the number of potential missed
324 	 * pings. This causes roots and relays to switch over a bit faster if they
325 	 * fail.
326 	 *
327 	 * @return Relay quality score computed from latency and other factors, lower is better
328 	 */
relayQuality(const int64_t now)329 	inline unsigned int relayQuality(const int64_t now)
330 	{
331 		const uint64_t tsr = now - _lastReceive;
332 		if (tsr >= ZT_PEER_ACTIVITY_TIMEOUT)
333 			return (~(unsigned int)0);
334 		unsigned int l = latency(now);
335 		if (!l)
336 			l = 0xffff;
337 		return (l * (((unsigned int)tsr / (ZT_PEER_PING_PERIOD + 1000)) + 1));
338 	}
339 
340 	/**
341 	 * @return 256-bit secret symmetric encryption key
342 	 */
key() const343 	inline const unsigned char *key() const { return _key; }
344 
345 	/**
346 	 * Set the currently known remote version of this peer's client
347 	 *
348 	 * @param vproto Protocol version
349 	 * @param vmaj Major version
350 	 * @param vmin Minor version
351 	 * @param vrev Revision
352 	 */
setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev)353 	inline void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev)
354 	{
355 		_vProto = (uint16_t)vproto;
356 		_vMajor = (uint16_t)vmaj;
357 		_vMinor = (uint16_t)vmin;
358 		_vRevision = (uint16_t)vrev;
359 	}
360 
remoteVersionProtocol() const361 	inline unsigned int remoteVersionProtocol() const { return _vProto; }
remoteVersionMajor() const362 	inline unsigned int remoteVersionMajor() const { return _vMajor; }
remoteVersionMinor() const363 	inline unsigned int remoteVersionMinor() const { return _vMinor; }
remoteVersionRevision() const364 	inline unsigned int remoteVersionRevision() const { return _vRevision; }
365 
remoteVersionKnown() const366 	inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
367 
368 	/**
369 	 * @return True if peer has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms
370 	 */
trustEstablished(const int64_t now) const371 	inline bool trustEstablished(const int64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); }
372 
373 	/**
374 	 * Rate limit gate for VERB_PUSH_DIRECT_PATHS
375 	 */
rateGatePushDirectPaths(const int64_t now)376 	inline bool rateGatePushDirectPaths(const int64_t now)
377 	{
378 		if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME)
379 			++_directPathPushCutoffCount;
380 		else _directPathPushCutoffCount = 0;
381 		_lastDirectPathPushReceive = now;
382 		return (_directPathPushCutoffCount < ZT_PUSH_DIRECT_PATHS_CUTOFF_LIMIT);
383 	}
384 
385 	/**
386 	 * Rate limit gate for VERB_NETWORK_CREDENTIALS
387 	 */
rateGateCredentialsReceived(const int64_t now)388 	inline bool rateGateCredentialsReceived(const int64_t now)
389 	{
390 		if ((now - _lastCredentialsReceived) <= ZT_PEER_CREDENTIALS_CUTOFF_TIME)
391 			++_credentialsCutoffCount;
392 		else _credentialsCutoffCount = 0;
393 		_lastCredentialsReceived = now;
394 		return (_directPathPushCutoffCount < ZT_PEER_CREDEITIALS_CUTOFF_LIMIT);
395 	}
396 
397 	/**
398 	 * Rate limit gate for sending of ERROR_NEED_MEMBERSHIP_CERTIFICATE
399 	 */
rateGateRequestCredentials(const int64_t now)400 	inline bool rateGateRequestCredentials(const int64_t now)
401 	{
402 		if ((now - _lastCredentialRequestSent) >= ZT_PEER_GENERAL_RATE_LIMIT) {
403 			_lastCredentialRequestSent = now;
404 			return true;
405 		}
406 		return false;
407 	}
408 
409 	/**
410 	 * Rate limit gate for inbound WHOIS requests
411 	 */
rateGateInboundWhoisRequest(const int64_t now)412 	inline bool rateGateInboundWhoisRequest(const int64_t now)
413 	{
414 		if ((now - _lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) {
415 			_lastWhoisRequestReceived = now;
416 			return true;
417 		}
418 		return false;
419 	}
420 
421 	/**
422 	 * Rate limit gate for inbound ECHO requests
423 	 */
rateGateEchoRequest(const int64_t now)424 	inline bool rateGateEchoRequest(const int64_t now)
425 	{
426 		if ((now - _lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) {
427 			_lastEchoRequestReceived = now;
428 			return true;
429 		}
430 		return false;
431 	}
432 
433 	/**
434 	 * Serialize a peer for storage in local cache
435 	 *
436 	 * This does not serialize everything, just non-ephemeral information.
437 	 */
438 	template<unsigned int C>
serializeForCache(Buffer<C> & b) const439 	inline void serializeForCache(Buffer<C> &b) const
440 	{
441 		b.append((uint8_t)1);
442 
443 		_id.serialize(b);
444 
445 		b.append((uint16_t)_vProto);
446 		b.append((uint16_t)_vMajor);
447 		b.append((uint16_t)_vMinor);
448 		b.append((uint16_t)_vRevision);
449 
450 		{
451 			Mutex::Lock _l(_paths_m);
452 			unsigned int pc = 0;
453 			for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
454 				if (_paths[i].p)
455 					++pc;
456 				else break;
457 			}
458 			b.append((uint16_t)pc);
459 			for(unsigned int i=0;i<pc;++i)
460 				_paths[i].p->address().serialize(b);
461 		}
462 	}
463 
464 	template<unsigned int C>
deserializeFromCache(int64_t now,void * tPtr,Buffer<C> & b,const RuntimeEnvironment * renv)465 	inline static SharedPtr<Peer> deserializeFromCache(int64_t now,void *tPtr,Buffer<C> &b,const RuntimeEnvironment *renv)
466 	{
467 		try {
468 			unsigned int ptr = 0;
469 			if (b[ptr++] != 1)
470 				return SharedPtr<Peer>();
471 
472 			Identity id;
473 			ptr += id.deserialize(b,ptr);
474 			if (!id)
475 				return SharedPtr<Peer>();
476 
477 			SharedPtr<Peer> p(new Peer(renv,renv->identity,id));
478 
479 			p->_vProto = b.template at<uint16_t>(ptr); ptr += 2;
480 			p->_vMajor = b.template at<uint16_t>(ptr); ptr += 2;
481 			p->_vMinor = b.template at<uint16_t>(ptr); ptr += 2;
482 			p->_vRevision = b.template at<uint16_t>(ptr); ptr += 2;
483 
484 			// When we deserialize from the cache we don't actually restore paths. We
485 			// just try them and then re-learn them if they happen to still be up.
486 			// Paths are fairly ephemeral in the real world in most cases.
487 			const unsigned int tryPathCount = b.template at<uint16_t>(ptr); ptr += 2;
488 			for(unsigned int i=0;i<tryPathCount;++i) {
489 				InetAddress inaddr;
490 				try {
491 					ptr += inaddr.deserialize(b,ptr);
492 					if (inaddr)
493 						p->attemptToContactAt(tPtr,-1,inaddr,now,true);
494 				} catch ( ... ) {
495 					break;
496 				}
497 			}
498 
499 			return p;
500 		} catch ( ... ) {
501 			return SharedPtr<Peer>();
502 		}
503 	}
504 
505 	/**
506 	 * @return The bonding policy used to reach this peer
507 	 */
bond()508 	SharedPtr<Bond> bond() { return _bond; }
509 
510 	/**
511 	 * @return The bonding policy used to reach this peer
512 	 */
bondingPolicy()513 	inline int8_t bondingPolicy() {
514 		Mutex::Lock _l(_paths_m);
515 		if (_bond) {
516 			return _bond->policy();
517 		}
518 		return ZT_BOND_POLICY_NONE;
519 	}
520 
521 	//inline const AES *aesKeysIfSupported() const
522 	//{ return (const AES *)0; }
523 
aesKeysIfSupported() const524 	inline const AES *aesKeysIfSupported() const
525 	{ return (_vProto >= 12) ? _aesKeys : (const AES *)0; }
526 
aesKeys() const527 	inline const AES *aesKeys() const
528 	{ return _aesKeys; }
529 
530 private:
531 	struct _PeerPath
532 	{
_PeerPathZeroTier::Peer::_PeerPath533 		_PeerPath() : lr(0),p(),priority(1) {}
534 		int64_t lr; // time of last valid ZeroTier packet
535 		SharedPtr<Path> p;
536 		long priority; // >= 1, higher is better
537 	};
538 
539 	uint8_t _key[ZT_SYMMETRIC_KEY_SIZE];
540 	AES _aesKeys[2];
541 
542 	const RuntimeEnvironment *RR;
543 
544 	int64_t _lastReceive; // direct or indirect
545 	int64_t _lastNontrivialReceive; // frames, things like netconf, etc.
546 	int64_t _lastTriedMemorizedPath;
547 	int64_t _lastDirectPathPushSent;
548 	int64_t _lastDirectPathPushReceive;
549 	int64_t _lastEchoRequestReceived;
550 	int64_t _lastCredentialRequestSent;
551 	int64_t _lastWhoisRequestReceived;
552 	int64_t _lastCredentialsReceived;
553 	int64_t _lastTrustEstablishedPacketReceived;
554 	int64_t _lastSentFullHello;
555 	int64_t _lastEchoCheck;
556 
557 	unsigned char _freeRandomByte;
558 
559 	uint16_t _vProto;
560 	uint16_t _vMajor;
561 	uint16_t _vMinor;
562 	uint16_t _vRevision;
563 
564 	std::list< std::pair< Path *, int64_t > > _lastTriedPath;
565 	Mutex _lastTriedPath_m;
566 
567 	_PeerPath _paths[ZT_MAX_PEER_NETWORK_PATHS];
568 	Mutex _paths_m;
569 	Mutex _bond_m;
570 
571 	Identity _id;
572 
573 	unsigned int _directPathPushCutoffCount;
574 	unsigned int _credentialsCutoffCount;
575 	unsigned int _echoRequestCutoffCount;
576 
577 	AtomicCounter __refCount;
578 
579 	bool _localMultipathSupported;
580 
581 	volatile bool _shouldCollectPathStatistics;
582 
583 	int32_t _lastComputedAggregateMeanLatency;
584 
585 	SharedPtr<Bond> _bond;
586 };
587 
588 } // namespace ZeroTier
589 
590 // Add a swap() for shared ptr's to peers to speed up peer sorts
591 namespace std {
592 	template<>
swap(ZeroTier::SharedPtr<ZeroTier::Peer> & a,ZeroTier::SharedPtr<ZeroTier::Peer> & b)593 	inline void swap(ZeroTier::SharedPtr<ZeroTier::Peer> &a,ZeroTier::SharedPtr<ZeroTier::Peer> &b)
594 	{
595 		a.swap(b);
596 	}
597 }
598 
599 #endif
600