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