Network.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*
  2. * ZeroTier One - Global Peer to Peer Ethernet
  3. * Copyright (C) 2011-2014 ZeroTier Networks LLC
  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. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <math.h>
  31. #include "Constants.hpp"
  32. #include "Network.hpp"
  33. #include "RuntimeEnvironment.hpp"
  34. #include "NodeConfig.hpp"
  35. #include "Switch.hpp"
  36. #include "Packet.hpp"
  37. #include "Buffer.hpp"
  38. #ifdef __WINDOWS__
  39. #include "WindowsEthernetTap.hpp"
  40. #else
  41. #include "UnixEthernetTap.hpp"
  42. #endif
  43. #define ZT_NETWORK_CERT_WRITE_BUF_SIZE 131072
  44. namespace ZeroTier {
  45. const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xff),0);
  46. const char *Network::statusString(const Status s)
  47. throw()
  48. {
  49. switch(s) {
  50. case NETWORK_INITIALIZING: return "INITIALIZING";
  51. case NETWORK_WAITING_FOR_FIRST_AUTOCONF: return "WAITING_FOR_FIRST_AUTOCONF";
  52. case NETWORK_OK: return "OK";
  53. case NETWORK_ACCESS_DENIED: return "ACCESS_DENIED";
  54. case NETWORK_NOT_FOUND: return "NOT_FOUND";
  55. case NETWORK_INITIALIZATION_FAILED: return "INITIALIZATION_FAILED";
  56. case NETWORK_NO_MORE_DEVICES: return "NO_MORE_DEVICES";
  57. }
  58. return "(invalid)";
  59. }
  60. Network::~Network()
  61. {
  62. Thread::join(_setupThread);
  63. #ifdef __WINDOWS__
  64. std::string devPersistentId;
  65. if (_tap) {
  66. devPersistentId = _tap->persistentId();
  67. delete _tap;
  68. }
  69. #else
  70. if (_tap)
  71. delete _tap;
  72. #endif
  73. if (_destroyOnDelete) {
  74. Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".conf"));
  75. Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts"));
  76. #ifdef __WINDOWS__
  77. if (devPersistentId.length())
  78. WindowsEthernetTap::deletePersistentTapDevice(_r,devPersistentId.c_str());
  79. #endif
  80. } else {
  81. // Causes flush of membership certs to disk
  82. clean();
  83. _dumpMulticastCerts();
  84. }
  85. }
  86. SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,NodeConfig *nc,uint64_t id)
  87. {
  88. /* We construct Network via a static method to ensure that it is immediately
  89. * wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet
  90. * tap device, a SharedPtr<> wrap can occur in the Ethernet frame handler
  91. * that then causes the Network instance to be deleted before it is finished
  92. * being constructed. C++ edge cases, how I love thee. */
  93. SharedPtr<Network> nw(new Network());
  94. nw->_id = id;
  95. nw->_nc = nc;
  96. nw->_mac.fromAddress(renv->identity.address(),id);
  97. nw->_r = renv;
  98. nw->_tap = (EthernetTap *)0;
  99. nw->_enabled = true;
  100. nw->_lastConfigUpdate = 0;
  101. nw->_destroyOnDelete = false;
  102. nw->_netconfFailure = NETCONF_FAILURE_NONE;
  103. if (nw->controller() == renv->identity.address()) // netconf masters can't really join networks
  104. throw std::runtime_error("cannot join a network for which I am the netconf master");
  105. nw->_setupThread = Thread::start<Network>(nw.ptr());
  106. return nw;
  107. }
  108. bool Network::updateMulticastGroups()
  109. {
  110. Mutex::Lock _l(_lock);
  111. EthernetTap *t = _tap;
  112. if (t) {
  113. // Grab current groups from the local tap
  114. bool updated = _tap->updateMulticastGroups(_multicastGroups);
  115. // Merge in learned groups from any hosts bridged in behind us
  116. for(std::map<MulticastGroup,uint64_t>::const_iterator mg(_bridgedMulticastGroups.begin());mg!=_bridgedMulticastGroups.end();++mg)
  117. _multicastGroups.insert(mg->first);
  118. // Add or remove BROADCAST group based on broadcast enabled netconf flag
  119. if ((_config)&&(_config->enableBroadcast())) {
  120. if (_multicastGroups.count(BROADCAST))
  121. return updated;
  122. else {
  123. _multicastGroups.insert(BROADCAST);
  124. return true;
  125. }
  126. } else {
  127. if (_multicastGroups.count(BROADCAST)) {
  128. _multicastGroups.erase(BROADCAST);
  129. return true;
  130. } else return updated;
  131. }
  132. } else return false;
  133. }
  134. bool Network::setConfiguration(const Dictionary &conf,bool saveToDisk)
  135. {
  136. Mutex::Lock _l(_lock);
  137. EthernetTap *t = _tap;
  138. if (!t) {
  139. TRACE("BUG: setConfiguration() called while tap is null!");
  140. return false; // can't accept config in initialization state
  141. }
  142. try {
  143. SharedPtr<NetworkConfig> newConfig(new NetworkConfig(conf));
  144. if ((newConfig->networkId() == _id)&&(newConfig->issuedTo() == _r->identity.address())) {
  145. _config = newConfig;
  146. if (newConfig->staticIps().size())
  147. t->setIps(newConfig->staticIps());
  148. t->setDisplayName((std::string("ZeroTier One [") + newConfig->name() + "]").c_str());
  149. _lastConfigUpdate = Utils::now();
  150. _netconfFailure = NETCONF_FAILURE_NONE;
  151. if (saveToDisk) {
  152. std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".conf");
  153. if (!Utils::writeFile(confPath.c_str(),conf.toString())) {
  154. LOG("error: unable to write network configuration file at: %s",confPath.c_str());
  155. } else {
  156. Utils::lockDownFile(confPath.c_str(),false);
  157. }
  158. }
  159. return true;
  160. } else {
  161. LOG("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id);
  162. }
  163. } catch (std::exception &exc) {
  164. LOG("ignored invalid configuration for network %.16llx (%s)",(unsigned long long)_id,exc.what());
  165. } catch ( ... ) {
  166. LOG("ignored invalid configuration for network %.16llx (unknown exception)",(unsigned long long)_id);
  167. }
  168. return false;
  169. }
  170. void Network::requestConfiguration()
  171. {
  172. if (!_tap)
  173. return; // don't bother requesting until we are initialized
  174. if (controller() == _r->identity.address()) {
  175. // netconf master cannot be a member of its own nets
  176. LOG("unable to request network configuration for network %.16llx: I am the network master, cannot query self",(unsigned long long)_id);
  177. return;
  178. }
  179. TRACE("requesting netconf for network %.16llx from netconf master %s",(unsigned long long)_id,controller().toString().c_str());
  180. Packet outp(controller(),_r->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST);
  181. outp.append((uint64_t)_id);
  182. outp.append((uint16_t)0); // no meta-data
  183. _r->sw->send(outp,true);
  184. }
  185. void Network::addMembershipCertificate(const CertificateOfMembership &cert)
  186. {
  187. if (!cert) // sanity check
  188. return;
  189. Mutex::Lock _l(_lock);
  190. // We go ahead and accept certs provisionally even if _isOpen is true, since
  191. // that might be changed in short order if the user is fiddling in the UI.
  192. // These will be purged on clean() for open networks eventually.
  193. CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()];
  194. if (cert.timestamp() >= old.timestamp()) {
  195. //TRACE("got new certificate for %s on network %.16llx",cert.issuedTo().toString().c_str(),cert.networkId());
  196. old = cert;
  197. }
  198. }
  199. bool Network::isAllowed(const Address &peer) const
  200. {
  201. try {
  202. Mutex::Lock _l(_lock);
  203. if (!_config)
  204. return false;
  205. if (_config->isPublic())
  206. return true;
  207. std::map<Address,CertificateOfMembership>::const_iterator pc(_membershipCertificates.find(peer));
  208. if (pc == _membershipCertificates.end())
  209. return false; // no certificate on file
  210. return _config->com().agreesWith(pc->second); // is other cert valid against ours?
  211. } catch (std::exception &exc) {
  212. TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what());
  213. } catch ( ... ) {
  214. TRACE("isAllowed() check failed for peer %s: unexpected exception: unknown exception",peer.toString().c_str());
  215. }
  216. return false; // default position on any failure
  217. }
  218. void Network::clean()
  219. {
  220. Mutex::Lock _l(_lock);
  221. uint64_t now = Utils::now();
  222. if ((_config)&&(_config->isPublic())) {
  223. // Open (public) networks do not track certs or cert pushes at all.
  224. _membershipCertificates.clear();
  225. _lastPushedMembershipCertificate.clear();
  226. } else if (_config) {
  227. // Clean certificates that are no longer valid from the cache.
  228. for(std::map<Address,CertificateOfMembership>::iterator c=(_membershipCertificates.begin());c!=_membershipCertificates.end();) {
  229. if (_config->com().agreesWith(c->second))
  230. ++c;
  231. else _membershipCertificates.erase(c++);
  232. }
  233. // Clean entries from the last pushed tracking map if they're so old as
  234. // to be no longer relevant.
  235. uint64_t forgetIfBefore = now - (_config->com().timestampMaxDelta() * 3ULL);
  236. for(std::map<Address,uint64_t>::iterator lp(_lastPushedMembershipCertificate.begin());lp!=_lastPushedMembershipCertificate.end();) {
  237. if (lp->second < forgetIfBefore)
  238. _lastPushedMembershipCertificate.erase(lp++);
  239. else ++lp;
  240. }
  241. }
  242. // Clean learned multicast groups if we haven't heard from them in a while
  243. for(std::map<MulticastGroup,uint64_t>::iterator mg(_bridgedMulticastGroups.begin());mg!=_bridgedMulticastGroups.end();) {
  244. if ((now - mg->second) > (ZT_MULTICAST_LIKE_EXPIRE * 2))
  245. _bridgedMulticastGroups.erase(mg++);
  246. else ++mg;
  247. }
  248. }
  249. Network::Status Network::status() const
  250. {
  251. Mutex::Lock _l(_lock);
  252. if (_tap) {
  253. switch(_netconfFailure) {
  254. case NETCONF_FAILURE_ACCESS_DENIED:
  255. return NETWORK_ACCESS_DENIED;
  256. case NETCONF_FAILURE_NOT_FOUND:
  257. return NETWORK_NOT_FOUND;
  258. case NETCONF_FAILURE_NONE:
  259. if (_lastConfigUpdate > 0)
  260. return NETWORK_OK;
  261. else return NETWORK_WAITING_FOR_FIRST_AUTOCONF;
  262. case NETCONF_FAILURE_INIT_FAILED:
  263. default:
  264. return NETWORK_INITIALIZATION_FAILED;
  265. }
  266. } else if (_netconfFailure == NETCONF_FAILURE_INIT_FAILED) {
  267. return NETWORK_INITIALIZATION_FAILED;
  268. } else return NETWORK_INITIALIZING;
  269. }
  270. void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
  271. {
  272. if ((!((Network *)arg)->_enabled)||(((Network *)arg)->status() != NETWORK_OK))
  273. return;
  274. const RuntimeEnvironment *_r = ((Network *)arg)->_r;
  275. if (_r->shutdownInProgress)
  276. return;
  277. try {
  278. _r->sw->onLocalEthernet(SharedPtr<Network>((Network *)arg),from,to,etherType,data);
  279. } catch (std::exception &exc) {
  280. TRACE("unexpected exception handling local packet: %s",exc.what());
  281. } catch ( ... ) {
  282. TRACE("unexpected exception handling local packet");
  283. }
  284. }
  285. void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t now)
  286. {
  287. uint64_t pushTimeout = _config->com().timestampMaxDelta() / 2;
  288. if (!pushTimeout)
  289. return; // still waiting on my own cert
  290. if (pushTimeout > 1000)
  291. pushTimeout -= 1000;
  292. uint64_t &lastPushed = _lastPushedMembershipCertificate[peer];
  293. if ((force)||((now - lastPushed) > pushTimeout)) {
  294. lastPushed = now;
  295. TRACE("pushing membership cert for %.16llx to %s",(unsigned long long)_id,peer.toString().c_str());
  296. Packet outp(peer,_r->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
  297. _config->com().serialize(outp);
  298. _r->sw->send(outp,true);
  299. }
  300. }
  301. void Network::threadMain()
  302. throw()
  303. {
  304. // Setup thread -- this exits when tap is constructed. It's here
  305. // because opening the tap can take some time on some platforms.
  306. try {
  307. #ifdef __WINDOWS__
  308. // Windows tags interfaces by their network IDs, which are shoved into the
  309. // registry to mark persistent instance of the tap device.
  310. char tag[24];
  311. Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)_id);
  312. _tap = new WindowsEthernetTap(_r,tag,_mac,ZT_IF_MTU,&_CBhandleTapData,this);
  313. #else
  314. // Unix tries to get the same device name next time, if possible.
  315. std::string tagstr;
  316. char lcentry[128];
  317. Utils::snprintf(lcentry,sizeof(lcentry),"_dev_for_%.16llx",(unsigned long long)_id);
  318. tagstr = _nc->getLocalConfig(lcentry);
  319. const char *tag = (tagstr.length() > 0) ? tagstr.c_str() : (const char *)0;
  320. _tap = new UnixEthernetTap(_r,tag,_mac,ZT_IF_MTU,&_CBhandleTapData,this);
  321. std::string dn(_tap->deviceName());
  322. if ((!tag)||(dn != tag))
  323. _nc->putLocalConfig(lcentry,dn);
  324. #endif
  325. } catch (std::exception &exc) {
  326. delete _tap;
  327. _tap = (EthernetTap *)0;
  328. LOG("network %.16llx failed to initialize: %s",_id,exc.what());
  329. _netconfFailure = NETCONF_FAILURE_INIT_FAILED;
  330. } catch ( ... ) {
  331. delete _tap;
  332. _tap = (EthernetTap *)0;
  333. LOG("network %.16llx failed to initialize: unknown error",_id);
  334. _netconfFailure = NETCONF_FAILURE_INIT_FAILED;
  335. }
  336. try {
  337. _restoreState();
  338. requestConfiguration();
  339. } catch ( ... ) {
  340. TRACE("BUG: exception in network setup thread in _restoreState() or requestConfiguration()!");
  341. _lastConfigUpdate = 0; // call requestConfiguration() again
  342. }
  343. }
  344. void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
  345. {
  346. Mutex::Lock _l(_lock);
  347. _bridgeRoutes[mac] = addr;
  348. // If _bridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker
  349. while (_bridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
  350. std::map<Address,unsigned long> counts;
  351. Address maxAddr;
  352. unsigned long maxCount = 0;
  353. for(std::map<MAC,Address>::iterator br(_bridgeRoutes.begin());br!=_bridgeRoutes.end();++br) {
  354. unsigned long c = ++counts[br->second];
  355. if (c > maxCount) {
  356. maxCount = c;
  357. maxAddr = br->second;
  358. }
  359. }
  360. for(std::map<MAC,Address>::iterator br(_bridgeRoutes.begin());br!=_bridgeRoutes.end();) {
  361. if (br->second == maxAddr)
  362. _bridgeRoutes.erase(br++);
  363. else ++br;
  364. }
  365. }
  366. }
  367. void Network::setEnabled(bool enabled)
  368. {
  369. Mutex::Lock _l(_lock);
  370. _enabled = enabled;
  371. // TODO: bring OS network device to "down" state if enabled == false
  372. }
  373. void Network::_restoreState()
  374. {
  375. if (!_id)
  376. return; // sanity check
  377. Buffer<ZT_NETWORK_CERT_WRITE_BUF_SIZE> buf;
  378. std::string idstr(idString());
  379. std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idstr + ".conf");
  380. std::string mcdbPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idstr + ".mcerts");
  381. // Read configuration file containing last config from netconf master
  382. {
  383. std::string confs;
  384. if (Utils::readFile(confPath.c_str(),confs)) {
  385. try {
  386. if (confs.length())
  387. setConfiguration(Dictionary(confs),false);
  388. } catch ( ... ) {} // ignore invalid config on disk, we will re-request from netconf master
  389. } else {
  390. // If the conf file isn't present, "touch" it so we'll remember
  391. // the existence of this network.
  392. FILE *tmp = fopen(confPath.c_str(),"wb");
  393. if (tmp)
  394. fclose(tmp);
  395. }
  396. }
  397. // Read most recent multicast cert dump
  398. if ((_config)&&(!_config->isPublic())&&(Utils::fileExists(mcdbPath.c_str()))) {
  399. CertificateOfMembership com;
  400. Mutex::Lock _l(_lock);
  401. _membershipCertificates.clear();
  402. FILE *mcdb = fopen(mcdbPath.c_str(),"rb");
  403. if (mcdb) {
  404. try {
  405. char magic[6];
  406. if ((fread(magic,6,1,mcdb) == 1)&&(!memcmp("ZTMCD0",magic,6))) {
  407. long rlen = 0;
  408. do {
  409. long rlen = (long)fread(buf.data() + buf.size(),1,ZT_NETWORK_CERT_WRITE_BUF_SIZE - buf.size(),mcdb);
  410. if (rlen < 0) rlen = 0;
  411. buf.setSize(buf.size() + (unsigned int)rlen);
  412. unsigned int ptr = 0;
  413. while ((ptr < (ZT_NETWORK_CERT_WRITE_BUF_SIZE / 2))&&(ptr < buf.size())) {
  414. ptr += com.deserialize(buf,ptr);
  415. if (com.issuedTo())
  416. _membershipCertificates[com.issuedTo()] = com;
  417. }
  418. if (ptr) {
  419. memmove(buf.data(),buf.data() + ptr,buf.size() - ptr);
  420. buf.setSize(buf.size() - ptr);
  421. }
  422. } while (rlen > 0);
  423. fclose(mcdb);
  424. } else {
  425. fclose(mcdb);
  426. Utils::rm(mcdbPath);
  427. }
  428. } catch ( ... ) {
  429. // Membership cert dump file invalid. We'll re-learn them off the net.
  430. _membershipCertificates.clear();
  431. fclose(mcdb);
  432. Utils::rm(mcdbPath);
  433. }
  434. }
  435. }
  436. }
  437. void Network::_dumpMulticastCerts()
  438. {
  439. Buffer<ZT_NETWORK_CERT_WRITE_BUF_SIZE> buf;
  440. std::string mcdbPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts");
  441. Mutex::Lock _l(_lock);
  442. if (!_config)
  443. return;
  444. if ((!_id)||(_config->isPublic())) {
  445. Utils::rm(mcdbPath);
  446. return;
  447. }
  448. FILE *mcdb = fopen(mcdbPath.c_str(),"wb");
  449. if (!mcdb)
  450. return;
  451. if (fwrite("ZTMCD0",6,1,mcdb) != 1) {
  452. fclose(mcdb);
  453. Utils::rm(mcdbPath);
  454. return;
  455. }
  456. for(std::map<Address,CertificateOfMembership>::iterator c=(_membershipCertificates.begin());c!=_membershipCertificates.end();++c) {
  457. try {
  458. c->second.serialize(buf);
  459. if (buf.size() >= (ZT_NETWORK_CERT_WRITE_BUF_SIZE / 2)) {
  460. if (fwrite(buf.data(),buf.size(),1,mcdb) != 1) {
  461. fclose(mcdb);
  462. Utils::rm(mcdbPath);
  463. return;
  464. }
  465. buf.clear();
  466. }
  467. } catch ( ... ) {
  468. // Sanity check... no cert will ever be big enough to overflow buf
  469. fclose(mcdb);
  470. Utils::rm(mcdbPath);
  471. return;
  472. }
  473. }
  474. if (buf.size()) {
  475. if (fwrite(buf.data(),buf.size(),1,mcdb) != 1) {
  476. fclose(mcdb);
  477. Utils::rm(mcdbPath);
  478. return;
  479. }
  480. }
  481. fclose(mcdb);
  482. Utils::lockDownFile(mcdbPath.c_str(),false);
  483. }
  484. } // namespace ZeroTier