Trace.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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_TRACE_HPP
  14. #define ZT_TRACE_HPP
  15. #include "Constants.hpp"
  16. #include "SharedPtr.hpp"
  17. #include "Mutex.hpp"
  18. #include "InetAddress.hpp"
  19. #include "Address.hpp"
  20. #include "MAC.hpp"
  21. #include <cstdint>
  22. #include <cstring>
  23. #include <cstdlib>
  24. #include <vector>
  25. namespace ZeroTier {
  26. class RuntimeEnvironment;
  27. class Identity;
  28. class Peer;
  29. class Path;
  30. class Network;
  31. class CertificateOfMembership;
  32. class CertificateOfOwnership;
  33. class Revocation;
  34. class Tag;
  35. class Capability;
  36. struct NetworkConfig;
  37. /**
  38. * Remote tracing and trace logging handler
  39. *
  40. * These methods are called when things happen that may be of interested to
  41. * someone debugging ZeroTier or its virtual networks. The codeLocation parameter
  42. * is an arbitrary pseudo-random identifier of the form 0xNNNNNNNN that could be
  43. * easily found by searching the code base. This makes it easy to locate the
  44. * specific line where a trace originated without relying on brittle non-portable
  45. * things like source file and line number. The same identifier should be used
  46. * for the same 'place' in the code across versions. These could eventually be
  47. * turned into constants that are semi-official and stored in a database to
  48. * provide extra debug context.
  49. */
  50. class Trace
  51. {
  52. public:
  53. struct RuleResultLog
  54. {
  55. uint8_t l[ZT_MAX_NETWORK_RULES / 2]; // ZT_MAX_NETWORK_RULES 4-bit fields
  56. ZT_ALWAYS_INLINE void log(const unsigned int rn,const uint8_t thisRuleMatches,const uint8_t thisSetMatches)
  57. {
  58. l[rn >> 1U] |= ( ((thisRuleMatches + 1U) << 2U) | (thisSetMatches + 1U) ) << ((rn & 1U) << 2U);
  59. }
  60. ZT_ALWAYS_INLINE void logSkipped(const unsigned int rn,const uint8_t thisSetMatches)
  61. {
  62. l[rn >> 1U] |= (thisSetMatches + 1U) << ((rn & 1U) << 2U);
  63. }
  64. ZT_ALWAYS_INLINE void clear()
  65. {
  66. memset(l,0,sizeof(l));
  67. }
  68. };
  69. /**
  70. * Simple container for a C string
  71. *
  72. * @tparam C Capacity of string
  73. */
  74. template<unsigned int C>
  75. struct Str
  76. {
  77. ZT_ALWAYS_INLINE Str() { memset(s,0,sizeof(s)); }
  78. constexpr static unsigned int capacity() { return C; }
  79. char s[C];
  80. };
  81. explicit Trace(const RuntimeEnvironment *renv);
  82. static Str<ZT_INETADDRESS_STRING_SIZE_MAX> str(const InetAddress &a,bool ipOnly = false);
  83. static Str<ZT_ADDRESS_STRING_SIZE_MAX> str(const Address &a);
  84. static Str<ZT_ADDRESS_STRING_SIZE_MAX + ZT_INETADDRESS_STRING_SIZE_MAX + 4> str(const Address &peerAddress,const SharedPtr<Path> &path);
  85. void unexpectedError(
  86. void *tPtr,
  87. uint32_t codeLocation,
  88. const char *message,
  89. ...);
  90. ZT_ALWAYS_INLINE void resettingPathsInScope(
  91. void *const tPtr,
  92. const uint32_t codeLocation,
  93. const Identity &reporter,
  94. const InetAddress &from,
  95. const InetAddress &oldExternal,
  96. const InetAddress &newExternal,
  97. const InetAddress::IpScope scope)
  98. {
  99. if (_vl1) _resettingPathsInScope(tPtr,codeLocation,reporter,from,oldExternal,newExternal,scope);
  100. }
  101. ZT_ALWAYS_INLINE void tryingNewPath(
  102. void *const tPtr,
  103. const uint32_t codeLocation,
  104. const Identity &trying,
  105. const InetAddress &physicalAddress,
  106. const InetAddress &triggerAddress,
  107. uint64_t triggeringPacketId,
  108. uint8_t triggeringPacketVerb,
  109. uint64_t triggeredByAddress,
  110. const uint8_t *triggeredByIdentityHash,
  111. ZT_TraceTryingNewPathReason reason)
  112. {
  113. if (_vl1) _tryingNewPath(tPtr,codeLocation,trying,physicalAddress,triggerAddress,triggeringPacketId,triggeringPacketVerb,triggeredByAddress,triggeredByIdentityHash,reason);
  114. }
  115. ZT_ALWAYS_INLINE void learnedNewPath(
  116. void *const tPtr,
  117. const uint32_t codeLocation,
  118. uint64_t packetId,
  119. const Identity &peerIdentity,
  120. const InetAddress &physicalAddress,
  121. const InetAddress &replaced)
  122. {
  123. if (_vl1) _learnedNewPath(tPtr,codeLocation,packetId,peerIdentity,physicalAddress,replaced);
  124. }
  125. ZT_ALWAYS_INLINE void incomingPacketDropped(
  126. void *const tPtr,
  127. const uint32_t codeLocation,
  128. uint64_t packetId,
  129. uint64_t networkId,
  130. const Identity &peerIdentity,
  131. const InetAddress &physicalAddress,
  132. uint8_t hops,
  133. uint8_t verb,
  134. const ZT_TracePacketDropReason reason)
  135. {
  136. if (_vl1) _incomingPacketDropped(tPtr,codeLocation,packetId,networkId,peerIdentity,physicalAddress,hops,verb,reason);
  137. }
  138. ZT_ALWAYS_INLINE void outgoingNetworkFrameDropped(
  139. void *const tPtr,
  140. const uint32_t codeLocation,
  141. uint64_t networkId,
  142. const MAC &sourceMac,
  143. const MAC &destMac,
  144. uint16_t etherType,
  145. uint16_t frameLength,
  146. const uint8_t *frameData,
  147. ZT_TraceFrameDropReason reason)
  148. {
  149. if (_vl2) _outgoingNetworkFrameDropped(tPtr,codeLocation,networkId,sourceMac,destMac,etherType,frameLength,frameData,reason);
  150. }
  151. ZT_ALWAYS_INLINE void incomingNetworkFrameDropped(
  152. void *const tPtr,
  153. const uint32_t codeLocation,
  154. uint64_t networkId,
  155. const MAC &sourceMac,
  156. const MAC &destMac,
  157. const Identity &peerIdentity,
  158. const InetAddress &physicalAddress,
  159. uint8_t hops,
  160. uint16_t frameLength,
  161. const uint8_t *frameData,
  162. uint8_t verb,
  163. bool credentialRequestSent,
  164. ZT_TraceFrameDropReason reason)
  165. {
  166. if (_vl2) _incomingNetworkFrameDropped(tPtr,codeLocation,networkId,sourceMac,destMac,peerIdentity,physicalAddress,hops,frameLength,frameData,verb,credentialRequestSent,reason);
  167. }
  168. ZT_ALWAYS_INLINE void networkConfigRequestSent(
  169. void *const tPtr,
  170. const uint32_t codeLocation,
  171. uint64_t networkId)
  172. {
  173. if (_vl2) _networkConfigRequestSent(tPtr,codeLocation,networkId);
  174. }
  175. ZT_ALWAYS_INLINE void networkFilter(
  176. void *const tPtr,
  177. const uint32_t codeLocation,
  178. uint64_t networkId,
  179. const uint8_t primaryRuleSetLog[512],
  180. const uint8_t matchingCapabilityRuleSetLog[512],
  181. uint32_t matchingCapabilityId,
  182. int64_t matchingCapabilityTimestamp,
  183. const Address &source,
  184. const Address &dest,
  185. const MAC &sourceMac,
  186. const MAC &destMac,
  187. uint16_t frameLength,
  188. const uint8_t *frameData,
  189. uint16_t etherType,
  190. uint16_t vlanId,
  191. bool noTee,
  192. bool inbound,
  193. int accept)
  194. {
  195. if (_vl2Filter) {
  196. _networkFilter(
  197. tPtr,
  198. codeLocation,
  199. networkId,
  200. primaryRuleSetLog,
  201. matchingCapabilityRuleSetLog,
  202. matchingCapabilityId,
  203. matchingCapabilityTimestamp,
  204. source,
  205. dest,
  206. sourceMac,
  207. destMac,
  208. frameLength,
  209. frameData,
  210. etherType,
  211. vlanId,
  212. noTee,
  213. inbound,
  214. accept);
  215. }
  216. }
  217. ZT_ALWAYS_INLINE void credentialRejected(
  218. void *const tPtr,
  219. const uint32_t codeLocation,
  220. uint64_t networkId,
  221. const Address &address,
  222. uint32_t credentialId,
  223. int64_t credentialTimestamp,
  224. uint8_t credentialType,
  225. ZT_TraceCredentialRejectionReason reason)
  226. {
  227. if (_vl2) _credentialRejected(tPtr,codeLocation,networkId,address,credentialId,credentialTimestamp,credentialType,reason);
  228. }
  229. private:
  230. void _resettingPathsInScope(
  231. void *tPtr,
  232. uint32_t codeLocation,
  233. const Identity &reporter,
  234. const InetAddress &from,
  235. const InetAddress &oldExternal,
  236. const InetAddress &newExternal,
  237. InetAddress::IpScope scope);
  238. void _tryingNewPath(
  239. void *tPtr,
  240. uint32_t codeLocation,
  241. const Identity &trying,
  242. const InetAddress &physicalAddress,
  243. const InetAddress &triggerAddress,
  244. uint64_t triggeringPacketId,
  245. uint8_t triggeringPacketVerb,
  246. uint64_t triggeredByAddress,
  247. const uint8_t *triggeredByIdentityHash,
  248. ZT_TraceTryingNewPathReason reason);
  249. void _learnedNewPath(
  250. void *tPtr,
  251. uint32_t codeLocation,
  252. uint64_t packetId,
  253. const Identity &peerIdentity,
  254. const InetAddress &physicalAddress,
  255. const InetAddress &replaced);
  256. void _incomingPacketDropped(
  257. void *tPtr,
  258. uint32_t codeLocation,
  259. uint64_t packetId,
  260. uint64_t networkId,
  261. const Identity &peerIdentity,
  262. const InetAddress &physicalAddress,
  263. uint8_t hops,
  264. uint8_t verb,
  265. ZT_TracePacketDropReason reason);
  266. void _outgoingNetworkFrameDropped(
  267. void *tPtr,
  268. uint32_t codeLocation,
  269. uint64_t networkId,
  270. const MAC &sourceMac,
  271. const MAC &destMac,
  272. uint16_t etherType,
  273. uint16_t frameLength,
  274. const uint8_t *frameData,
  275. ZT_TraceFrameDropReason reason);
  276. void _incomingNetworkFrameDropped(
  277. void *tPtr,
  278. uint32_t codeLocation,
  279. uint64_t networkId,
  280. const MAC &sourceMac,
  281. const MAC &destMac,
  282. const Identity &peerIdentity,
  283. const InetAddress &physicalAddress,
  284. uint8_t hops,
  285. uint16_t frameLength,
  286. const uint8_t *frameData,
  287. uint8_t verb,
  288. bool credentialRequestSent,
  289. ZT_TraceFrameDropReason reason);
  290. void _networkConfigRequestSent(
  291. void *tPtr,
  292. uint32_t codeLocation,
  293. uint64_t networkId);
  294. void _networkFilter(
  295. void *tPtr,
  296. uint32_t codeLocation,
  297. uint64_t networkId,
  298. const uint8_t primaryRuleSetLog[512],
  299. const uint8_t matchingCapabilityRuleSetLog[512],
  300. uint32_t matchingCapabilityId,
  301. int64_t matchingCapabilityTimestamp,
  302. const Address &source,
  303. const Address &dest,
  304. const MAC &sourceMac,
  305. const MAC &destMac,
  306. uint16_t frameLength,
  307. const uint8_t *frameData,
  308. uint16_t etherType,
  309. uint16_t vlanId,
  310. bool noTee,
  311. bool inbound,
  312. int accept);
  313. void _credentialRejected(
  314. void *tPtr,
  315. uint32_t codeLocation,
  316. uint64_t networkId,
  317. const Address &address,
  318. uint32_t credentialId,
  319. int64_t credentialTimestamp,
  320. uint8_t credentialType,
  321. ZT_TraceCredentialRejectionReason reason);
  322. const RuntimeEnvironment *const RR;
  323. volatile bool _vl1,_vl2,_vl2Filter,_vl2Multicast;
  324. struct _MonitoringPeer
  325. {
  326. int64_t _timeSet;
  327. unsigned int _traceTypes;
  328. SharedPtr<Peer> peer;
  329. Mutex lock;
  330. };
  331. std::vector<_MonitoringPeer> _monitoringPeers;
  332. RWMutex _monitoringPeers_l;
  333. };
  334. } // namespace ZeroTier
  335. #endif