DB.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2018 ZeroTier, Inc.
  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. #include "DB.hpp"
  19. #include "EmbeddedNetworkController.hpp"
  20. #include <chrono>
  21. #include <algorithm>
  22. #include <stdexcept>
  23. using json = nlohmann::json;
  24. namespace ZeroTier {
  25. void DB::initNetwork(nlohmann::json &network)
  26. {
  27. if (!network.count("private")) network["private"] = true;
  28. if (!network.count("creationTime")) network["creationTime"] = OSUtils::now();
  29. if (!network.count("name")) network["name"] = "";
  30. if (!network.count("multicastLimit")) network["multicastLimit"] = (uint64_t)32;
  31. if (!network.count("enableBroadcast")) network["enableBroadcast"] = true;
  32. if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}};
  33. if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}};
  34. if (!network.count("authTokens")) network["authTokens"] = {{}};
  35. if (!network.count("capabilities")) network["capabilities"] = nlohmann::json::array();
  36. if (!network.count("tags")) network["tags"] = nlohmann::json::array();
  37. if (!network.count("routes")) network["routes"] = nlohmann::json::array();
  38. if (!network.count("ipAssignmentPools")) network["ipAssignmentPools"] = nlohmann::json::array();
  39. if (!network.count("mtu")) network["mtu"] = ZT_DEFAULT_MTU;
  40. if (!network.count("remoteTraceTarget")) network["remoteTraceTarget"] = nlohmann::json();
  41. if (!network.count("removeTraceLevel")) network["remoteTraceLevel"] = 0;
  42. if (!network.count("rules")) {
  43. // If unspecified, rules are set to allow anything and behave like a flat L2 segment
  44. network["rules"] = {{
  45. { "not",false },
  46. { "or", false },
  47. { "type","ACTION_ACCEPT" }
  48. }};
  49. }
  50. network["objtype"] = "network";
  51. }
  52. void DB::initMember(nlohmann::json &member)
  53. {
  54. if (!member.count("authorized")) member["authorized"] = false;
  55. if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array();
  56. if (!member.count("activeBridge")) member["activeBridge"] = false;
  57. if (!member.count("tags")) member["tags"] = nlohmann::json::array();
  58. if (!member.count("capabilities")) member["capabilities"] = nlohmann::json::array();
  59. if (!member.count("creationTime")) member["creationTime"] = OSUtils::now();
  60. if (!member.count("noAutoAssignIps")) member["noAutoAssignIps"] = false;
  61. if (!member.count("revision")) member["revision"] = 0ULL;
  62. if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL;
  63. if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL;
  64. if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json();
  65. if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json();
  66. if (!member.count("vMajor")) member["vMajor"] = -1;
  67. if (!member.count("vMinor")) member["vMinor"] = -1;
  68. if (!member.count("vRev")) member["vRev"] = -1;
  69. if (!member.count("vProto")) member["vProto"] = -1;
  70. if (!member.count("remoteTraceTarget")) member["remoteTraceTarget"] = nlohmann::json();
  71. if (!member.count("removeTraceLevel")) member["remoteTraceLevel"] = 0;
  72. member["objtype"] = "member";
  73. }
  74. void DB::cleanNetwork(nlohmann::json &network)
  75. {
  76. network.erase("clock");
  77. network.erase("authorizedMemberCount");
  78. network.erase("activeMemberCount");
  79. network.erase("totalMemberCount");
  80. network.erase("lastModified");
  81. }
  82. void DB::cleanMember(nlohmann::json &member)
  83. {
  84. member.erase("clock");
  85. member.erase("physicalAddr");
  86. member.erase("recentLog");
  87. member.erase("lastModified");
  88. member.erase("lastRequestMetaData");
  89. }
  90. DB::DB(EmbeddedNetworkController *const nc,const Identity &myId,const char *path) :
  91. _controller(nc),
  92. _myId(myId),
  93. _myAddress(myId.address()),
  94. _path((path) ? path : "")
  95. {
  96. char tmp[32];
  97. _myAddress.toString(tmp);
  98. _myAddressStr = tmp;
  99. }
  100. DB::~DB()
  101. {
  102. }
  103. bool DB::get(const uint64_t networkId,nlohmann::json &network)
  104. {
  105. waitForReady();
  106. std::shared_ptr<_Network> nw;
  107. {
  108. std::lock_guard<std::mutex> l(_networks_l);
  109. auto nwi = _networks.find(networkId);
  110. if (nwi == _networks.end())
  111. return false;
  112. nw = nwi->second;
  113. }
  114. {
  115. std::lock_guard<std::mutex> l2(nw->lock);
  116. network = nw->config;
  117. }
  118. return true;
  119. }
  120. bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member)
  121. {
  122. waitForReady();
  123. std::shared_ptr<_Network> nw;
  124. {
  125. std::lock_guard<std::mutex> l(_networks_l);
  126. auto nwi = _networks.find(networkId);
  127. if (nwi == _networks.end())
  128. return false;
  129. nw = nwi->second;
  130. }
  131. {
  132. std::lock_guard<std::mutex> l2(nw->lock);
  133. network = nw->config;
  134. auto m = nw->members.find(memberId);
  135. if (m == nw->members.end())
  136. return false;
  137. member = m->second;
  138. }
  139. return true;
  140. }
  141. bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info)
  142. {
  143. waitForReady();
  144. std::shared_ptr<_Network> nw;
  145. {
  146. std::lock_guard<std::mutex> l(_networks_l);
  147. auto nwi = _networks.find(networkId);
  148. if (nwi == _networks.end())
  149. return false;
  150. nw = nwi->second;
  151. }
  152. {
  153. std::lock_guard<std::mutex> l2(nw->lock);
  154. network = nw->config;
  155. _fillSummaryInfo(nw,info);
  156. auto m = nw->members.find(memberId);
  157. if (m == nw->members.end())
  158. return false;
  159. member = m->second;
  160. }
  161. return true;
  162. }
  163. bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohmann::json> &members)
  164. {
  165. waitForReady();
  166. std::shared_ptr<_Network> nw;
  167. {
  168. std::lock_guard<std::mutex> l(_networks_l);
  169. auto nwi = _networks.find(networkId);
  170. if (nwi == _networks.end())
  171. return false;
  172. nw = nwi->second;
  173. }
  174. {
  175. std::lock_guard<std::mutex> l2(nw->lock);
  176. network = nw->config;
  177. for(auto m=nw->members.begin();m!=nw->members.end();++m)
  178. members.push_back(m->second);
  179. }
  180. return true;
  181. }
  182. bool DB::summary(const uint64_t networkId,NetworkSummaryInfo &info)
  183. {
  184. waitForReady();
  185. std::shared_ptr<_Network> nw;
  186. {
  187. std::lock_guard<std::mutex> l(_networks_l);
  188. auto nwi = _networks.find(networkId);
  189. if (nwi == _networks.end())
  190. return false;
  191. nw = nwi->second;
  192. }
  193. {
  194. std::lock_guard<std::mutex> l2(nw->lock);
  195. _fillSummaryInfo(nw,info);
  196. }
  197. return true;
  198. }
  199. void DB::networks(std::vector<uint64_t> &networks)
  200. {
  201. waitForReady();
  202. std::lock_guard<std::mutex> l(_networks_l);
  203. networks.reserve(_networks.size() + 1);
  204. for(auto n=_networks.begin();n!=_networks.end();++n)
  205. networks.push_back(n->first);
  206. }
  207. void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool push)
  208. {
  209. uint64_t memberId = 0;
  210. uint64_t networkId = 0;
  211. bool isAuth = false;
  212. bool wasAuth = false;
  213. std::shared_ptr<_Network> nw;
  214. if (old.is_object()) {
  215. memberId = OSUtils::jsonIntHex(old["id"],0ULL);
  216. networkId = OSUtils::jsonIntHex(old["nwid"],0ULL);
  217. if ((memberId)&&(networkId)) {
  218. {
  219. std::lock_guard<std::mutex> l(_networks_l);
  220. auto nw2 = _networks.find(networkId);
  221. if (nw2 != _networks.end())
  222. nw = nw2->second;
  223. }
  224. if (nw) {
  225. std::lock_guard<std::mutex> l(nw->lock);
  226. if (OSUtils::jsonBool(old["activeBridge"],false))
  227. nw->activeBridgeMembers.erase(memberId);
  228. wasAuth = OSUtils::jsonBool(old["authorized"],false);
  229. if (wasAuth)
  230. nw->authorizedMembers.erase(memberId);
  231. json &ips = old["ipAssignments"];
  232. if (ips.is_array()) {
  233. for(unsigned long i=0;i<ips.size();++i) {
  234. json &ipj = ips[i];
  235. if (ipj.is_string()) {
  236. const std::string ips = ipj;
  237. InetAddress ipa(ips.c_str());
  238. ipa.setPort(0);
  239. nw->allocatedIps.erase(ipa);
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. if (memberConfig.is_object()) {
  247. if (!nw) {
  248. memberId = OSUtils::jsonIntHex(memberConfig["id"],0ULL);
  249. networkId = OSUtils::jsonIntHex(memberConfig["nwid"],0ULL);
  250. if ((!memberId)||(!networkId))
  251. return;
  252. std::lock_guard<std::mutex> l(_networks_l);
  253. std::shared_ptr<_Network> &nw2 = _networks[networkId];
  254. if (!nw2)
  255. nw2.reset(new _Network);
  256. nw = nw2;
  257. }
  258. {
  259. std::lock_guard<std::mutex> l(nw->lock);
  260. nw->members[memberId] = memberConfig;
  261. if (OSUtils::jsonBool(memberConfig["activeBridge"],false))
  262. nw->activeBridgeMembers.insert(memberId);
  263. isAuth = OSUtils::jsonBool(memberConfig["authorized"],false);
  264. if (isAuth)
  265. nw->authorizedMembers.insert(memberId);
  266. json &ips = memberConfig["ipAssignments"];
  267. if (ips.is_array()) {
  268. for(unsigned long i=0;i<ips.size();++i) {
  269. json &ipj = ips[i];
  270. if (ipj.is_string()) {
  271. const std::string ips = ipj;
  272. InetAddress ipa(ips.c_str());
  273. ipa.setPort(0);
  274. nw->allocatedIps.insert(ipa);
  275. }
  276. }
  277. }
  278. if (!isAuth) {
  279. const int64_t ldt = (int64_t)OSUtils::jsonInt(memberConfig["lastDeauthorizedTime"],0ULL);
  280. if (ldt > nw->mostRecentDeauthTime)
  281. nw->mostRecentDeauthTime = ldt;
  282. }
  283. }
  284. if (push)
  285. _controller->onNetworkMemberUpdate(networkId,memberId);
  286. } else if (memberId) {
  287. if (nw) {
  288. std::lock_guard<std::mutex> l(nw->lock);
  289. nw->members.erase(memberId);
  290. }
  291. if (networkId) {
  292. std::lock_guard<std::mutex> l(_networks_l);
  293. auto er = _networkByMember.equal_range(memberId);
  294. for(auto i=er.first;i!=er.second;++i) {
  295. if (i->second == networkId) {
  296. _networkByMember.erase(i);
  297. break;
  298. }
  299. }
  300. }
  301. }
  302. /*
  303. if (old.is_object()) {
  304. json &config = old["config"];
  305. if (config.is_object()) {
  306. memberId = OSUtils::jsonIntHex(config["id"],0ULL);
  307. networkId = OSUtils::jsonIntHex(config["nwid"],0ULL);
  308. if ((memberId)&&(networkId)) {
  309. {
  310. std::lock_guard<std::mutex> l(_networks_l);
  311. auto nw2 = _networks.find(networkId);
  312. if (nw2 != _networks.end())
  313. nw = nw2->second;
  314. }
  315. if (nw) {
  316. std::lock_guard<std::mutex> l(nw->lock);
  317. if (OSUtils::jsonBool(config["activeBridge"],false))
  318. nw->activeBridgeMembers.erase(memberId);
  319. wasAuth = OSUtils::jsonBool(config["authorized"],false);
  320. if (wasAuth)
  321. nw->authorizedMembers.erase(memberId);
  322. json &ips = config["ipAssignments"];
  323. if (ips.is_array()) {
  324. for(unsigned long i=0;i<ips.size();++i) {
  325. json &ipj = ips[i];
  326. if (ipj.is_string()) {
  327. const std::string ips = ipj;
  328. InetAddress ipa(ips.c_str());
  329. ipa.setPort(0);
  330. nw->allocatedIps.erase(ipa);
  331. }
  332. }
  333. }
  334. }
  335. }
  336. }
  337. }
  338. if (member.is_object()) {
  339. json &config = member["config"];
  340. if (config.is_object()) {
  341. if (!nw) {
  342. memberId = OSUtils::jsonIntHex(config["id"],0ULL);
  343. networkId = OSUtils::jsonIntHex(config["nwid"],0ULL);
  344. if ((!memberId)||(!networkId))
  345. return;
  346. std::lock_guard<std::mutex> l(_networks_l);
  347. std::shared_ptr<_Network> &nw2 = _networks[networkId];
  348. if (!nw2)
  349. nw2.reset(new _Network);
  350. nw = nw2;
  351. }
  352. {
  353. std::lock_guard<std::mutex> l(nw->lock);
  354. nw->members[memberId] = config;
  355. if (OSUtils::jsonBool(config["activeBridge"],false))
  356. nw->activeBridgeMembers.insert(memberId);
  357. isAuth = OSUtils::jsonBool(config["authorized"],false);
  358. if (isAuth)
  359. nw->authorizedMembers.insert(memberId);
  360. json &ips = config["ipAssignments"];
  361. if (ips.is_array()) {
  362. for(unsigned long i=0;i<ips.size();++i) {
  363. json &ipj = ips[i];
  364. if (ipj.is_string()) {
  365. const std::string ips = ipj;
  366. InetAddress ipa(ips.c_str());
  367. ipa.setPort(0);
  368. nw->allocatedIps.insert(ipa);
  369. }
  370. }
  371. }
  372. if (!isAuth) {
  373. const int64_t ldt = (int64_t)OSUtils::jsonInt(config["lastDeauthorizedTime"],0ULL);
  374. if (ldt > nw->mostRecentDeauthTime)
  375. nw->mostRecentDeauthTime = ldt;
  376. }
  377. }
  378. if (push)
  379. _controller->onNetworkMemberUpdate(networkId,memberId);
  380. }
  381. } else if (memberId) {
  382. if (nw) {
  383. std::lock_guard<std::mutex> l(nw->lock);
  384. nw->members.erase(memberId);
  385. }
  386. if (networkId) {
  387. std::lock_guard<std::mutex> l(_networks_l);
  388. auto er = _networkByMember.equal_range(memberId);
  389. for(auto i=er.first;i!=er.second;++i) {
  390. if (i->second == networkId) {
  391. _networkByMember.erase(i);
  392. break;
  393. }
  394. }
  395. }
  396. }
  397. */
  398. if ((push)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId)))
  399. _controller->onNetworkMemberDeauthorize(networkId,memberId);
  400. }
  401. void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool push)
  402. {
  403. if (networkConfig.is_object()) {
  404. const std::string ids = networkConfig["id"];
  405. const uint64_t id = Utils::hexStrToU64(ids.c_str());
  406. if (id) {
  407. std::shared_ptr<_Network> nw;
  408. {
  409. std::lock_guard<std::mutex> l(_networks_l);
  410. std::shared_ptr<_Network> &nw2 = _networks[id];
  411. if (!nw2)
  412. nw2.reset(new _Network);
  413. nw = nw2;
  414. }
  415. {
  416. std::lock_guard<std::mutex> l2(nw->lock);
  417. nw->config = networkConfig;
  418. }
  419. if (push)
  420. _controller->onNetworkUpdate(id);
  421. }
  422. } else if (old.is_object()) {
  423. const std::string ids = old["id"];
  424. const uint64_t id = Utils::hexStrToU64(ids.c_str());
  425. if (id) {
  426. std::lock_guard<std::mutex> l(_networks_l);
  427. _networks.erase(id);
  428. }
  429. }
  430. /*
  431. if (network.is_object()) {
  432. json &config = network["config"];
  433. if (networkConfig.is_object()) {
  434. const std::string ids = config["id"];
  435. const uint64_t id = Utils::hexStrToU64(ids.c_str());
  436. if (id) {
  437. std::shared_ptr<_Network> nw;
  438. {
  439. std::lock_guard<std::mutex> l(_networks_l);
  440. std::shared_ptr<_Network> &nw2 = _networks[id];
  441. if (!nw2)
  442. nw2.reset(new _Network);
  443. nw = nw2;
  444. }
  445. {
  446. std::lock_guard<std::mutex> l2(nw->lock);
  447. nw->config = config;
  448. }
  449. if (push)
  450. _controller->onNetworkUpdate(id);
  451. }
  452. }
  453. } else if (old.is_object()) {
  454. const std::string ids = old["id"];
  455. const uint64_t id = Utils::hexStrToU64(ids.c_str());
  456. if (id) {
  457. std::lock_guard<std::mutex> l(_networks_l);
  458. _networks.erase(id);
  459. }
  460. }
  461. */
  462. }
  463. void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info)
  464. {
  465. for(auto ab=nw->activeBridgeMembers.begin();ab!=nw->activeBridgeMembers.end();++ab)
  466. info.activeBridges.push_back(Address(*ab));
  467. std::sort(info.activeBridges.begin(),info.activeBridges.end());
  468. for(auto ip=nw->allocatedIps.begin();ip!=nw->allocatedIps.end();++ip)
  469. info.allocatedIps.push_back(*ip);
  470. std::sort(info.allocatedIps.begin(),info.allocatedIps.end());
  471. info.authorizedMemberCount = (unsigned long)nw->authorizedMembers.size();
  472. info.totalMemberCount = (unsigned long)nw->members.size();
  473. info.mostRecentDeauthTime = nw->mostRecentDeauthTime;
  474. }
  475. } // namespace ZeroTier