NetworkConfig.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2019 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. #include <stdint.h>
  27. #include <algorithm>
  28. #include "NetworkConfig.hpp"
  29. namespace ZeroTier {
  30. bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,bool includeLegacy) const
  31. {
  32. Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
  33. char tmp2[128];
  34. try {
  35. d.clear();
  36. // Try to put the more human-readable fields first
  37. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) return false;
  38. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) return false;
  39. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) return false;
  40. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) return false;
  41. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) return false;
  42. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) return false;
  43. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) return false;
  44. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) return false;
  45. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) return false;
  46. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false;
  47. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false;
  48. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
  49. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
  50. // Then add binary blobs
  51. if (this->com) {
  52. tmp->clear();
  53. this->com.serialize(*tmp);
  54. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false;
  55. }
  56. tmp->clear();
  57. for(unsigned int i=0;i<this->capabilityCount;++i)
  58. this->capabilities[i].serialize(*tmp);
  59. if (tmp->size()) {
  60. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false;
  61. }
  62. tmp->clear();
  63. for(unsigned int i=0;i<this->tagCount;++i)
  64. this->tags[i].serialize(*tmp);
  65. if (tmp->size()) {
  66. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false;
  67. }
  68. tmp->clear();
  69. for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i)
  70. this->certificatesOfOwnership[i].serialize(*tmp);
  71. if (tmp->size()) {
  72. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false;
  73. }
  74. tmp->clear();
  75. for(unsigned int i=0;i<this->specialistCount;++i)
  76. tmp->append((uint64_t)this->specialists[i]);
  77. if (tmp->size()) {
  78. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false;
  79. }
  80. tmp->clear();
  81. for(unsigned int i=0;i<this->routeCount;++i) {
  82. reinterpret_cast<const InetAddress *>(&(this->routes[i].target))->serialize(*tmp);
  83. reinterpret_cast<const InetAddress *>(&(this->routes[i].via))->serialize(*tmp);
  84. tmp->append((uint16_t)this->routes[i].flags);
  85. tmp->append((uint16_t)this->routes[i].metric);
  86. }
  87. if (tmp->size()) {
  88. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false;
  89. }
  90. tmp->clear();
  91. for(unsigned int i=0;i<this->staticIpCount;++i)
  92. this->staticIps[i].serialize(*tmp);
  93. if (tmp->size()) {
  94. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false;
  95. }
  96. if (this->ruleCount) {
  97. tmp->clear();
  98. Capability::serializeRules(*tmp,rules,ruleCount);
  99. if (tmp->size()) {
  100. if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false;
  101. }
  102. }
  103. delete tmp;
  104. } catch ( ... ) {
  105. delete tmp;
  106. throw;
  107. }
  108. return true;
  109. }
  110. bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d)
  111. {
  112. static const NetworkConfig NIL_NC;
  113. Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *const tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
  114. try {
  115. *this = NIL_NC;
  116. // Fields that are always present, new or old
  117. this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,0);
  118. if (!this->networkId) {
  119. delete tmp;
  120. return false;
  121. }
  122. this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,0);
  123. this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0);
  124. this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0);
  125. this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0);
  126. if (!this->issuedTo) {
  127. delete tmp;
  128. return false;
  129. }
  130. this->remoteTraceTarget = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET);
  131. this->remoteTraceLevel = (Trace::Level)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL);
  132. this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,0);
  133. d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name,sizeof(this->name));
  134. this->mtu = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MTU,ZT_DEFAULT_MTU);
  135. if (this->mtu < 1280)
  136. this->mtu = 1280; // minimum MTU allowed by IPv6 standard and others
  137. else if (this->mtu > ZT_MAX_MTU)
  138. this->mtu = ZT_MAX_MTU;
  139. if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) {
  140. delete tmp;
  141. return false;
  142. } else {
  143. // Otherwise we can use the new fields
  144. this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,0);
  145. this->type = (ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)ZT_NETWORK_TYPE_PRIVATE);
  146. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp))
  147. this->com.deserialize(*tmp,0);
  148. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) {
  149. try {
  150. unsigned int p = 0;
  151. while (p < tmp->size()) {
  152. Capability cap;
  153. p += cap.deserialize(*tmp,p);
  154. this->capabilities[this->capabilityCount++] = cap;
  155. }
  156. } catch ( ... ) {}
  157. std::sort(&(this->capabilities[0]),&(this->capabilities[this->capabilityCount]));
  158. }
  159. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) {
  160. try {
  161. unsigned int p = 0;
  162. while (p < tmp->size()) {
  163. Tag tag;
  164. p += tag.deserialize(*tmp,p);
  165. this->tags[this->tagCount++] = tag;
  166. }
  167. } catch ( ... ) {}
  168. std::sort(&(this->tags[0]),&(this->tags[this->tagCount]));
  169. }
  170. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) {
  171. unsigned int p = 0;
  172. while (p < tmp->size()) {
  173. if (certificateOfOwnershipCount < ZT_MAX_CERTIFICATES_OF_OWNERSHIP)
  174. p += certificatesOfOwnership[certificateOfOwnershipCount++].deserialize(*tmp,p);
  175. else {
  176. CertificateOfOwnership foo;
  177. p += foo.deserialize(*tmp,p);
  178. }
  179. }
  180. }
  181. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) {
  182. unsigned int p = 0;
  183. while ((p + 8) <= tmp->size()) {
  184. if (specialistCount < ZT_MAX_NETWORK_SPECIALISTS)
  185. this->specialists[this->specialistCount++] = tmp->at<uint64_t>(p);
  186. p += 8;
  187. }
  188. }
  189. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) {
  190. unsigned int p = 0;
  191. while ((p < tmp->size())&&(routeCount < ZT_MAX_NETWORK_ROUTES)) {
  192. p += reinterpret_cast<InetAddress *>(&(this->routes[this->routeCount].target))->deserialize(*tmp,p);
  193. p += reinterpret_cast<InetAddress *>(&(this->routes[this->routeCount].via))->deserialize(*tmp,p);
  194. this->routes[this->routeCount].flags = tmp->at<uint16_t>(p); p += 2;
  195. this->routes[this->routeCount].metric = tmp->at<uint16_t>(p); p += 2;
  196. ++this->routeCount;
  197. }
  198. }
  199. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) {
  200. unsigned int p = 0;
  201. while ((p < tmp->size())&&(staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
  202. p += this->staticIps[this->staticIpCount++].deserialize(*tmp,p);
  203. }
  204. }
  205. if (d.get(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) {
  206. this->ruleCount = 0;
  207. unsigned int p = 0;
  208. Capability::deserializeRules(*tmp,p,this->rules,this->ruleCount,ZT_MAX_NETWORK_RULES);
  209. }
  210. }
  211. delete tmp;
  212. return true;
  213. } catch ( ... ) {
  214. delete tmp;
  215. return false;
  216. }
  217. }
  218. } // namespace ZeroTier