One.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2015 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. * --
  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 <stdlib.h>
  29. #include <string.h>
  30. #include "../version.h"
  31. #include "../include/ZeroTierOne.h"
  32. #include "../node/Constants.hpp"
  33. #include "../node/Mutex.hpp"
  34. #include "../node/Node.hpp"
  35. #include "../node/Utils.hpp"
  36. #include "../node/InetAddress.hpp"
  37. #include "../osdep/Phy.hpp"
  38. #include "../osdep/Thread.hpp"
  39. #include "../osdep/OSUtils.hpp"
  40. #include "One.hpp"
  41. namespace ZeroTier {
  42. static void SphyOnDatagramFunction(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len);
  43. static void SphyOnTcpConnectFunction(PhySocket *sock,void **uptr,bool success);
  44. static void SphyOnTcpAcceptFunction(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from);
  45. static void SphyOnTcpCloseFunction(PhySocket *sock,void **uptr);
  46. static void SphyOnTcpDataFunction(PhySocket *sock,void **uptr,void *data,unsigned long len);
  47. static void SphyOnTcpWritableFunction(PhySocket *sock,void **uptr);
  48. static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf);
  49. static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData);
  50. static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize);
  51. static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
  52. static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len);
  53. static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
  54. class OneImpl : public One
  55. {
  56. public:
  57. OneImpl(const char *hp,unsigned int port,NetworkConfigMaster *master,const char *overrideRootTopology) :
  58. _homePath((hp) ? hp : "."),
  59. _phy(SphyOnDatagramFunction,SphyOnTcpConnectFunction,SphyOnTcpAcceptFunction,SphyOnTcpCloseFunction,SphyOnTcpDataFunction,SphyOnTcpWritableFunction,true),
  60. _master(master),
  61. _overrideRootTopology((overrideRootTopology) ? overrideRootTopology : ""),
  62. _node((Node *)0),
  63. _nextBackgroundTaskDeadline(0),
  64. _termReason(ONE_STILL_RUNNING),
  65. _run(true)
  66. {
  67. struct sockaddr_in in4;
  68. struct sockaddr_in6 in6;
  69. if (*hp) {
  70. std::vector<std::string> hpsp(Utils::split(hp,ZT_PATH_SEPARATOR_S,"",""));
  71. std::string ptmp;
  72. if (*hp == '/')
  73. ptmp.push_back('/');
  74. for(std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) {
  75. if (ptmp.length() > 0)
  76. ptmp.push_back(ZT_PATH_SEPARATOR);
  77. ptmp.append(*pi);
  78. if ((*pi != ".")&&(*pi != "..")) {
  79. if (!OSUtils::mkdir(ptmp))
  80. throw std::runtime_error("home path does not exist, and could not create");
  81. }
  82. }
  83. }
  84. ::memset((void *)&in4,0,sizeof(in4));
  85. in4.sin_family = AF_INET;
  86. in4.sin_port = Utils::hton(port);
  87. _v4UdpSocket = _phy.udpBind((const struct sockaddr *)&in4,this,131072);
  88. if (!_v4UdpSocket)
  89. throw std::runtime_error("cannot bind to port (UDP/IPv4)");
  90. _v4TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this);
  91. if (!_v4TcpListenSocket) {
  92. _phy.close(_v4UdpSocket);
  93. throw std::runtime_error("cannot bind to port (TCP/IPv4)");
  94. }
  95. ::memset((void *)&in6,0,sizeof(in6));
  96. in6.sin6_family = AF_INET6;
  97. in6.sin6_port = in4.sin_port;
  98. _v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,this,131072);
  99. _v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this);
  100. _thread = Thread::start(this);
  101. }
  102. virtual ~OneImpl()
  103. {
  104. if (reasonForTermination() == ONE_STILL_RUNNING) {
  105. terminate();
  106. waitForTermination();
  107. }
  108. _phy.close(_v4UdpSocket);
  109. _phy.close(_v6UdpSocket);
  110. _phy.close(_v4TcpListenSocket);
  111. _phy.close(_v6TcpListenSocket);
  112. }
  113. virtual ReasonForTermination reasonForTermination() const
  114. {
  115. Mutex::Lock _l(_termReason_m);
  116. return _termReason;
  117. }
  118. virtual std::string fatalErrorMessage() const
  119. {
  120. Mutex::Lock _l(_termReason_m);
  121. return _fatalErrorMessage;
  122. }
  123. virtual void waitForTermination()
  124. {
  125. if (reasonForTermination() == ONE_STILL_RUNNING)
  126. Thread::join(_thread);
  127. }
  128. virtual void terminate()
  129. {
  130. _run_m.lock();
  131. _run = false;
  132. _run_m.unlock();
  133. _phy.whack();
  134. }
  135. // Begin private implementation methods
  136. inline void phyOnDatagramFunction(PhySocket *sock,const struct sockaddr *from,void *data,unsigned long len)
  137. {
  138. ZT1_ResultCode rc = _node->processWirePacket(
  139. OSUtils::now(),
  140. (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
  141. 0,
  142. data,
  143. len,
  144. const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
  145. if (ZT1_ResultCode_isFatal(rc)) {
  146. char tmp[256];
  147. Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket(%d)",(int)rc);
  148. Mutex::Lock _l(_termReason_m);
  149. _termReason = ONE_UNRECOVERABLE_ERROR;
  150. _fatalErrorMessage = tmp;
  151. this->terminate();
  152. }
  153. }
  154. inline void phyOnTcpConnectFunction(PhySocket *sock,bool success)
  155. {
  156. }
  157. inline void phyOnTcpAcceptFunction(PhySocket *sockN,const struct sockaddr *from)
  158. {
  159. }
  160. inline void phyOnTcpCloseFunction(PhySocket *sock)
  161. {
  162. }
  163. inline void phyOnTcpDataFunction(PhySocket *sock,void *data,unsigned long len)
  164. {
  165. }
  166. inline void phyOnTcpWritableFunction(PhySocket *sock)
  167. {
  168. }
  169. inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf)
  170. {
  171. return 0;
  172. }
  173. inline void nodeEventCallback(enum ZT1_Event event,const void *metaData)
  174. {
  175. switch(event) {
  176. case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION: {
  177. Mutex::Lock _l(_termReason_m);
  178. _termReason = ONE_IDENTITY_COLLISION;
  179. _fatalErrorMessage = "identity/address collision";
  180. this->terminate();
  181. } break;
  182. case ZT1_EVENT_SAW_MORE_RECENT_VERSION: {
  183. } break;
  184. case ZT1_EVENT_TRACE: {
  185. if (metaData) {
  186. ::fprintf(stderr,"%s"ZT_EOL_S,(const char *)metaData);
  187. ::fflush(stderr);
  188. }
  189. } break;
  190. default:
  191. break;
  192. }
  193. }
  194. inline long nodeDataStoreGetFunction(const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize)
  195. {
  196. std::string p(_homePath);
  197. p.push_back(ZT_PATH_SEPARATOR);
  198. char lastc = (char)0;
  199. for(const char *n=name;(*n);++n) {
  200. if ((*n == '.')&&(lastc == '.'))
  201. return -2; // security sanity check-- don't allow ../ stuff even though there's really no way Node will ever do this
  202. p.push_back((*n == '/') ? ZT_PATH_SEPARATOR : *n);
  203. lastc = *n;
  204. }
  205. FILE *f = fopen(p.c_str(),"rb");
  206. if (!f)
  207. return -1;
  208. if (fseek(f,0,SEEK_END) != 0) {
  209. fclose(f);
  210. return -2;
  211. }
  212. long ts = ftell(f);
  213. if (ts < 0) {
  214. fclose(f);
  215. return -2;
  216. }
  217. *totalSize = (unsigned long)ts;
  218. if (fseek(f,(long)readIndex,SEEK_SET) != 0) {
  219. fclose(f);
  220. return -2;
  221. }
  222. long n = (long)fread(buf,1,bufSize,f);
  223. fclose(f);
  224. return n;
  225. }
  226. inline int nodeDataStorePutFunction(const char *name,const void *data,unsigned long len,int secure)
  227. {
  228. std::string p(_homePath);
  229. p.push_back(ZT_PATH_SEPARATOR);
  230. char lastc = (char)0;
  231. for(const char *n=name;(*n);++n) {
  232. if ((*n == '.')&&(lastc == '.'))
  233. return -2; // security sanity check-- don't allow ../ stuff even though there's really no way Node will ever do this
  234. p.push_back((*n == '/') ? ZT_PATH_SEPARATOR : *n);
  235. lastc = *n;
  236. }
  237. if (!data) {
  238. OSUtils::rm(p.c_str());
  239. return 0;
  240. }
  241. FILE *f = fopen(p.c_str(),"wb");
  242. if (!f)
  243. return -1;
  244. if (fwrite(data,len,1,f) == 1) {
  245. fclose(f);
  246. if (secure)
  247. OSUtils::lockDownFile(p.c_str(),false);
  248. return 0;
  249. } else {
  250. fclose(f);
  251. OSUtils::rm(p.c_str());
  252. return -1;
  253. }
  254. }
  255. inline int nodeWirePacketSendFunction(const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len)
  256. {
  257. switch(addr->ss_family) {
  258. case AF_INET:
  259. if (_v4UdpSocket)
  260. return (_phy.udpSend(_v4UdpSocket,(const struct sockaddr *)addr,data,len) ? 0 : -1);
  261. break;
  262. case AF_INET6:
  263. if (_v6UdpSocket)
  264. return (_phy.udpSend(_v6UdpSocket,(const struct sockaddr *)addr,data,len) ? 0 : -1);
  265. break;
  266. }
  267. return -1;
  268. }
  269. inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
  270. {
  271. fprintf(stderr,"VIRTUAL NETWORK FRAME from %.16llx : %.12llx -> %.12llx %.4x %u bytes\n",nwid,sourceMac,destMac,etherType,len);
  272. fflush(stderr);
  273. }
  274. void threadMain()
  275. throw()
  276. {
  277. _nextBackgroundTaskDeadline = 0;
  278. try {
  279. _node = new Node(
  280. OSUtils::now(),
  281. this,
  282. SnodeDataStoreGetFunction,
  283. SnodeDataStorePutFunction,
  284. SnodeWirePacketSendFunction,
  285. SnodeVirtualNetworkFrameFunction,
  286. SnodeVirtualNetworkConfigFunction,
  287. SnodeEventCallback,
  288. ((_overrideRootTopology.length() > 0) ? _overrideRootTopology.c_str() : (const char *)0));
  289. if (_master)
  290. _node->setNetconfMaster((void *)_master);
  291. for(;;) {
  292. _run_m.lock();
  293. if (!_run) {
  294. _run_m.unlock();
  295. break;
  296. } else _run_m.unlock();
  297. uint64_t dl = _nextBackgroundTaskDeadline;
  298. uint64_t now = OSUtils::now();
  299. if (dl <= now) {
  300. _node->processBackgroundTasks(now,const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
  301. dl = _nextBackgroundTaskDeadline;
  302. now = OSUtils::now();
  303. }
  304. _phy.poll((dl > now) ? (unsigned long)(dl - now) : 100);
  305. }
  306. } catch (std::exception &exc) {
  307. Mutex::Lock _l(_termReason_m);
  308. _termReason = ONE_UNRECOVERABLE_ERROR;
  309. _fatalErrorMessage = exc.what();
  310. } catch ( ... ) {
  311. Mutex::Lock _l(_termReason_m);
  312. _termReason = ONE_UNRECOVERABLE_ERROR;
  313. _fatalErrorMessage = "unexpected exception in main thread";
  314. }
  315. delete _node;
  316. }
  317. private:
  318. const std::string _homePath;
  319. SimpleFunctionPhy _phy;
  320. NetworkConfigMaster *_master;
  321. std::string _overrideRootTopology;
  322. Node *_node;
  323. PhySocket *_v4UdpSocket;
  324. PhySocket *_v6UdpSocket;
  325. PhySocket *_v4TcpListenSocket;
  326. PhySocket *_v6TcpListenSocket;
  327. Thread _thread;
  328. volatile uint64_t _nextBackgroundTaskDeadline;
  329. ReasonForTermination _termReason;
  330. std::string _fatalErrorMessage;
  331. Mutex _termReason_m;
  332. bool _run;
  333. Mutex _run_m;
  334. };
  335. static void SphyOnDatagramFunction(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len)
  336. { reinterpret_cast<OneImpl *>(*uptr)->phyOnDatagramFunction(sock,from,data,len); }
  337. static void SphyOnTcpConnectFunction(PhySocket *sock,void **uptr,bool success)
  338. { reinterpret_cast<OneImpl *>(*uptr)->phyOnTcpConnectFunction(sock,success); }
  339. static void SphyOnTcpAcceptFunction(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from)
  340. { *uptrN = *uptrL; reinterpret_cast<OneImpl *>(*uptrL)->phyOnTcpAcceptFunction(sockN,from); }
  341. static void SphyOnTcpCloseFunction(PhySocket *sock,void **uptr)
  342. { reinterpret_cast<OneImpl *>(*uptr)->phyOnTcpCloseFunction(sock); }
  343. static void SphyOnTcpDataFunction(PhySocket *sock,void **uptr,void *data,unsigned long len)
  344. { reinterpret_cast<OneImpl *>(*uptr)->phyOnTcpDataFunction(sock,data,len); }
  345. static void SphyOnTcpWritableFunction(PhySocket *sock,void **uptr)
  346. { reinterpret_cast<OneImpl *>(*uptr)->phyOnTcpWritableFunction(sock); }
  347. static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf)
  348. { return reinterpret_cast<OneImpl *>(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); }
  349. static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData)
  350. { reinterpret_cast<OneImpl *>(uptr)->nodeEventCallback(event,metaData); }
  351. static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize)
  352. { return reinterpret_cast<OneImpl *>(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); }
  353. static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure)
  354. { return reinterpret_cast<OneImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); }
  355. static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len)
  356. { return reinterpret_cast<OneImpl *>(uptr)->nodeWirePacketSendFunction(addr,desperation,data,len); }
  357. static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
  358. { reinterpret_cast<OneImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); }
  359. std::string One::platformDefaultHomePath()
  360. {
  361. #ifdef __UNIX_LIKE__
  362. #ifdef __APPLE__
  363. // /Library/... on Apple
  364. return std::string("/Library/Application Support/ZeroTier/One");
  365. #else
  366. #ifdef __FreeBSD__
  367. // FreeBSD likes /var/db instead of /var/lib
  368. return std::string("/var/db/zerotier-one");
  369. #else
  370. // Use /var/lib for Linux and other *nix
  371. return std::string("/var/lib/zerotier-one");
  372. #endif
  373. #endif
  374. #else // not __UNIX_LIKE__
  375. #ifdef __WINDOWS__
  376. // Look up app data folder on Windows, e.g. C:\ProgramData\...
  377. char buf[16384];
  378. if (SUCCEEDED(SHGetFolderPathA(NULL,CSIDL_COMMON_APPDATA,NULL,0,buf)))
  379. return (std::string(buf) + "\\ZeroTier\\One");
  380. else return std::string("C:\\ZeroTier\\One");
  381. #else
  382. return std::string(); // UNKNOWN PLATFORM
  383. #endif
  384. #endif // __UNIX_LIKE__ or not...
  385. }
  386. One *One::newInstance(const char *hp,unsigned int port,NetworkConfigMaster *master,const char *overrideRootTopology) { return new OneImpl(hp,port,master,overrideRootTopology); }
  387. One::~One() {}
  388. } // namespace ZeroTier