Bond.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  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: 2024-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_BOND_HPP
  14. #define ZT_BOND_HPP
  15. #include <map>
  16. #include "Path.hpp"
  17. #include "Peer.hpp"
  18. #include "../osdep/Link.hpp"
  19. #include "Flow.hpp"
  20. namespace ZeroTier {
  21. class RuntimeEnvironment;
  22. class Link;
  23. class Bond
  24. {
  25. friend class SharedPtr<Bond>;
  26. friend class Peer;
  27. friend class BondController;
  28. struct PathQualityComparator
  29. {
  30. bool operator ()(const SharedPtr<Path> & a, const SharedPtr<Path> & b)
  31. {
  32. if(a->_failoverScore == b->_failoverScore) {
  33. return a < b;
  34. }
  35. return a->_failoverScore > b->_failoverScore;
  36. }
  37. };
  38. public:
  39. // TODO: Remove
  40. bool _header;
  41. int64_t _lastLogTS;
  42. int64_t _lastPrintTS;
  43. void dumpInfo(const int64_t now);
  44. bool relevant();
  45. SharedPtr<Link> getLink(const SharedPtr<Path>& path);
  46. /**
  47. * Constructor. Creates a bond based off of ZT defaults
  48. *
  49. * @param renv Runtime environment
  50. * @param policy Bonding policy
  51. * @param peer
  52. */
  53. Bond(const RuntimeEnvironment *renv, int policy, const SharedPtr<Peer>& peer);
  54. /**
  55. * Constructor. For use when user intends to manually specify parameters
  56. *
  57. * @param basePolicy
  58. * @param policyAlias
  59. * @param peer
  60. */
  61. Bond(const RuntimeEnvironment *renv, std::string& basePolicy, std::string& policyAlias, const SharedPtr<Peer>& peer);
  62. /**
  63. * Constructor. Creates a bond based off of a user-defined bond template
  64. *
  65. * @param renv Runtime environment
  66. * @param original
  67. * @param peer
  68. */
  69. Bond(const RuntimeEnvironment *renv, SharedPtr<Bond> originalBond, const SharedPtr<Peer>& peer);
  70. /**
  71. * @return The human-readable name of the bonding policy
  72. */
  73. std::string policyAlias() { return _policyAlias; }
  74. /**
  75. * Inform the bond about the path that its peer (owning object) just learned about
  76. *
  77. * @param path Newly-learned Path which should now be handled by the Bond
  78. * @param now Current time
  79. */
  80. void nominatePath(const SharedPtr<Path>& path, int64_t now);
  81. /**
  82. * Propagate and memoize often-used bonding preferences for each path
  83. */
  84. void applyUserPrefs();
  85. /**
  86. * Check path states and perform bond rebuilds if needed.
  87. *
  88. * @param now Current time
  89. * @param rebuild Whether or not the bond should be reconstructed.
  90. */
  91. void curateBond(const int64_t now, bool rebuild);
  92. /**
  93. * Periodically perform statistical summaries of quality metrics for all paths.
  94. *
  95. * @param now Current time
  96. */
  97. void estimatePathQuality(int64_t now);
  98. /**
  99. * Record an invalid incoming packet. This packet failed
  100. * MAC/compression/cipher checks and will now contribute to a
  101. * Packet Error Ratio (PER).
  102. *
  103. * @param path Path over which packet was received
  104. */
  105. void recordIncomingInvalidPacket(const SharedPtr<Path>& path);
  106. /**
  107. * Record statistics on outbound an packet.
  108. *
  109. * @param path Path over which packet is being sent
  110. * @param packetId Packet ID
  111. * @param payloadLength Packet data length
  112. * @param verb Packet verb
  113. * @param flowId Flow ID
  114. * @param now Current time
  115. */
  116. void recordOutgoingPacket(const SharedPtr<Path> &path, uint64_t packetId,
  117. uint16_t payloadLength, Packet::Verb verb, int32_t flowId, int64_t now);
  118. /**
  119. * Process the contents of an inbound VERB_QOS_MEASUREMENT to gather path quality observations.
  120. *
  121. * @param now Current time
  122. * @param count Number of records
  123. * @param rx_id table of packet IDs
  124. * @param rx_ts table of holding times
  125. */
  126. void receivedQoS(const SharedPtr<Path>& path, int64_t now, int count, uint64_t *rx_id, uint16_t *rx_ts);
  127. /**
  128. * Process the contents of an inbound VERB_ACK to gather path quality observations.
  129. *
  130. * @param path Path over which packet was received
  131. * @param now Current time
  132. * @param ackedBytes Number of bytes ACKed by this VERB_ACK
  133. */
  134. void receivedAck(const SharedPtr<Path>& path, int64_t now, int32_t ackedBytes);
  135. /**
  136. * Generate the contents of a VERB_QOS_MEASUREMENT packet.
  137. *
  138. * @param now Current time
  139. * @param qosBuffer destination buffer
  140. * @return Size of payload
  141. */
  142. int32_t generateQoSPacket(const SharedPtr<Path>& path, int64_t now, char *qosBuffer);
  143. /**
  144. * Record statistics for an inbound packet.
  145. *
  146. * @param path Path over which packet was received
  147. * @param packetId Packet ID
  148. * @param payloadLength Packet data length
  149. * @param verb Packet verb
  150. * @param flowId Flow ID
  151. * @param now Current time
  152. */
  153. void recordIncomingPacket(const SharedPtr<Path>& path, uint64_t packetId, uint16_t payloadLength,
  154. Packet::Verb verb, int32_t flowId, int64_t now);
  155. /**
  156. * Determines the most appropriate path for packet and flow egress. This decision is made by
  157. * the underlying bonding policy as well as QoS-related statistical observations of path quality.
  158. *
  159. * @param now Current time
  160. * @param flowId Flow ID
  161. * @return Pointer to suggested Path
  162. */
  163. SharedPtr<Path> getAppropriatePath(int64_t now, int32_t flowId);
  164. /**
  165. * Creates a new flow record
  166. *
  167. * @param path Path over which flow shall be handled
  168. * @param flowId Flow ID
  169. * @param entropy A byte of entropy to be used by the bonding algorithm
  170. * @param now Current time
  171. * @return Pointer to newly-created Flow
  172. */
  173. SharedPtr<Flow> createFlow(const SharedPtr<Path> &path, int32_t flowId, unsigned char entropy, int64_t now);
  174. /**
  175. * Removes flow records that are past a certain age limit.
  176. *
  177. * @param age Age threshold to be forgotten
  178. * @param oldest Whether only the oldest shall be forgotten
  179. * @param now Current time
  180. */
  181. void forgetFlowsWhenNecessary(uint64_t age, bool oldest, int64_t now);
  182. /**
  183. * Assigns a new flow to a bonded path
  184. *
  185. * @param flow Flow to be assigned
  186. * @param now Current time
  187. */
  188. bool assignFlowToBondedPath(SharedPtr<Flow> &flow, int64_t now);
  189. /**
  190. * Determine whether a path change should occur given the remote peer's reported utility and our
  191. * local peer's known utility. This has the effect of assigning inbound and outbound traffic to
  192. * the same path.
  193. *
  194. * @param now Current time
  195. * @param path Path over which the negotiation request was received
  196. * @param remoteUtility How much utility the remote peer claims to gain by using the declared path
  197. */
  198. void processIncomingPathNegotiationRequest(uint64_t now, SharedPtr<Path> &path, int16_t remoteUtility);
  199. /**
  200. * Determine state of path synchronization and whether a negotiation request
  201. * shall be sent to the peer.
  202. *
  203. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  204. * @param now Current time
  205. */
  206. void pathNegotiationCheck(void *tPtr, const int64_t now);
  207. /**
  208. * Sends a VERB_ACK to the remote peer.
  209. *
  210. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  211. * @param path Path over which packet should be sent
  212. * @param localSocket Local source socket
  213. * @param atAddress
  214. * @param now Current time
  215. */
  216. void sendACK(void *tPtr,const SharedPtr<Path> &path,int64_t localSocket,
  217. const InetAddress &atAddress,int64_t now);
  218. /**
  219. * Sends a VERB_QOS_MEASUREMENT to the remote peer.
  220. *
  221. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  222. * @param path Path over which packet should be sent
  223. * @param localSocket Local source socket
  224. * @param atAddress
  225. * @param now Current time
  226. */
  227. void sendQOS_MEASUREMENT(void *tPtr,const SharedPtr<Path> &path,int64_t localSocket,
  228. const InetAddress &atAddress,int64_t now);
  229. /**
  230. * Sends a VERB_PATH_NEGOTIATION_REQUEST to the remote peer.
  231. *
  232. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  233. * @param path Path over which packet should be sent
  234. */
  235. void sendPATH_NEGOTIATION_REQUEST(void *tPtr, const SharedPtr<Path> &path);
  236. /**
  237. *
  238. * @param now Current time
  239. */
  240. void processBalanceTasks(int64_t now);
  241. /**
  242. * Perform periodic tasks unique to active-backup
  243. *
  244. * @param now Current time
  245. */
  246. void processActiveBackupTasks(int64_t now);
  247. /**
  248. * Switches the active link in an active-backup scenario to the next best during
  249. * a failover event.
  250. *
  251. * @param now Current time
  252. */
  253. void dequeueNextActiveBackupPath(uint64_t now);
  254. /**
  255. * Set bond parameters to reasonable defaults, these may later be overwritten by
  256. * user-specified parameters.
  257. *
  258. * @param policy Bonding policy
  259. * @param templateBond
  260. */
  261. void setReasonableDefaults(int policy, SharedPtr<Bond> templateBond, bool useTemplate);
  262. /**
  263. * Check and assign user-specified quality weights to this bond.
  264. *
  265. * @param weights Set of user-specified weights
  266. * @param len Length of weight vector
  267. */
  268. void setUserQualityWeights(float weights[], int len);
  269. /**
  270. * @param latencyInMilliseconds Maximum acceptable latency.
  271. */
  272. void setMaxAcceptableLatency(int16_t latencyInMilliseconds) {
  273. _maxAcceptableLatency = latencyInMilliseconds;
  274. }
  275. /**
  276. * @param latencyInMilliseconds Maximum acceptable (mean) latency.
  277. */
  278. void setMaxAcceptableMeanLatency(int16_t latencyInMilliseconds) {
  279. _maxAcceptableMeanLatency = latencyInMilliseconds;
  280. }
  281. /**
  282. * @param latencyVarianceInMilliseconds Maximum acceptable packet delay variance (jitter).
  283. */
  284. void setMaxAcceptablePacketDelayVariance(int16_t latencyVarianceInMilliseconds) {
  285. _maxAcceptablePacketDelayVariance = latencyVarianceInMilliseconds;
  286. }
  287. /**
  288. * @param lossRatio Maximum acceptable packet loss ratio (PLR).
  289. */
  290. void setMaxAcceptablePacketLossRatio(float lossRatio) {
  291. _maxAcceptablePacketLossRatio = lossRatio;
  292. }
  293. /**
  294. * @param errorRatio Maximum acceptable packet error ratio (PER).
  295. */
  296. void setMaxAcceptablePacketErrorRatio(float errorRatio) {
  297. _maxAcceptablePacketErrorRatio = errorRatio;
  298. }
  299. /**
  300. * @param errorRatio Maximum acceptable packet error ratio (PER).
  301. */
  302. void setMinAcceptableAllocation(float minAlloc) {
  303. _minAcceptableAllocation = minAlloc * 255;
  304. }
  305. /**
  306. * @return Whether the user has defined links for use on this bond
  307. */
  308. inline bool userHasSpecifiedLinks() { return _userHasSpecifiedLinks; }
  309. /**
  310. * @return Whether the user has defined a set of failover link(s) for this bond
  311. */
  312. inline bool userHasSpecifiedFailoverInstructions() { return _userHasSpecifiedFailoverInstructions; };
  313. /**
  314. * @return Whether the user has specified a primary link
  315. */
  316. inline bool userHasSpecifiedPrimaryLink() { return _userHasSpecifiedPrimaryLink; }
  317. /**
  318. * @return Whether the user has specified link speeds
  319. */
  320. inline bool userHasSpecifiedLinkSpeeds() { return _userHasSpecifiedLinkSpeeds; }
  321. /**
  322. * Periodically perform maintenance tasks for each active bond.
  323. *
  324. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  325. * @param now Current time
  326. */
  327. void processBackgroundTasks(void *tPtr, int64_t now);
  328. /**
  329. * Rate limit gate for VERB_ACK
  330. *
  331. * @param now Current time
  332. * @return Whether the incoming packet should be rate-gated
  333. */
  334. inline bool rateGateACK(const int64_t now)
  335. {
  336. _ackCutoffCount++;
  337. int numToDrain = _lastAckRateCheck ? (now - _lastAckRateCheck) / ZT_ACK_DRAINAGE_DIVISOR : _ackCutoffCount;
  338. _lastAckRateCheck = now;
  339. if (_ackCutoffCount > numToDrain) {
  340. _ackCutoffCount-=numToDrain;
  341. } else {
  342. _ackCutoffCount = 0;
  343. }
  344. return (_ackCutoffCount < ZT_ACK_CUTOFF_LIMIT);
  345. }
  346. /**
  347. * Rate limit gate for VERB_QOS_MEASUREMENT
  348. *
  349. * @param now Current time
  350. * @return Whether the incoming packet should be rate-gated
  351. */
  352. inline bool rateGateQoS(const int64_t now)
  353. {
  354. _qosCutoffCount++;
  355. int numToDrain = (now - _lastQoSRateCheck) / ZT_QOS_DRAINAGE_DIVISOR;
  356. _lastQoSRateCheck = now;
  357. if (_qosCutoffCount > numToDrain) {
  358. _qosCutoffCount-=numToDrain;
  359. } else {
  360. _qosCutoffCount = 0;
  361. }
  362. return (_qosCutoffCount < ZT_QOS_CUTOFF_LIMIT);
  363. }
  364. /**
  365. * Rate limit gate for VERB_PATH_NEGOTIATION_REQUEST
  366. *
  367. * @param now Current time
  368. * @return Whether the incoming packet should be rate-gated
  369. */
  370. inline bool rateGatePathNegotiation(const int64_t now)
  371. {
  372. if ((now - _lastPathNegotiationReceived) <= ZT_PATH_NEGOTIATION_CUTOFF_TIME)
  373. ++_pathNegotiationCutoffCount;
  374. else _pathNegotiationCutoffCount = 0;
  375. _lastPathNegotiationReceived = now;
  376. return (_pathNegotiationCutoffCount < ZT_PATH_NEGOTIATION_CUTOFF_LIMIT);
  377. }
  378. /**
  379. * @param interval Maximum amount of time user expects a failover to take on this bond.
  380. */
  381. inline void setFailoverInterval(uint32_t interval) { _failoverInterval = interval; }
  382. /**
  383. * @param strategy Strategy that the bond uses to re-assign protocol flows.
  384. */
  385. inline void setFlowRebalanceStrategy(uint32_t strategy) { _flowRebalanceStrategy = strategy; }
  386. /**
  387. * @param strategy Strategy that the bond uses to prob for path aliveness and quality
  388. */
  389. inline void setLinkMonitorStrategy(uint8_t strategy) { _linkMonitorStrategy = strategy; }
  390. /**
  391. * @return the current up delay parameter
  392. */
  393. inline uint16_t getUpDelay() { return _upDelay; }
  394. /**
  395. * @param upDelay Length of time before a newly-discovered path is admitted to the bond
  396. */
  397. inline void setUpDelay(int upDelay) { if (upDelay >= 0) { _upDelay = upDelay; } }
  398. /**
  399. * @return Length of time before a newly-failed path is removed from the bond
  400. */
  401. inline uint16_t getDownDelay() { return _downDelay; }
  402. /**
  403. * @param downDelay Length of time before a newly-failed path is removed from the bond
  404. */
  405. inline void setDownDelay(int downDelay) { if (downDelay >= 0) { _downDelay = downDelay; } }
  406. /**
  407. * @return the current monitoring interval for the bond (can be overridden with intervals specific to certain links.)
  408. */
  409. inline uint16_t getBondMonitorInterval() { return _bondMonitorInterval; }
  410. /**
  411. * Set the current monitoring interval for the bond (can be overridden with intervals specific to certain links.)
  412. *
  413. * @param monitorInterval How often gratuitous VERB_HELLO(s) are sent to remote peer.
  414. */
  415. inline void setBondMonitorInterval(uint16_t interval) { _bondMonitorInterval = interval; }
  416. /**
  417. * @param policy Bonding policy for this bond
  418. */
  419. inline void setPolicy(uint8_t policy) { _bondingPolicy = policy; }
  420. /**
  421. * @return the current bonding policy
  422. */
  423. inline uint8_t getPolicy() { return _bondingPolicy; }
  424. /**
  425. *
  426. * @param allowFlowHashing
  427. */
  428. inline void setFlowHashing(bool allowFlowHashing) { _allowFlowHashing = allowFlowHashing; }
  429. /**
  430. * @return Whether flow-hashing is currently enabled for this bond.
  431. */
  432. bool flowHashingEnabled() { return _allowFlowHashing; }
  433. /**
  434. *
  435. * @param packetsPerLink
  436. */
  437. inline void setPacketsPerLink(int packetsPerLink) { _packetsPerLink = packetsPerLink; }
  438. /**
  439. *
  440. * @param linkSelectMethod
  441. */
  442. inline void setLinkSelectMethod(uint8_t method) { _abLinkSelectMethod = method; }
  443. /**
  444. *
  445. * @return
  446. */
  447. inline uint8_t getLinkSelectMethod() { return _abLinkSelectMethod; }
  448. /**
  449. *
  450. * @param allowPathNegotiation
  451. */
  452. inline void setAllowPathNegotiation(bool allowPathNegotiation) { _allowPathNegotiation = allowPathNegotiation; }
  453. /**
  454. *
  455. * @return
  456. */
  457. inline bool allowPathNegotiation() { return _allowPathNegotiation; }
  458. private:
  459. const RuntimeEnvironment *RR;
  460. AtomicCounter __refCount;
  461. /**
  462. * Custom name given by the user to this bond type.
  463. */
  464. std::string _policyAlias;
  465. /**
  466. * Paths that this bond has been made aware of but that are not necessarily
  467. * part of the bond proper.
  468. */
  469. SharedPtr<Path> _paths[ZT_MAX_PEER_NETWORK_PATHS];
  470. /**
  471. * Set of indices corresponding to paths currently included in the bond proper. This
  472. * may only be updated during a call to curateBond(). The reason for this is so that
  473. * we can simplify the high frequency packet egress logic.
  474. */
  475. int _bondedIdx[ZT_MAX_PEER_NETWORK_PATHS];
  476. /**
  477. * Number of paths currently included in the _bondedIdx set.
  478. */
  479. int _numBondedPaths;
  480. /**
  481. * Flows hashed according to port and protocol
  482. */
  483. std::map<int32_t,SharedPtr<Flow> > _flows;
  484. float _qualityWeights[ZT_QOS_WEIGHT_SIZE]; // How much each factor contributes to the "quality" score of a path.
  485. uint8_t _bondingPolicy;
  486. uint32_t _upDelay;
  487. uint32_t _downDelay;
  488. // active-backup
  489. SharedPtr<Path> _abPath; // current active path
  490. std::list<SharedPtr<Path> > _abFailoverQueue;
  491. uint8_t _abLinkSelectMethod; // link re-selection policy for the primary link in active-backup
  492. uint64_t _lastActiveBackupPathChange;
  493. // balance-rr
  494. uint8_t _rrIdx; // index to path currently in use during Round Robin operation
  495. uint16_t _rrPacketsSentOnCurrLink; // number of packets sent on this link since the most recent path switch.
  496. /**
  497. * How many packets will be sent on a path before moving to the next path
  498. * in the round-robin sequence. A value of zero will cause a random path
  499. * selection for each outgoing packet.
  500. */
  501. int _packetsPerLink;
  502. // balance-aware
  503. uint64_t _totalBondUnderload;
  504. uint8_t _flowRebalanceStrategy;
  505. // dynamic link monitoring
  506. uint8_t _linkMonitorStrategy;
  507. uint64_t _lastFrame;
  508. uint32_t _dynamicPathMonitorInterval;
  509. // path negotiation
  510. int16_t _localUtility;
  511. SharedPtr<Path> negotiatedPath;
  512. uint8_t _numSentPathNegotiationRequests;
  513. unsigned int _pathNegotiationCutoffCount;
  514. bool _allowPathNegotiation;
  515. uint64_t _lastPathNegotiationReceived;
  516. uint64_t _lastSentPathNegotiationRequest;
  517. // timers
  518. uint32_t _failoverInterval;
  519. uint32_t _qosSendInterval;
  520. uint32_t _ackSendInterval;
  521. uint16_t _ackCutoffCount;
  522. uint64_t _lastAckRateCheck;
  523. uint16_t _qosCutoffCount;
  524. uint64_t _lastQoSRateCheck;
  525. uint32_t throughputMeasurementInterval;
  526. uint32_t _qualityEstimationInterval;
  527. // timestamps
  528. uint64_t _lastCheckUserPreferences;
  529. uint64_t _lastQualityEstimation;
  530. uint64_t _lastFlowStatReset;
  531. uint64_t _lastFlowExpirationCheck;
  532. uint64_t _lastFlowRebalance;
  533. uint64_t _lastPathNegotiationCheck;
  534. uint64_t _lastBackgroundTaskCheck;
  535. float _maxAcceptablePacketLossRatio;
  536. float _maxAcceptablePacketErrorRatio;
  537. uint16_t _maxAcceptableLatency;
  538. uint16_t _maxAcceptableMeanLatency;
  539. uint16_t _maxAcceptablePacketDelayVariance;
  540. uint8_t _minAcceptableAllocation;
  541. /**
  542. * Default initial punishment inflicted on misbehaving paths. Punishment slowly
  543. * drains linearly. For each eligibility change the remaining punishment is doubled.
  544. */
  545. uint32_t _defaultPathRefractoryPeriod;
  546. /**
  547. * Whether the current bonding policy requires computation of path statistics
  548. */
  549. bool _shouldCollectPathStatistics;
  550. /**
  551. * Free byte of entropy that is updated on every packet egress event.
  552. */
  553. unsigned char _freeRandomByte;
  554. /**
  555. * Remote peer that this bond services
  556. */
  557. SharedPtr<Peer> _peer;
  558. Mutex _paths_m;
  559. Mutex _flows_m;
  560. /**
  561. * Whether the user has specified links for this bond.
  562. */
  563. bool _userHasSpecifiedLinks;
  564. /**
  565. * Whether the user has specified a primary link for this bond.
  566. */
  567. bool _userHasSpecifiedPrimaryLink;
  568. /**
  569. * Whether the user has specified failover instructions for this bond.
  570. */
  571. bool _userHasSpecifiedFailoverInstructions;
  572. /**
  573. * Whether the user has specified links speeds for this bond.
  574. */
  575. bool _userHasSpecifiedLinkSpeeds;
  576. /**
  577. * How frequently (in ms) a VERB_ECHO is sent to a peer to verify that a
  578. * path is still active. A value of zero (0) will disable active path
  579. * monitoring; as result, all monitoring will be a function of traffic.
  580. */
  581. uint16_t _bondMonitorInterval;
  582. /**
  583. * Whether or not flow hashing is allowed.
  584. */
  585. bool _allowFlowHashing;
  586. };
  587. } // namespace ZeroTier
  588. #endif