Bond.hpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #ifndef ZT_BOND_HPP
  9. #define ZT_BOND_HPP
  10. #include "../osdep/Binder.hpp"
  11. #include "../osdep/Phy.hpp"
  12. #include "Packet.hpp"
  13. #include "Path.hpp"
  14. #include "RuntimeEnvironment.hpp"
  15. #include "Trace.hpp"
  16. #include <cstdarg>
  17. #include <deque>
  18. #include <map>
  19. /**
  20. * Indices for the path quality weight vector
  21. */
  22. enum ZT_BondQualityWeightIndex { ZT_QOS_LAT_MAX_IDX, ZT_QOS_PDV_MAX_IDX, ZT_QOS_PLR_MAX_IDX, ZT_QOS_PER_MAX_IDX, ZT_QOS_LAT_WEIGHT_IDX, ZT_QOS_PDV_WEIGHT_IDX, ZT_QOS_PLR_WEIGHT_IDX, ZT_QOS_PER_WEIGHT_IDX, ZT_QOS_PARAMETER_SIZE };
  23. /**
  24. * Multipath bonding policy
  25. */
  26. enum ZT_BondBondingPolicy {
  27. /**
  28. * Normal operation. No fault tolerance, no load balancing
  29. */
  30. ZT_BOND_POLICY_NONE = 0,
  31. /**
  32. * Sends traffic out on only one path at a time. Configurable immediate
  33. * fail-over.
  34. */
  35. ZT_BOND_POLICY_ACTIVE_BACKUP = 1,
  36. /**
  37. * Sends traffic out on all paths
  38. */
  39. ZT_BOND_POLICY_BROADCAST = 2,
  40. /**
  41. * Stripes packets across all paths
  42. */
  43. ZT_BOND_POLICY_BALANCE_RR = 3,
  44. /**
  45. * Packets destined for specific peers will always be sent over the same
  46. * path.
  47. */
  48. ZT_BOND_POLICY_BALANCE_XOR = 4,
  49. /**
  50. * Balances flows among all paths according to path performance
  51. */
  52. ZT_BOND_POLICY_BALANCE_AWARE = 5
  53. };
  54. /**
  55. * Multipath active re-selection policy (linkSelectMethod)
  56. */
  57. enum ZT_BondLinkSelectMethod {
  58. /**
  59. * Primary link regains status as active link whenever it comes back up
  60. * (default when links are explicitly specified)
  61. */
  62. ZT_BOND_RESELECTION_POLICY_ALWAYS = 0,
  63. /**
  64. * Primary link regains status as active link when it comes back up and
  65. * (if) it is better than the currently-active link.
  66. */
  67. ZT_BOND_RESELECTION_POLICY_BETTER = 1,
  68. /**
  69. * Primary link regains status as active link only if the currently-active
  70. * link fails.
  71. */
  72. ZT_BOND_RESELECTION_POLICY_FAILURE = 2,
  73. /**
  74. * The primary link can change if a superior path is detected.
  75. * (default if user provides no fail-over guidance)
  76. */
  77. ZT_BOND_RESELECTION_POLICY_OPTIMIZE = 3
  78. };
  79. /**
  80. * Mode of multipath link interface
  81. */
  82. enum ZT_BondLinkMode { ZT_BOND_SLAVE_MODE_PRIMARY = 0, ZT_BOND_SLAVE_MODE_SPARE = 1 };
  83. #include "../node/AtomicCounter.hpp"
  84. #include "../node/SharedPtr.hpp"
  85. #include <string>
  86. namespace ZeroTier {
  87. class Link {
  88. friend class SharedPtr<Link>;
  89. public:
  90. /**
  91. *
  92. * @param ifnameStr
  93. * @param ipvPref
  94. * @param capacity
  95. * @param enabled
  96. * @param mode
  97. * @param failoverToLinkStr
  98. */
  99. Link(std::string ifnameStr, uint8_t ipvPref, uint16_t mtu, uint32_t capacity, bool enabled, uint8_t mode, std::string failoverToLinkStr)
  100. : _ifnameStr(ifnameStr)
  101. , _ipvPref(ipvPref)
  102. , _mtu(mtu)
  103. , _capacity(capacity)
  104. , _relativeCapacity(0.0)
  105. , _enabled(enabled)
  106. , _mode(mode)
  107. , _failoverToLinkStr(failoverToLinkStr)
  108. , _isUserSpecified(false)
  109. {
  110. }
  111. /**
  112. * @return The string representation of this link's underlying interface's system name.
  113. */
  114. inline std::string ifname()
  115. {
  116. return _ifnameStr;
  117. }
  118. /**
  119. * @return Whether this link is designated as a primary.
  120. */
  121. inline bool primary()
  122. {
  123. return _mode == ZT_BOND_SLAVE_MODE_PRIMARY;
  124. }
  125. /**
  126. * @return Whether this link is designated as a spare.
  127. */
  128. inline bool spare()
  129. {
  130. return _mode == ZT_BOND_SLAVE_MODE_SPARE;
  131. }
  132. /**
  133. * @return The name of the link interface that should be used in the event of a failure.
  134. */
  135. inline std::string failoverToLink()
  136. {
  137. return _failoverToLinkStr;
  138. }
  139. /**
  140. * @return Whether this link interface was specified by the user or auto-detected.
  141. */
  142. inline bool isUserSpecified()
  143. {
  144. return _isUserSpecified;
  145. }
  146. /**
  147. * Signify that this link was specified by the user and not the result of auto-detection.
  148. *
  149. * @param isUserSpecified
  150. */
  151. inline void setAsUserSpecified(bool isUserSpecified)
  152. {
  153. _isUserSpecified = isUserSpecified;
  154. }
  155. /**
  156. * @return Whether or not the user has specified failover instructions.
  157. */
  158. inline bool userHasSpecifiedFailoverInstructions()
  159. {
  160. return _failoverToLinkStr.length();
  161. }
  162. /**
  163. * @return The capacity of the link relative to others in the bond.
  164. */
  165. inline float relativeCapacity()
  166. {
  167. return _relativeCapacity;
  168. }
  169. /**
  170. * Sets the capacity of the link relative to others in the bond.
  171. *
  172. * @param relativeCapacity The capacity relative to the rest of the link.
  173. */
  174. inline void setRelativeCapacity(float relativeCapacity)
  175. {
  176. _relativeCapacity = relativeCapacity;
  177. }
  178. /**
  179. * @return The absolute capacity of the link (as specified by the user.)
  180. */
  181. inline uint32_t capacity()
  182. {
  183. return _capacity;
  184. }
  185. /**
  186. * @return The address preference for this link (as specified by the user.)
  187. */
  188. inline uint8_t ipvPref()
  189. {
  190. return _ipvPref;
  191. }
  192. /**
  193. * @return The MTU for this link (as specified by the user.)
  194. */
  195. inline uint16_t mtu()
  196. {
  197. return _mtu;
  198. }
  199. /**
  200. * @return The mode (e.g. primary/spare) for this link (as specified by the user.)
  201. */
  202. inline uint8_t mode()
  203. {
  204. return _mode;
  205. }
  206. /**
  207. * @return Whether this link is enabled or disabled
  208. */
  209. inline uint8_t enabled()
  210. {
  211. return _enabled;
  212. }
  213. private:
  214. /**
  215. * String representation of underlying interface's system name
  216. */
  217. std::string _ifnameStr;
  218. /**
  219. * What preference (if any) a user has for IP protocol version used in
  220. * path aggregations. Preference is expressed in the order of the digits:
  221. *
  222. * 0: no preference
  223. * 4: IPv4 only
  224. * 6: IPv6 only
  225. * 46: IPv4 over IPv6
  226. * 64: IPv6 over IPv4
  227. */
  228. uint8_t _ipvPref;
  229. /**
  230. * The physical-layer MTU for this link
  231. */
  232. uint16_t _mtu;
  233. /**
  234. * User-specified capacity of this link
  235. */
  236. uint32_t _capacity;
  237. /**
  238. * Speed relative to other specified links (computed by Bond)
  239. */
  240. float _relativeCapacity;
  241. /**
  242. * Whether this link is enabled, or (disabled (possibly bad config))
  243. */
  244. uint8_t _enabled;
  245. /**
  246. * Whether this link is designated as a primary, a spare, or no preference.
  247. */
  248. uint8_t _mode;
  249. /**
  250. * The specific name of the link to be used in the event that this
  251. * link fails.
  252. */
  253. std::string _failoverToLinkStr;
  254. /**
  255. * Whether or not this link was created as a result of manual user specification. This is
  256. * important to know because certain policy decisions are dependent on whether the user
  257. * intents to use a specific set of interfaces.
  258. */
  259. bool _isUserSpecified;
  260. AtomicCounter __refCount;
  261. };
  262. class Link;
  263. class Peer;
  264. class Bond {
  265. public:
  266. /**
  267. * Stop bond's internal functions (can be resumed)
  268. */
  269. void stopBond();
  270. /**
  271. * Start or resume a bond's internal functions
  272. */
  273. void startBond();
  274. /**
  275. * @return Whether this link is permitted to become a member of a bond.
  276. */
  277. static bool linkAllowed(std::string& policyAlias, SharedPtr<Link> link);
  278. /**
  279. * @return The minimum interval required to poll the active bonds to fulfill all active monitoring timing requirements.
  280. */
  281. static int minReqMonitorInterval()
  282. {
  283. return _minReqMonitorInterval;
  284. }
  285. /**
  286. * @return Whether the bonding layer is currently set up to be used.
  287. */
  288. static bool inUse()
  289. {
  290. return ! _bondPolicyTemplates.empty() || _defaultPolicy;
  291. }
  292. /**
  293. * Sets a pointer to an instance of _binder used by the Bond to get interface data
  294. */
  295. static void setBinder(Binder* b)
  296. {
  297. _binder = b;
  298. }
  299. /**
  300. * @param basePolicyName Bonding policy name (See ZeroTierOne.h)
  301. * @return The bonding policy code for a given human-readable bonding policy name
  302. */
  303. static int getPolicyCodeByStr(const std::string& basePolicyName)
  304. {
  305. if (basePolicyName == "active-backup") {
  306. return 1;
  307. }
  308. if (basePolicyName == "broadcast") {
  309. return 2;
  310. }
  311. if (basePolicyName == "balance-rr") {
  312. return 3;
  313. }
  314. if (basePolicyName == "balance-xor") {
  315. return 4;
  316. }
  317. if (basePolicyName == "balance-aware") {
  318. return 5;
  319. }
  320. return 0; // "none"
  321. }
  322. /**
  323. * @param policy Bonding policy code (See ZeroTierOne.h)
  324. * @return The human-readable name for the given bonding policy code
  325. */
  326. static std::string getPolicyStrByCode(int policy)
  327. {
  328. if (policy == 1) {
  329. return "active-backup";
  330. }
  331. if (policy == 2) {
  332. return "broadcast";
  333. }
  334. if (policy == 3) {
  335. return "balance-rr";
  336. }
  337. if (policy == 4) {
  338. return "balance-xor";
  339. }
  340. if (policy == 5) {
  341. return "balance-aware";
  342. }
  343. return "none";
  344. }
  345. /**
  346. * Sets the default bonding policy for new or undefined bonds.
  347. *
  348. * @param bp Bonding policy
  349. */
  350. static void setBondingLayerDefaultPolicy(uint8_t bp)
  351. {
  352. _defaultPolicy = bp;
  353. }
  354. /**
  355. * Sets the default (custom) bonding policy for new or undefined bonds.
  356. *
  357. * @param alias Human-readable string alias for bonding policy
  358. */
  359. static void setBondingLayerDefaultPolicyStr(std::string alias)
  360. {
  361. _defaultPolicyStr = alias;
  362. }
  363. /**
  364. * Add a user-defined link to a given bonding policy.
  365. *
  366. * @param policyAlias User-defined custom name for variant of bonding policy
  367. * @param link Pointer to new link definition
  368. */
  369. static void addCustomLink(std::string& policyAlias, SharedPtr<Link> link);
  370. /**
  371. * Add a user-defined bonding policy that is based on one of the standard types.
  372. *
  373. * @param newBond Pointer to custom Bond object
  374. * @return Whether a uniquely-named custom policy was successfully added
  375. */
  376. static bool addCustomPolicy(const SharedPtr<Bond>& newBond);
  377. /**
  378. * Assigns a specific bonding policy
  379. *
  380. * @param identity
  381. * @param policyAlias
  382. * @return
  383. */
  384. static bool assignBondingPolicyToPeer(int64_t identity, const std::string& policyAlias);
  385. /**
  386. * Get pointer to bond by a given peer ID
  387. *
  388. * @param peer Remote peer ID
  389. * @return A pointer to the Bond
  390. */
  391. static SharedPtr<Bond> getBondByPeerId(int64_t identity);
  392. /**
  393. * Set MTU for link by given interface name and IP address (across all bonds)
  394. *
  395. * @param mtu MTU to be used on this link
  396. * @param ifStr interface name to match
  397. * @param ipStr IP address to match
  398. * @return Whether the MTU was set
  399. */
  400. static bool setAllMtuByTuple(uint16_t mtu, const std::string& ifStr, const std::string& ipStr);
  401. /**
  402. * Set MTU for link by given interface name and IP address
  403. *
  404. * @param mtu MTU to be used on this link
  405. * @param ifStr interface name to match
  406. * @param ipStr IP address to match
  407. * @return Whether the MTU was set
  408. */
  409. bool setMtuByTuple(uint16_t mtu, const std::string& ifStr, const std::string& ipStr);
  410. /**
  411. * Add a new bond to the bond controller.
  412. *
  413. * @param renv Runtime environment
  414. * @param peer Remote peer that this bond services
  415. * @return A pointer to the newly created Bond
  416. */
  417. static SharedPtr<Bond> createBond(const RuntimeEnvironment* renv, const SharedPtr<Peer>& peer);
  418. /**
  419. * Remove a bond from the bond controller.
  420. *
  421. * @param peerId Remote peer that this bond services
  422. */
  423. static void destroyBond(uint64_t peerId);
  424. /**
  425. * Periodically perform maintenance tasks for the bonding layer.
  426. *
  427. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  428. * @param now Current time
  429. */
  430. static void processBackgroundTasks(void* tPtr, int64_t now);
  431. /**
  432. * Gets a reference to a physical link definition given a policy alias and a local socket.
  433. *
  434. * @param policyAlias Policy in use
  435. * @param localSocket Local source socket
  436. * @param createIfNeeded Whether a Link object is created if the name wasn't previously in the link map
  437. * @return Physical link definition
  438. */
  439. SharedPtr<Link> getLinkBySocket(const std::string& policyAlias, uint64_t localSocket, bool createIfNeeded);
  440. /**
  441. * Gets a reference to a physical link definition given its human-readable system name.
  442. *
  443. * @param policyAlias Policy in use
  444. * @param ifname Alphanumeric human-readable name
  445. * @return Physical link definition
  446. */
  447. static SharedPtr<Link> getLinkByName(const std::string& policyAlias, const std::string& ifname);
  448. private:
  449. static Phy<Bond*>* _phy;
  450. static Mutex _bonds_m;
  451. static Mutex _links_m;
  452. /**
  453. * The minimum required monitoring interval among all bonds
  454. */
  455. static int _minReqMonitorInterval;
  456. /**
  457. * The default bonding policy used for new bonds unless otherwise specified.
  458. */
  459. static uint8_t _defaultPolicy;
  460. /**
  461. * The default bonding policy used for new bonds unless otherwise specified.
  462. */
  463. static std::string _defaultPolicyStr;
  464. /**
  465. * All currently active bonds.
  466. */
  467. static std::map<int64_t, SharedPtr<Bond> > _bonds;
  468. /**
  469. * Map of peers to custom bonding policies
  470. */
  471. static std::map<int64_t, std::string> _policyTemplateAssignments;
  472. /**
  473. * User-defined bonding policies (can be assigned to a peer)
  474. */
  475. static std::map<std::string, SharedPtr<Bond> > _bondPolicyTemplates;
  476. /**
  477. * Set of links defined for a given bonding policy
  478. */
  479. static std::map<std::string, std::vector<SharedPtr<Link> > > _linkDefinitions;
  480. /**
  481. * Set of link objects mapped to their physical interfaces
  482. */
  483. static std::map<std::string, std::map<std::string, SharedPtr<Link> > > _interfaceToLinkMap;
  484. struct NominatedPath;
  485. struct Flow;
  486. friend class SharedPtr<Bond>;
  487. friend class Peer;
  488. public:
  489. void dumpInfo(int64_t now, bool force);
  490. std::string pathToStr(const SharedPtr<Path>& path);
  491. void dumpPathStatus(int64_t now, int pathIdx);
  492. SharedPtr<Link> getLink(const SharedPtr<Path>& path);
  493. /**
  494. * Constructor
  495. *
  496. *
  497. */
  498. Bond(const RuntimeEnvironment* renv);
  499. /**
  500. * Constructor. Creates a bond based off of ZT defaults
  501. *
  502. * @param renv Runtime environment
  503. * @param policy Bonding policy
  504. * @param peer
  505. */
  506. Bond(const RuntimeEnvironment* renv, int policy, const SharedPtr<Peer>& peer);
  507. /**
  508. * Constructor. For use when user intends to manually specify parameters
  509. *
  510. * @param basePolicy
  511. * @param policyAlias
  512. * @param peer
  513. */
  514. Bond(const RuntimeEnvironment* renv, std::string& basePolicy, std::string& policyAlias, const SharedPtr<Peer>& peer);
  515. /**
  516. * Constructor. Creates a bond based off of a user-defined bond template
  517. *
  518. * @param renv Runtime environment
  519. * @param original
  520. * @param peer
  521. */
  522. Bond(const RuntimeEnvironment* renv, SharedPtr<Bond> originalBond, const SharedPtr<Peer>& peer);
  523. /**
  524. * @return The human-readable name of the bonding policy
  525. */
  526. std::string policyAlias()
  527. {
  528. return _policyAlias;
  529. }
  530. /**
  531. * Return whether this bond is able to properly process traffic
  532. */
  533. bool isReady()
  534. {
  535. return _numBondedPaths;
  536. }
  537. /**
  538. * Inform the bond about the path that its peer (owning object) just learned about.
  539. * If the path is allowed to be used, it will be inducted into the bond on a trial
  540. * period where link statistics will be collected to judge its quality.
  541. *
  542. * @param path Newly-learned Path which should now be handled by the Bond
  543. * @param now Current time
  544. */
  545. void nominatePathToBond(const SharedPtr<Path>& path, int64_t now);
  546. /**
  547. * Add a nominated path to the bond. This merely maps the index from the nominated set
  548. * to a smaller set and sets the path's bonded flag to true.
  549. *
  550. * @param nominatedIdx The index in the nominated set
  551. * @param bondedIdx The index in the bonded set (subset of nominated)
  552. */
  553. void addPathToBond(int nominatedIdx, int bondedIdx);
  554. /**
  555. * Check path states and perform bond rebuilds if needed.
  556. *
  557. * @param now Current time
  558. * @param rebuild Whether or not the bond should be reconstructed.
  559. */
  560. void curateBond(int64_t now, bool rebuild);
  561. /**
  562. * Periodically perform statistical summaries of quality metrics for all paths.
  563. *
  564. * @param now Current time
  565. */
  566. void estimatePathQuality(int64_t now);
  567. /**
  568. * Record an invalid incoming packet. This packet failed
  569. * MAC/compression/cipher checks and will now contribute to a
  570. * Packet Error Ratio (PER).
  571. *
  572. * @param path Path over which packet was received
  573. */
  574. void recordIncomingInvalidPacket(const SharedPtr<Path>& path);
  575. /**
  576. * Record statistics on outbound an packet.
  577. *
  578. * @param path Path over which packet is being sent
  579. * @param packetId Packet ID
  580. * @param payloadLength Packet data length
  581. * @param verb Packet verb
  582. * @param flowId Flow ID
  583. * @param now Current time
  584. */
  585. void recordOutgoingPacket(const SharedPtr<Path>& path, uint64_t packetId, uint16_t payloadLength, Packet::Verb verb, int32_t flowId, int64_t now);
  586. /**
  587. * Process the contents of an inbound VERB_QOS_MEASUREMENT to gather path quality observations.
  588. *
  589. * @param now Current time
  590. * @param count Number of records
  591. * @param rx_id table of packet IDs
  592. * @param rx_ts table of holding times
  593. */
  594. void receivedQoS(const SharedPtr<Path>& path, int64_t now, int count, uint64_t* rx_id, uint16_t* rx_ts);
  595. /**
  596. * Process the contents of an inbound VERB_ACK to gather path quality observations.
  597. *
  598. * @param pathIdx Path over which packet was received
  599. * @param now Current time
  600. * @param ackedBytes Number of bytes ACKed by this VERB_ACK
  601. */
  602. void receivedAck(int pathIdx, int64_t now, int32_t ackedBytes);
  603. /**
  604. * Generate the contents of a VERB_QOS_MEASUREMENT packet.
  605. *
  606. * @param now Current time
  607. * @param qosBuffer destination buffer
  608. * @return Size of payload
  609. */
  610. int32_t generateQoSPacket(int pathIdx, int64_t now, char* qosBuffer);
  611. /**
  612. * Record statistics for an inbound packet.
  613. *
  614. * @param path Path over which packet was received
  615. * @param packetId Packet ID
  616. * @param payloadLength Packet data length
  617. * @param verb Packet verb
  618. * @param flowId Flow ID
  619. * @param now Current time
  620. */
  621. void recordIncomingPacket(const SharedPtr<Path>& path, uint64_t packetId, uint16_t payloadLength, Packet::Verb verb, int32_t flowId, int64_t now);
  622. /**
  623. * Determines the most appropriate path for packet and flow egress. This decision is made by
  624. * the underlying bonding policy as well as QoS-related statistical observations of path quality.
  625. *
  626. * @param now Current time
  627. * @param flowId Flow ID
  628. * @return Pointer to suggested Path
  629. */
  630. SharedPtr<Path> getAppropriatePath(int64_t now, int32_t flowId);
  631. /**
  632. * Creates a new flow record
  633. *
  634. * @param np Path over which flow shall be handled
  635. * @param flowId Flow ID
  636. * @param entropy A byte of entropy to be used by the bonding algorithm
  637. * @param now Current time
  638. * @return Pointer to newly-created Flow
  639. */
  640. SharedPtr<Flow> createFlow(int pathIdx, int32_t flowId, unsigned char entropy, int64_t now);
  641. /**
  642. * Removes flow records that are past a certain age limit.
  643. *
  644. * @param age Age threshold to be forgotten
  645. * @param oldest Whether only the oldest shall be forgotten
  646. * @param now Current time
  647. */
  648. void forgetFlowsWhenNecessary(uint64_t age, bool oldest, int64_t now);
  649. /**
  650. * Assigns a new flow to a bonded path
  651. *
  652. * @param flow Flow to be assigned
  653. * @param now Current time
  654. * @param reassign Whether this flow is being re-assigned to another path
  655. */
  656. bool assignFlowToBondedPath(SharedPtr<Flow>& flow, int64_t now, bool reassign);
  657. /**
  658. * Determine whether a path change should occur given the remote peer's reported utility and our
  659. * local peer's known utility. This has the effect of assigning inbound and outbound traffic to
  660. * the same path.
  661. *
  662. * @param now Current time
  663. * @param path Path over which the negotiation request was received
  664. * @param remoteUtility How much utility the remote peer claims to gain by using the declared path
  665. */
  666. void processIncomingPathNegotiationRequest(uint64_t now, SharedPtr<Path>& path, int16_t remoteUtility);
  667. /**
  668. * Determine state of path synchronization and whether a negotiation request
  669. * shall be sent to the peer.
  670. *
  671. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  672. * @param now Current time
  673. */
  674. void pathNegotiationCheck(void* tPtr, int64_t now);
  675. /**
  676. * Sends a VERB_ACK to the remote peer.
  677. *
  678. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  679. * @param path Path over which packet should be sent
  680. * @param localSocket Local source socket
  681. * @param atAddress
  682. * @param now Current time
  683. */
  684. void sendACK(void* tPtr, int pathIdx, int64_t localSocket, const InetAddress& atAddress, int64_t now);
  685. /**
  686. * Sends a VERB_QOS_MEASUREMENT to the remote peer.
  687. *
  688. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  689. * @param path Path over which packet should be sent
  690. * @param localSocket Local source socket
  691. * @param atAddress
  692. * @param now Current time
  693. */
  694. void sendQOS_MEASUREMENT(void* tPtr, int pathIdx, int64_t localSocket, const InetAddress& atAddress, int64_t now);
  695. /**
  696. * Sends a VERB_PATH_NEGOTIATION_REQUEST to the remote peer.
  697. *
  698. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  699. * @param path Path over which packet should be sent
  700. */
  701. void sendPATH_NEGOTIATION_REQUEST(void* tPtr, int pathIdx);
  702. /**
  703. *
  704. * @param now Current time
  705. */
  706. void processBalanceTasks(int64_t now);
  707. /**
  708. * Perform periodic tasks unique to active-backup
  709. *
  710. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  711. * @param now Current time
  712. */
  713. void processActiveBackupTasks(void* tPtr, int64_t now);
  714. /**
  715. * Switches the active link in an active-backup scenario to the next best during
  716. * a failover event.
  717. *
  718. * @param now Current time
  719. */
  720. void dequeueNextActiveBackupPath(uint64_t now);
  721. /**
  722. * Zero all timers
  723. */
  724. void initTimers();
  725. /**
  726. * Set bond parameters to reasonable defaults, these may later be overwritten by
  727. * user-specified parameters.
  728. *
  729. * @param policy Bonding policy
  730. * @param templateBond
  731. */
  732. void setBondParameters(int policy, SharedPtr<Bond> templateBond, bool useTemplate);
  733. /**
  734. * Check and assign user-specified link quality parameters to this bond.
  735. *
  736. * @param weights Set of user-specified parameters
  737. * @param len Length of parameter vector
  738. */
  739. void setUserLinkQualitySpec(float weights[], int len);
  740. /**
  741. * @return Whether the user has defined links for use on this bond
  742. */
  743. inline bool userHasSpecifiedLinks()
  744. {
  745. return _userHasSpecifiedLinks;
  746. }
  747. /**
  748. * @return Whether the user has defined a set of failover link(s) for this bond
  749. */
  750. inline bool userHasSpecifiedFailoverInstructions()
  751. {
  752. return _userHasSpecifiedFailoverInstructions;
  753. };
  754. /**
  755. * @return Whether the user has specified a primary link
  756. */
  757. inline bool userHasSpecifiedPrimaryLink()
  758. {
  759. return _userHasSpecifiedPrimaryLink;
  760. }
  761. /**
  762. * @return Whether the user has specified link capacities
  763. */
  764. inline bool userHasSpecifiedLinkCapacities()
  765. {
  766. return _userHasSpecifiedLinkCapacities;
  767. }
  768. /**
  769. * Periodically perform maintenance tasks for each active bond.
  770. *
  771. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  772. * @param now Current time
  773. */
  774. void processBackgroundBondTasks(void* tPtr, int64_t now);
  775. /**
  776. * Rate limit gate for VERB_ACK
  777. *
  778. * @param now Current time
  779. * @return Whether the incoming packet should be rate-gated
  780. */
  781. inline bool rateGateACK(const int64_t now)
  782. {
  783. _ackCutoffCount++;
  784. int numToDrain = _lastAckRateCheck ? (now - _lastAckRateCheck) / ZT_ACK_DRAINAGE_DIVISOR : _ackCutoffCount;
  785. _lastAckRateCheck = now;
  786. if (_ackCutoffCount > numToDrain) {
  787. _ackCutoffCount -= numToDrain;
  788. }
  789. else {
  790. _ackCutoffCount = 0;
  791. }
  792. return (_ackCutoffCount < ZT_ACK_CUTOFF_LIMIT);
  793. }
  794. /**
  795. * Rate limit gate for VERB_QOS_MEASUREMENT
  796. *
  797. * @param now Current time
  798. * @return Whether the incoming packet should be rate-gated
  799. */
  800. inline bool rateGateQoS(int64_t now, SharedPtr<Path>& path)
  801. {
  802. char pathStr[64] = { 0 };
  803. path->address().toString(pathStr);
  804. uint64_t diff = now - _lastQoSRateCheck;
  805. if ((diff) <= (_qosSendInterval / ZT_MAX_PEER_NETWORK_PATHS)) {
  806. ++_qosCutoffCount;
  807. }
  808. else {
  809. _qosCutoffCount = 0;
  810. }
  811. _lastQoSRateCheck = now;
  812. return (_qosCutoffCount < (ZT_MAX_PEER_NETWORK_PATHS * 2));
  813. }
  814. /**
  815. * Rate limit gate for VERB_PATH_NEGOTIATION_REQUEST
  816. *
  817. * @param now Current time
  818. * @return Whether the incoming packet should be rate-gated
  819. */
  820. inline bool rateGatePathNegotiation(int64_t now, SharedPtr<Path>& path)
  821. {
  822. char pathStr[64] = { 0 };
  823. path->address().toString(pathStr);
  824. int diff = now - _lastPathNegotiationReceived;
  825. if ((diff) <= (ZT_PATH_NEGOTIATION_CUTOFF_TIME / ZT_MAX_PEER_NETWORK_PATHS)) {
  826. ++_pathNegotiationCutoffCount;
  827. }
  828. else {
  829. _pathNegotiationCutoffCount = 0;
  830. }
  831. _lastPathNegotiationReceived = now;
  832. return (_pathNegotiationCutoffCount < (ZT_MAX_PEER_NETWORK_PATHS * 2));
  833. }
  834. /**
  835. * @param interval Maximum amount of time user expects a failover to take on this bond.
  836. */
  837. inline void setFailoverInterval(uint32_t interval)
  838. {
  839. _failoverInterval = interval;
  840. }
  841. /**
  842. * @param interval Maximum amount of time user expects a failover to take on this bond.
  843. */
  844. inline uint32_t getFailoverInterval()
  845. {
  846. return _failoverInterval;
  847. }
  848. /**
  849. * @param strategy Strategy that the bond uses to prob for path aliveness and quality
  850. */
  851. inline void setLinkMonitorStrategy(uint8_t strategy)
  852. {
  853. _linkMonitorStrategy = strategy;
  854. }
  855. /**
  856. * @return the current up delay parameter
  857. */
  858. inline uint16_t getUpDelay()
  859. {
  860. return _upDelay;
  861. }
  862. /**
  863. * @param upDelay Length of time before a newly-discovered path is admitted to the bond
  864. */
  865. inline void setUpDelay(int upDelay)
  866. {
  867. if (upDelay >= 0) {
  868. _upDelay = upDelay;
  869. }
  870. }
  871. /**
  872. * @return Length of time before a newly-failed path is removed from the bond
  873. */
  874. inline uint16_t getDownDelay()
  875. {
  876. return _downDelay;
  877. }
  878. /**
  879. * @param downDelay Length of time before a newly-failed path is removed from the bond
  880. */
  881. inline void setDownDelay(int downDelay)
  882. {
  883. if (downDelay >= 0) {
  884. _downDelay = downDelay;
  885. }
  886. }
  887. /**
  888. * @return The current monitoring interval for the bond
  889. */
  890. inline int monitorInterval()
  891. {
  892. return _monitorInterval;
  893. }
  894. /**
  895. * Set the current monitoring interval for the bond (can be overridden with intervals specific to certain links.)
  896. *
  897. * @param monitorInterval How often gratuitous VERB_HELLO(s) are sent to remote peer.
  898. */
  899. inline void setBondMonitorInterval(uint16_t interval)
  900. {
  901. _monitorInterval = interval;
  902. }
  903. /**
  904. * @param policy Bonding policy for this bond
  905. */
  906. inline void setPolicy(uint8_t policy)
  907. {
  908. _policy = policy;
  909. }
  910. /**
  911. * @return the current bonding policy
  912. */
  913. inline uint8_t policy()
  914. {
  915. return _policy;
  916. }
  917. /**
  918. * @return the number of links in this bond which are considered alive
  919. */
  920. inline uint8_t getNumAliveLinks()
  921. {
  922. return _numAliveLinks;
  923. };
  924. /**
  925. * @return the number of links in this bond
  926. */
  927. inline uint8_t getNumTotalLinks()
  928. {
  929. return _numTotalLinks;
  930. }
  931. /**
  932. * @return Whether flow-hashing is currently supported for this bond.
  933. */
  934. bool flowHashingSupported()
  935. {
  936. return _policy == ZT_BOND_POLICY_BALANCE_XOR || _policy == ZT_BOND_POLICY_BALANCE_AWARE;
  937. }
  938. /**
  939. *
  940. * @param packetsPerLink
  941. */
  942. inline void setPacketsPerLink(int packetsPerLink)
  943. {
  944. _packetsPerLink = packetsPerLink;
  945. }
  946. /**
  947. * @return Number of packets to be sent on each interface in a balance-rr bond
  948. */
  949. inline int getPacketsPerLink()
  950. {
  951. return _packetsPerLink;
  952. }
  953. /**
  954. *
  955. * @param linkSelectMethod
  956. */
  957. inline void setLinkSelectMethod(uint8_t method)
  958. {
  959. _abLinkSelectMethod = method;
  960. }
  961. /**
  962. *
  963. * @return
  964. */
  965. inline uint8_t getLinkSelectMethod()
  966. {
  967. return _abLinkSelectMethod;
  968. }
  969. /**
  970. *
  971. * @param allowPathNegotiation
  972. */
  973. inline void setAllowPathNegotiation(bool allowPathNegotiation)
  974. {
  975. _allowPathNegotiation = allowPathNegotiation;
  976. }
  977. /**
  978. *
  979. * @return
  980. */
  981. inline bool allowPathNegotiation()
  982. {
  983. return _allowPathNegotiation;
  984. }
  985. /**
  986. * Forcibly rotates the currently active link used in an active-backup bond to the next link in the failover queue
  987. *
  988. * @return True if this operation succeeded, false if otherwise
  989. */
  990. bool abForciblyRotateLink();
  991. /**
  992. * Emit message to tracing system but with added timestamp and subsystem info
  993. */
  994. void log(const char* fmt, ...)
  995. #ifdef __GNUC__
  996. __attribute__((format(printf, 2, 3)))
  997. #endif
  998. {
  999. // if (_peerId != 0x0 && _peerId != 0x0) { return; }
  1000. #ifdef ZT_TRACE
  1001. time_t rawtime;
  1002. struct tm* timeinfo;
  1003. char timestamp[80];
  1004. time(&rawtime);
  1005. timeinfo = localtime(&rawtime);
  1006. strftime(timestamp, 80, "%F %T", timeinfo);
  1007. #define MAX_BOND_MSG_LEN 1024
  1008. char traceMsg[MAX_BOND_MSG_LEN];
  1009. char userMsg[MAX_BOND_MSG_LEN];
  1010. va_list args;
  1011. va_start(args, fmt);
  1012. if (vsnprintf(userMsg, sizeof(userMsg), fmt, args) < 0) {
  1013. fprintf(stderr, "Encountered format encoding error while writing to trace log\n");
  1014. return;
  1015. }
  1016. snprintf(traceMsg, MAX_BOND_MSG_LEN, "%s (%llx/%s) %s", timestamp, _peerId, _policyAlias.c_str(), userMsg);
  1017. va_end(args);
  1018. RR->t->bondStateMessage(NULL, traceMsg);
  1019. #undef MAX_MSG_LEN
  1020. #endif
  1021. }
  1022. /**
  1023. * Emit message to tracing system but with added timestamp and subsystem info
  1024. */
  1025. void debug(const char* fmt, ...)
  1026. #ifdef __GNUC__
  1027. __attribute__((format(printf, 2, 3)))
  1028. #endif
  1029. {
  1030. // if (_peerId != 0x0 && _peerId != 0x0) { return; }
  1031. #ifdef ZT_DEBUG
  1032. time_t rawtime;
  1033. struct tm* timeinfo;
  1034. char timestamp[80];
  1035. time(&rawtime);
  1036. timeinfo = localtime(&rawtime);
  1037. strftime(timestamp, 80, "%F %T", timeinfo);
  1038. #define MAX_BOND_MSG_LEN 1024
  1039. char traceMsg[MAX_BOND_MSG_LEN];
  1040. char userMsg[MAX_BOND_MSG_LEN];
  1041. va_list args;
  1042. va_start(args, fmt);
  1043. if (vsnprintf(userMsg, sizeof(userMsg), fmt, args) < 0) {
  1044. fprintf(stderr, "Encountered format encoding error while writing to trace log\n");
  1045. return;
  1046. }
  1047. snprintf(traceMsg, MAX_BOND_MSG_LEN, "%s (%llx/%s) %s", timestamp, _peerId, _policyAlias.c_str(), userMsg);
  1048. va_end(args);
  1049. RR->t->bondStateMessage(NULL, traceMsg);
  1050. #undef MAX_MSG_LEN
  1051. #endif
  1052. }
  1053. private:
  1054. struct NominatedPath {
  1055. NominatedPath()
  1056. : lastAckSent(0)
  1057. , lastAckReceived(0)
  1058. , lastQoSReceived(0)
  1059. , unackedBytes(0)
  1060. , packetsReceivedSinceLastAck(0)
  1061. , lastQoSMeasurement(0)
  1062. , lastThroughputEstimation(0)
  1063. , lastRefractoryUpdate(0)
  1064. , lastAliveToggle(0)
  1065. , alive(false)
  1066. , eligible(true)
  1067. , lastEligibility(0)
  1068. , whenNominated(0)
  1069. , refractoryPeriod(0)
  1070. , ipvPref(0)
  1071. , mode(0)
  1072. , onlyPathOnLink(false)
  1073. , bonded(false)
  1074. , negotiated(false)
  1075. , shouldAvoid(false)
  1076. , assignedFlowCount(0)
  1077. , latency(0)
  1078. , latencyVariance(0)
  1079. , packetLossRatio(0)
  1080. , packetErrorRatio(0)
  1081. , relativeQuality(0)
  1082. , relativeLinkCapacity(0)
  1083. , failoverScore(0)
  1084. , packetsReceivedSinceLastQoS(0)
  1085. , packetsIn(0)
  1086. , packetsOut(0)
  1087. , localPort(0)
  1088. {
  1089. }
  1090. /**
  1091. * Set or update a refractory period for the path.
  1092. *
  1093. * @param punishment How much a path should be punished
  1094. * @param pathFailure Whether this call is the result of a recent path failure
  1095. */
  1096. inline void adjustRefractoryPeriod(int64_t now, uint32_t punishment, bool pathFailure)
  1097. {
  1098. if (pathFailure) {
  1099. unsigned int suggestedRefractoryPeriod = refractoryPeriod ? punishment + (refractoryPeriod * 2) : punishment;
  1100. refractoryPeriod = std::min(suggestedRefractoryPeriod, (unsigned int)ZT_BOND_MAX_REFRACTORY_PERIOD);
  1101. lastRefractoryUpdate = 0;
  1102. }
  1103. else {
  1104. uint32_t drainRefractory = 0;
  1105. if (lastRefractoryUpdate) {
  1106. drainRefractory = (now - lastRefractoryUpdate);
  1107. }
  1108. else {
  1109. drainRefractory = (now - lastAliveToggle);
  1110. }
  1111. lastRefractoryUpdate = now;
  1112. if (refractoryPeriod > drainRefractory) {
  1113. refractoryPeriod -= drainRefractory;
  1114. }
  1115. else {
  1116. refractoryPeriod = 0;
  1117. lastRefractoryUpdate = 0;
  1118. }
  1119. }
  1120. }
  1121. /**
  1122. * @return True if a path is permitted to be used in a bond (according to user pref.)
  1123. */
  1124. inline bool allowed()
  1125. {
  1126. return (! ipvPref || ((p->_addr.isV4() && (ipvPref == 4 || ipvPref == 46 || ipvPref == 64)) || ((p->_addr.isV6() && (ipvPref == 6 || ipvPref == 46 || ipvPref == 64)))));
  1127. }
  1128. /**
  1129. * @return True if a path exists on a link marked as a spare
  1130. */
  1131. inline bool isSpare()
  1132. {
  1133. return mode == ZT_BOND_SLAVE_MODE_SPARE;
  1134. }
  1135. /**
  1136. * @return True if a path is preferred over another on the same physical link (according to user pref.)
  1137. */
  1138. inline bool preferred()
  1139. {
  1140. return onlyPathOnLink || (p->_addr.isV4() && (ipvPref == 4 || ipvPref == 46)) || (p->_addr.isV6() && (ipvPref == 6 || ipvPref == 64));
  1141. }
  1142. /**
  1143. * @param now Current time
  1144. * @return Whether a QoS (VERB_QOS_MEASUREMENT) packet needs to be emitted at this time
  1145. */
  1146. inline bool needsToSendQoS(int64_t now, uint64_t qosSendInterval)
  1147. {
  1148. return ((packetsReceivedSinceLastQoS >= ZT_QOS_TABLE_SIZE) || ((now - lastQoSMeasurement) > qosSendInterval)) && packetsReceivedSinceLastQoS;
  1149. }
  1150. /**
  1151. * @param now Current time
  1152. * @return Whether an ACK (VERB_ACK) packet needs to be emitted at this time
  1153. */
  1154. inline bool needsToSendAck(int64_t now, uint64_t ackSendInterval)
  1155. {
  1156. return ((now - lastAckSent) >= ackSendInterval || (packetsReceivedSinceLastAck == ZT_QOS_TABLE_SIZE)) && packetsReceivedSinceLastAck;
  1157. }
  1158. /**
  1159. * Reset packet counters
  1160. */
  1161. inline void resetPacketCounts()
  1162. {
  1163. packetsIn = 0;
  1164. packetsOut = 0;
  1165. }
  1166. std::map<uint64_t, uint64_t> qosStatsOut; // id:egress_time
  1167. std::map<uint64_t, uint64_t> qosStatsIn; // id:now
  1168. std::map<uint64_t, uint64_t> ackStatsIn; // id:now
  1169. RingBuffer<int, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> qosRecordSize;
  1170. RingBuffer<float, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> qosRecordLossSamples;
  1171. RingBuffer<uint64_t, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> throughputSamples;
  1172. RingBuffer<bool, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> packetValiditySamples;
  1173. RingBuffer<float, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> throughputVarianceSamples;
  1174. RingBuffer<uint16_t, ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE> latencySamples;
  1175. uint64_t lastAckSent;
  1176. uint64_t lastAckReceived;
  1177. uint64_t lastQoSReceived;
  1178. uint64_t unackedBytes;
  1179. uint64_t packetsReceivedSinceLastAck;
  1180. uint64_t lastQoSMeasurement; // Last time that a VERB_QOS_MEASUREMENT was sent out on this path.
  1181. uint64_t lastThroughputEstimation; // Last time that the path's throughput was estimated.
  1182. uint64_t lastRefractoryUpdate; // The last time that the refractory period was updated.
  1183. uint64_t lastAliveToggle; // The last time that the path was marked as "alive".
  1184. bool alive;
  1185. bool eligible; // State of eligibility at last check. Used for determining state changes.
  1186. uint64_t lastEligibility; // The last time that this path was eligible
  1187. uint64_t whenNominated; // Timestamp indicating when this path's trial period began.
  1188. uint32_t refractoryPeriod; // Amount of time that this path will be prevented from becoming a member of a bond.
  1189. uint8_t ipvPref; // IP version preference inherited from the physical link.
  1190. uint8_t mode; // Mode inherited from the physical link.
  1191. bool onlyPathOnLink; // IP version preference inherited from the physical link.
  1192. bool enabled; // Enabled state inherited from the physical link.
  1193. bool bonded; // Whether this path is currently part of a bond.
  1194. bool negotiated; // Whether this path was intentionally negotiated by either peer.
  1195. bool shouldAvoid; // Whether flows should be moved from this path. Current traffic flows will be re-allocated immediately.
  1196. uint16_t assignedFlowCount; // The number of flows currently assigned to this path.
  1197. float latency; // The mean latency (computed from a sliding window.)
  1198. float latencyVariance; // Packet delay variance (computed from a sliding window.)
  1199. float packetLossRatio; // The ratio of lost packets to received packets.
  1200. float packetErrorRatio; // The ratio of packets that failed their MAC/CRC checks to those that did not.
  1201. float relativeQuality; // The relative quality of the link.
  1202. float relativeLinkCapacity; // The relative capacity of the link.
  1203. uint32_t failoverScore; // Score that indicates to what degree this path is preferred over others that are available to the bonding policy. (specifically for active-backup)
  1204. int32_t packetsReceivedSinceLastQoS; // Number of packets received since the last VERB_QOS_MEASUREMENT was sent to the remote peer.
  1205. /**
  1206. * Counters used for tracking path load.
  1207. */
  1208. int packetsIn;
  1209. int packetsOut;
  1210. uint16_t localPort;
  1211. // AtomicCounter __refCount;
  1212. SharedPtr<Path> p;
  1213. void set(uint64_t now, const SharedPtr<Path>& path)
  1214. {
  1215. p = path;
  1216. whenNominated = now;
  1217. }
  1218. };
  1219. /**
  1220. * Paths nominated to the bond (may or may not actually be bonded)
  1221. */
  1222. NominatedPath _paths[ZT_MAX_PEER_NETWORK_PATHS];
  1223. inline int getNominatedPathIdx(const SharedPtr<Path>& path)
  1224. {
  1225. for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
  1226. if (_paths[i].p == path) {
  1227. return i;
  1228. }
  1229. }
  1230. return ZT_MAX_PEER_NETWORK_PATHS;
  1231. }
  1232. /**
  1233. * A protocol flow that is identified by the origin and destination port.
  1234. */
  1235. struct Flow {
  1236. /**
  1237. * @param flowId Given flow ID
  1238. * @param now Current time
  1239. */
  1240. Flow(int32_t flowId, int64_t now) : id(flowId), bytesIn(0), bytesOut(0), lastActivity(now), lastPathReassignment(0), assignedPath(ZT_MAX_PEER_NETWORK_PATHS)
  1241. {
  1242. }
  1243. /**
  1244. * Reset flow statistics
  1245. */
  1246. inline void resetByteCounts()
  1247. {
  1248. bytesIn = 0;
  1249. bytesOut = 0;
  1250. }
  1251. /**
  1252. * How long since a packet was sent or received in this flow
  1253. *
  1254. * @param now Current time
  1255. * @return The age of the flow in terms of last recorded activity
  1256. */
  1257. int64_t age(int64_t now)
  1258. {
  1259. return now - lastActivity;
  1260. }
  1261. /**
  1262. * @param path Assigned path over which this flow should be handled
  1263. */
  1264. inline void assignPath(int pathIdx, int64_t now)
  1265. {
  1266. assignedPath = pathIdx;
  1267. lastPathReassignment = now;
  1268. }
  1269. AtomicCounter __refCount;
  1270. int32_t id; // Flow ID used for hashing and path selection
  1271. uint64_t bytesIn; // Used for tracking flow size
  1272. uint64_t bytesOut; // Used for tracking flow size
  1273. int64_t lastActivity; // The last time that this flow handled traffic
  1274. int64_t lastPathReassignment; // Time of last path assignment. Used for anti-flapping
  1275. int assignedPath; // Index of path to which this flow is assigned
  1276. };
  1277. const RuntimeEnvironment* RR;
  1278. AtomicCounter __refCount;
  1279. std::string _policyAlias; // Custom name given by the user to this bond type.
  1280. static Binder* _binder;
  1281. /**
  1282. * Set of indices corresponding to paths currently included in the bond proper. This
  1283. * may only be updated during a call to curateBond(). The reason for this is so that
  1284. * we can simplify the high frequency packet egress logic.
  1285. */
  1286. int _realIdxMap[ZT_MAX_PEER_NETWORK_PATHS] = { ZT_MAX_PEER_NETWORK_PATHS };
  1287. int _numBondedPaths; // Number of paths currently included in the _realIdxMap set.
  1288. std::map<int16_t, SharedPtr<Flow> > _flows; // Flows hashed according to port and protocol
  1289. float _qw[ZT_QOS_PARAMETER_SIZE]; // Link quality specification (can be customized by user)
  1290. bool _run;
  1291. uint8_t _policy;
  1292. uint32_t _upDelay;
  1293. uint32_t _downDelay;
  1294. // active-backup
  1295. int _abPathIdx; // current active path
  1296. std::deque<int> _abFailoverQueue;
  1297. uint8_t _abLinkSelectMethod; // link re-selection policy for the primary link in active-backup
  1298. // balance-rr
  1299. uint8_t _rrIdx; // index to path currently in use during Round Robin operation
  1300. uint16_t _rrPacketsSentOnCurrLink; // number of packets sent on this link since the most recent path switch.
  1301. /**
  1302. * How many packets will be sent on a path before moving to the next path
  1303. * in the round-robin sequence. A value of zero will cause a random path
  1304. * selection for each outgoing packet.
  1305. */
  1306. int _packetsPerLink;
  1307. // balance-aware
  1308. uint64_t _totalBondUnderload;
  1309. // dynamic link monitoring
  1310. uint8_t _linkMonitorStrategy;
  1311. // path negotiation
  1312. int16_t _localUtility;
  1313. int _negotiatedPathIdx;
  1314. uint8_t _numSentPathNegotiationRequests;
  1315. bool _allowPathNegotiation;
  1316. /**
  1317. * Timers and intervals
  1318. */
  1319. uint64_t _failoverInterval;
  1320. uint64_t _qosSendInterval;
  1321. uint64_t _ackSendInterval;
  1322. uint64_t throughputMeasurementInterval;
  1323. uint64_t _qualityEstimationInterval;
  1324. /**
  1325. * Link state reporting
  1326. */
  1327. uint8_t _numAliveLinks;
  1328. uint8_t _numTotalLinks;
  1329. /**
  1330. * Default initial punishment inflicted on misbehaving paths. Punishment slowly
  1331. * drains linearly. For each eligibility change the remaining punishment is doubled.
  1332. */
  1333. uint32_t _defaultPathRefractoryPeriod;
  1334. unsigned char _freeRandomByte; // Free byte of entropy that is updated on every packet egress event.
  1335. SharedPtr<Peer> _peer; // Remote peer that this bond services
  1336. unsigned long long _peerId; // ID of the peer that this bond services
  1337. bool _isLeaf;
  1338. /**
  1339. * Rate-limiting
  1340. */
  1341. uint16_t _qosCutoffCount;
  1342. uint16_t _ackCutoffCount;
  1343. uint64_t _lastQoSRateCheck;
  1344. uint64_t _lastAckRateCheck;
  1345. uint16_t _pathNegotiationCutoffCount;
  1346. uint64_t _lastPathNegotiationReceived;
  1347. /**
  1348. * Recent event timestamps
  1349. */
  1350. uint64_t _lastSummaryDump;
  1351. uint64_t _lastQualityEstimation;
  1352. uint64_t _lastBackgroundTaskCheck;
  1353. uint64_t _lastBondStatusLog;
  1354. uint64_t _lastPathNegotiationCheck;
  1355. uint64_t _lastSentPathNegotiationRequest;
  1356. uint64_t _lastFlowExpirationCheck;
  1357. uint64_t _lastFlowRebalance;
  1358. uint64_t _lastFrame;
  1359. uint64_t _lastActiveBackupPathChange;
  1360. Mutex _paths_m;
  1361. Mutex _flows_m;
  1362. bool _userHasSpecifiedLinks; // Whether the user has specified links for this bond.
  1363. bool _userHasSpecifiedPrimaryLink; // Whether the user has specified a primary link for this bond.
  1364. bool _userHasSpecifiedFailoverInstructions; // Whether the user has specified failover instructions for this bond.
  1365. bool _userHasSpecifiedLinkCapacities; // Whether the user has specified links capacities for this bond.
  1366. /**
  1367. * How frequently (in ms) a VERB_ECHO is sent to a peer to verify that a
  1368. * path is still active. A value of zero (0) will disable active path
  1369. * monitoring; as result, all monitoring will be a function of traffic.
  1370. */
  1371. int _monitorInterval;
  1372. bool _allowFlowHashing; // Whether or not flow hashing is allowed.
  1373. uint64_t _overheadBytes;
  1374. };
  1375. } // namespace ZeroTier
  1376. #endif