DBM.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * --
  19. *
  20. * You can be released from the requirements of the license by purchasing
  21. * a commercial license. Buying such a license is mandatory as soon as you
  22. * develop commercial closed-source software that incorporates or links
  23. * directly against ZeroTier software without disclosing the source code
  24. * of your own application.
  25. */
  26. #ifndef ZT_DBM_HPP___
  27. #define ZT_DBM_HPP___
  28. #include <stdio.h>
  29. #include <stdint.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <stdexcept>
  33. #include "../node/Constants.hpp"
  34. #include "../node/Mutex.hpp"
  35. #include "../node/Utils.hpp"
  36. #include "../node/Identity.hpp"
  37. #include "../node/Peer.hpp"
  38. #include "../ext/vsdm/vsdm.hpp"
  39. // The Peer is the largest structure we persist here
  40. #define ZT_DBM_MAX_VALUE_SIZE sizeof(Peer)
  41. namespace ZeroTier {
  42. class Node;
  43. class DBM;
  44. class DBM
  45. {
  46. public:
  47. ZT_PACKED_STRUCT(struct Value
  48. {
  49. Value(const uint64_t t,const uint16_t l,const void *d) :
  50. ts(t),
  51. l(l)
  52. {
  53. memcpy(data,d,l);
  54. }
  55. uint64_t ts;
  56. uint16_t len;
  57. uint8_t data[ZT_DBM_MAX_VALUE_SIZE];
  58. });
  59. private:
  60. ZT_PACKED_STRUCT(struct _MapKey
  61. {
  62. _MapKey() : obj(0),type(0) {}
  63. _MapKey(const uint16_t t,const uint64_t o) : obj(o),type(t) {}
  64. uint64_t obj;
  65. uint16_t type;
  66. inline bool operator==(const _MapKey &k) const { return ((obj == k.obj)&&(type == k.type)); }
  67. });
  68. struct _MapHasher
  69. {
  70. inline std::size_t operator()(const _MapKey &k) const { return (std::size_t)((k.obj ^ (k.obj >> 32)) + (uint64_t)k.type); }
  71. };
  72. void onUpdate(uint64_t from,const _MapKey &k,const Value &v,uint64_t rev);
  73. void onDelete(uint64_t from,const _MapKey &k);
  74. class _vsdm_watcher
  75. {
  76. public:
  77. _vsdm_watcher(DBM *p) : _parent(p) {}
  78. inline void add(uint64_t from,const _MapKey &k,const Value &v,uint64_t rev) { _parent->onUpdate(from,k,v,rev); }
  79. inline void update(uint64_t from,const _MapKey &k,const Value &v,uint64_t rev) { _parent->onUpdate(from,k,v,rev); }
  80. inline void del(uint64_t from,const _MapKey &k) { _parent->onDelete(from,k); }
  81. private:
  82. DBM *_parent;
  83. };
  84. class _vsdm_serializer
  85. {
  86. public:
  87. static inline unsigned long objectSize(const _MapKey &k) { return 10; }
  88. static inline unsigned long objectSize(const Value &v) { return (10 + v.len); }
  89. static inline const char *objectData(const _MapKey &k) { return reinterpret_cast<const char *>(&k); }
  90. static inline const char *objectData(const Value &v) { return reinterpret_cast<const char *>(&v); }
  91. static inline bool objectDeserialize(const char *d,unsigned long l,_MapKey &k)
  92. {
  93. if (l == 10) {
  94. memcpy(&k,d,10);
  95. return true;
  96. }
  97. return false;
  98. }
  99. static inline bool objectDeserialize(const char *d,unsigned long l,Value &v)
  100. {
  101. if ((l >= 10)&&(l <= (10 + ZT_DBM_MAX_VALUE_SIZE))) {
  102. memcpy(&v,d,l);
  103. return true;
  104. }
  105. return false;
  106. }
  107. };
  108. class _vsdm_cryptor
  109. {
  110. public:
  111. _vsdm_cryptor(const Identity &secretIdentity);
  112. static inline unsigned long overhead() { return 24; }
  113. void encrypt(void *d,unsigned long l);
  114. bool decrypt(void *d,unsigned long l);
  115. uint8_t _key[32];
  116. };
  117. typedef vsdm< _MapKey,Value,16384,_vsdm_watcher,_vsdm_serializer,_vsdm_cryptor,_MapHasher > _Map;
  118. friend class _Map;
  119. public:
  120. ZT_PACKED_STRUCT(struct ClusterPeerStatus
  121. {
  122. uint64_t startTime;
  123. uint64_t currentTime;
  124. uint64_t clusterPeersConnected;
  125. uint64_t ztPeersConnected;
  126. uint16_t platform;
  127. uint16_t arch;
  128. });
  129. DBM(const Identity &secretIdentity,uint64_t clusterMemberId,const std::string &basePath,Node *node);
  130. ~DBM();
  131. void put(const ZT_StoredObjectType type,const uint64_t key,const void *data,unsigned int len);
  132. bool get(const ZT_StoredObjectType type,const uint64_t key,Value &value);
  133. void del(const ZT_StoredObjectType type,const uint64_t key);
  134. void clean();
  135. private:
  136. bool DBM::_persistentPath(const ZT_StoredObjectType type,const uint64_t key,char *p,unsigned int maxlen);
  137. const std::string _basePath;
  138. Node *const _node;
  139. uint64_t _startTime;
  140. _Map _m;
  141. };
  142. } // namespace ZeroTier
  143. #endif