Node.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2026-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. #include <stdint.h>
  18. #include "../version.h"
  19. #include "Constants.hpp"
  20. #include "SharedPtr.hpp"
  21. #include "Node.hpp"
  22. #include "RuntimeEnvironment.hpp"
  23. #include "NetworkController.hpp"
  24. #include "Switch.hpp"
  25. #include "Multicaster.hpp"
  26. #include "Topology.hpp"
  27. #include "Buffer.hpp"
  28. #include "Packet.hpp"
  29. #include "Address.hpp"
  30. #include "Identity.hpp"
  31. #include "SelfAwareness.hpp"
  32. #include "Network.hpp"
  33. #include "Trace.hpp"
  34. #include "Metrics.hpp"
  35. #include "PacketMultiplexer.hpp"
  36. // FIXME: remove this suppression and actually fix warnings
  37. #ifdef __GNUC__
  38. #pragma GCC diagnostic ignored "-Wsign-compare"
  39. #endif
  40. namespace ZeroTier {
  41. /****************************************************************************/
  42. /* Public Node interface (C++, exposed via CAPI bindings) */
  43. /****************************************************************************/
  44. Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now) :
  45. _RR(this),
  46. RR(&_RR),
  47. _uPtr(uptr),
  48. _networks(8),
  49. _now(now),
  50. _lastPingCheck(0),
  51. _lastGratuitousPingCheck(0),
  52. _lastHousekeepingRun(0),
  53. _lastMemoizedTraceSettings(0),
  54. _lowBandwidthMode(false)
  55. {
  56. if (callbacks->version != 0) {
  57. throw ZT_EXCEPTION_INVALID_ARGUMENT;
  58. }
  59. memcpy(&_cb,callbacks,sizeof(ZT_Node_Callbacks));
  60. // Initialize non-cryptographic PRNG from a good random source
  61. Utils::getSecureRandom((void *)_prngState,sizeof(_prngState));
  62. _online = false;
  63. memset(_expectingRepliesToBucketPtr,0,sizeof(_expectingRepliesToBucketPtr));
  64. memset(_expectingRepliesTo,0,sizeof(_expectingRepliesTo));
  65. memset(_lastIdentityVerification,0,sizeof(_lastIdentityVerification));
  66. memset((void *)(&_stats),0,sizeof(_stats));
  67. uint64_t idtmp[2];
  68. idtmp[0] = 0;
  69. idtmp[1] = 0;
  70. char tmp[2048];
  71. int n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,tmp,sizeof(tmp) - 1);
  72. if (n > 0) {
  73. tmp[n] = (char)0;
  74. if (RR->identity.fromString(tmp)) {
  75. RR->identity.toString(false,RR->publicIdentityStr);
  76. RR->identity.toString(true,RR->secretIdentityStr);
  77. } else {
  78. throw ZT_EXCEPTION_INVALID_IDENTITY;
  79. }
  80. if (!RR->identity.locallyValidate()) {
  81. throw ZT_EXCEPTION_INVALID_IDENTITY;
  82. }
  83. }
  84. if (n <= 0) {
  85. RR->identity.generate();
  86. RR->identity.toString(false,RR->publicIdentityStr);
  87. RR->identity.toString(true,RR->secretIdentityStr);
  88. idtmp[0] = RR->identity.address().toInt();
  89. idtmp[1] = 0;
  90. stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,RR->secretIdentityStr,(unsigned int)strlen(RR->secretIdentityStr));
  91. stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
  92. } else {
  93. idtmp[0] = RR->identity.address().toInt();
  94. idtmp[1] = 0;
  95. n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,tmp,sizeof(tmp) - 1);
  96. if ((n > 0)&&(n < (int)sizeof(RR->publicIdentityStr))&&(n < (int)sizeof(tmp))) {
  97. if (memcmp(tmp,RR->publicIdentityStr,n)) {
  98. stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
  99. }
  100. }
  101. }
  102. char *m = (char *)0;
  103. try {
  104. const unsigned long ts = sizeof(Trace) + (((sizeof(Trace) & 0xf) != 0) ? (16 - (sizeof(Trace) & 0xf)) : 0);
  105. const unsigned long sws = sizeof(Switch) + (((sizeof(Switch) & 0xf) != 0) ? (16 - (sizeof(Switch) & 0xf)) : 0);
  106. const unsigned long mcs = sizeof(Multicaster) + (((sizeof(Multicaster) & 0xf) != 0) ? (16 - (sizeof(Multicaster) & 0xf)) : 0);
  107. const unsigned long topologys = sizeof(Topology) + (((sizeof(Topology) & 0xf) != 0) ? (16 - (sizeof(Topology) & 0xf)) : 0);
  108. const unsigned long sas = sizeof(SelfAwareness) + (((sizeof(SelfAwareness) & 0xf) != 0) ? (16 - (sizeof(SelfAwareness) & 0xf)) : 0);
  109. const unsigned long bcs = sizeof(Bond) + (((sizeof(Bond) & 0xf) != 0) ? (16 - (sizeof(Bond) & 0xf)) : 0);
  110. const unsigned long pms = sizeof(PacketMultiplexer) + (((sizeof(PacketMultiplexer) & 0xf) != 0) ? (16 - (sizeof(PacketMultiplexer) & 0xf)) : 0);
  111. m = reinterpret_cast<char *>(::malloc(16 + ts + sws + mcs + topologys + sas + bcs + pms));
  112. if (!m) {
  113. throw std::bad_alloc();
  114. }
  115. RR->rtmem = m;
  116. while (((uintptr_t)m & 0xf) != 0) {
  117. ++m;
  118. }
  119. RR->t = new (m) Trace(RR);
  120. m += ts;
  121. RR->sw = new (m) Switch(RR);
  122. m += sws;
  123. RR->mc = new (m) Multicaster(RR);
  124. m += mcs;
  125. RR->topology = new (m) Topology(RR,tptr);
  126. m += topologys;
  127. RR->sa = new (m) SelfAwareness(RR);
  128. m += sas;
  129. RR->bc = new (m) Bond(RR);
  130. m += bcs;
  131. RR->pm = new (m) PacketMultiplexer(RR);
  132. } catch ( ... ) {
  133. if (RR->sa) {
  134. RR->sa->~SelfAwareness();
  135. }
  136. if (RR->topology) {
  137. RR->topology->~Topology();
  138. }
  139. if (RR->mc) {
  140. RR->mc->~Multicaster();
  141. }
  142. if (RR->sw) {
  143. RR->sw->~Switch();
  144. }
  145. if (RR->t) {
  146. RR->t->~Trace();
  147. }
  148. if (RR->bc) {
  149. RR->bc->~Bond();
  150. }
  151. if (RR->pm) {
  152. RR->pm->~PacketMultiplexer();
  153. }
  154. ::free(m);
  155. throw;
  156. }
  157. postEvent(tptr,ZT_EVENT_UP);
  158. }
  159. Node::~Node()
  160. {
  161. {
  162. Mutex::Lock _l(_networks_m);
  163. _networks.clear(); // destroy all networks before shutdown
  164. }
  165. if (RR->sa) {
  166. RR->sa->~SelfAwareness();
  167. }
  168. if (RR->topology) {
  169. RR->topology->~Topology();
  170. }
  171. if (RR->mc) {
  172. RR->mc->~Multicaster();
  173. }
  174. if (RR->sw) {
  175. RR->sw->~Switch();
  176. }
  177. if (RR->t) {
  178. RR->t->~Trace();
  179. }
  180. if (RR->bc) {
  181. RR->bc->~Bond();
  182. }
  183. if (RR->pm) {
  184. RR->pm->~PacketMultiplexer();
  185. }
  186. ::free(RR->rtmem);
  187. }
  188. ZT_ResultCode Node::processWirePacket(
  189. void *tptr,
  190. int64_t now,
  191. int64_t localSocket,
  192. const struct sockaddr_storage *remoteAddress,
  193. const void *packetData,
  194. unsigned int packetLength,
  195. volatile int64_t *nextBackgroundTaskDeadline)
  196. {
  197. _now = now;
  198. RR->sw->onRemotePacket(tptr,localSocket,*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
  199. return ZT_RESULT_OK;
  200. }
  201. ZT_ResultCode Node::processVirtualNetworkFrame(
  202. void *tptr,
  203. int64_t now,
  204. uint64_t nwid,
  205. uint64_t sourceMac,
  206. uint64_t destMac,
  207. unsigned int etherType,
  208. unsigned int vlanId,
  209. const void *frameData,
  210. unsigned int frameLength,
  211. volatile int64_t *nextBackgroundTaskDeadline)
  212. {
  213. _now = now;
  214. SharedPtr<Network> nw(this->network(nwid));
  215. if (nw) {
  216. RR->sw->onLocalEthernet(tptr,nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength);
  217. return ZT_RESULT_OK;
  218. } else {
  219. return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
  220. }
  221. }
  222. void Node::initMultithreading(unsigned int concurrency, bool cpuPinningEnabled)
  223. {
  224. RR->pm->setUpPostDecodeReceiveThreads(concurrency, cpuPinningEnabled);
  225. }
  226. // Closure used to ping upstream and active/online peers
  227. class _PingPeersThatNeedPing
  228. {
  229. public:
  230. _PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &alwaysContact,int64_t now) :
  231. RR(renv),
  232. _tPtr(tPtr),
  233. _alwaysContact(alwaysContact),
  234. _now(now),
  235. _bestCurrentUpstream(RR->topology->getUpstreamPeer())
  236. {
  237. }
  238. inline void operator()(Topology &t,const SharedPtr<Peer> &p)
  239. {
  240. const std::vector<InetAddress> *const alwaysContactEndpoints = _alwaysContact.get(p->address());
  241. if (alwaysContactEndpoints) {
  242. ZT_PeerRole role = RR->topology->role(p->address());
  243. // Contact upstream peers as infrequently as possible
  244. int roleBasedTimerScale = (role == ZT_PEER_ROLE_LEAF) ? 2 : 16;
  245. // Unless we don't any have paths to the roots, then we shouldn't wait a long time to contact them
  246. bool hasPaths = p->paths(RR->node->now()).size() > 0;
  247. roleBasedTimerScale = (role != ZT_PEER_ROLE_LEAF && !hasPaths) ? 0 : roleBasedTimerScale;
  248. if ((RR->node->now() - p->lastSentFullHello()) <= (ZT_PATH_HEARTBEAT_PERIOD * roleBasedTimerScale)) {
  249. return;
  250. }
  251. const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now);
  252. bool contacted = (sent != 0);
  253. if ((sent & 0x1) == 0) { // bit 0x1 == IPv4 sent
  254. for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)alwaysContactEndpoints->size();++k) {
  255. const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()];
  256. if (addr.ss_family == AF_INET) {
  257. p->sendHELLO(_tPtr,-1,addr,_now);
  258. contacted = true;
  259. break;
  260. }
  261. }
  262. }
  263. if ((sent & 0x2) == 0) { // bit 0x2 == IPv6 sent
  264. for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)alwaysContactEndpoints->size();++k) {
  265. const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()];
  266. if (addr.ss_family == AF_INET6) {
  267. p->sendHELLO(_tPtr,-1,addr,_now);
  268. contacted = true;
  269. break;
  270. }
  271. }
  272. }
  273. if ((!contacted)&&(_bestCurrentUpstream)) {
  274. const SharedPtr<Path> up(_bestCurrentUpstream->getAppropriatePath(_now,true));
  275. if (up) {
  276. p->sendHELLO(_tPtr,up->localSocket(),up->address(),_now);
  277. }
  278. }
  279. _alwaysContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain
  280. } else if (p->isActive(_now)) {
  281. p->doPingAndKeepalive(_tPtr,_now);
  282. }
  283. }
  284. private:
  285. const RuntimeEnvironment *RR;
  286. void *_tPtr;
  287. Hashtable< Address,std::vector<InetAddress> > &_alwaysContact;
  288. const int64_t _now;
  289. const SharedPtr<Peer> _bestCurrentUpstream;
  290. };
  291. ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline)
  292. {
  293. _now = now;
  294. Mutex::Lock bl(_backgroundTasksLock);
  295. // Process background bond tasks
  296. unsigned long bondCheckInterval = ZT_PING_CHECK_INTERVAL;
  297. if (RR->bc->inUse()) {
  298. bondCheckInterval = std::max(RR->bc->minReqMonitorInterval(), ZT_CORE_TIMER_TASK_GRANULARITY);
  299. if ((now - _lastGratuitousPingCheck) >= ZT_CORE_TIMER_TASK_GRANULARITY) {
  300. _lastGratuitousPingCheck = now;
  301. RR->bc->processBackgroundTasks(tptr, now);
  302. }
  303. }
  304. unsigned long timeUntilNextPingCheck = _lowBandwidthMode ? (ZT_PING_CHECK_INTERVAL * 5) : ZT_PING_CHECK_INTERVAL;
  305. const int64_t timeSinceLastPingCheck = now - _lastPingCheck;
  306. if (timeSinceLastPingCheck >= timeUntilNextPingCheck) {
  307. try {
  308. _lastPingCheck = now;
  309. // Get designated VL1 upstreams
  310. Hashtable< Address,std::vector<InetAddress> > alwaysContact;
  311. RR->topology->getUpstreamsToContact(alwaysContact);
  312. // Uncomment to dump stats
  313. /*
  314. for(unsigned int i=0;i<32;i++) {
  315. if (_stats.inVerbCounts[i] > 0)
  316. printf("%.2x\t%12lld %lld\n",i,(unsigned long long)_stats.inVerbCounts[i],(unsigned long long)_stats.inVerbBytes[i]);
  317. }
  318. printf("\n");
  319. */
  320. // Check last receive time on designated upstreams to see if we seem to be online
  321. int64_t lastReceivedFromUpstream = 0;
  322. {
  323. Hashtable< Address,std::vector<InetAddress> >::Iterator i(alwaysContact);
  324. Address *upstreamAddress = (Address *)0;
  325. std::vector<InetAddress> *upstreamStableEndpoints = (std::vector<InetAddress> *)0;
  326. while (i.next(upstreamAddress,upstreamStableEndpoints)) {
  327. SharedPtr<Peer> p(RR->topology->getPeerNoCache(*upstreamAddress));
  328. if (p) {
  329. lastReceivedFromUpstream = std::max(p->lastReceive(),lastReceivedFromUpstream);
  330. }
  331. }
  332. }
  333. // Clean up any old local controller auth memorizations.
  334. {
  335. _localControllerAuthorizations_m.lock();
  336. Hashtable< _LocalControllerAuth,int64_t >::Iterator i(_localControllerAuthorizations);
  337. _LocalControllerAuth *k = (_LocalControllerAuth *)0;
  338. int64_t *v = (int64_t *)0;
  339. while (i.next(k,v)) {
  340. if ((*v - now) > (ZT_NETWORK_AUTOCONF_DELAY * 3)) {
  341. _localControllerAuthorizations.erase(*k);
  342. }
  343. }
  344. _localControllerAuthorizations_m.unlock();
  345. }
  346. // Get peers we should stay connected to according to network configs
  347. // Also get networks and whether they need config so we only have to do one pass over networks
  348. int timerScale = _lowBandwidthMode ? 64 : 1;
  349. std::vector< std::pair< SharedPtr<Network>,bool > > networkConfigNeeded;
  350. {
  351. Mutex::Lock l(_networks_m);
  352. Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
  353. uint64_t *nwid = (uint64_t *)0;
  354. SharedPtr<Network> *network = (SharedPtr<Network> *)0;
  355. while (i.next(nwid,network)) {
  356. (*network)->config().alwaysContactAddresses(alwaysContact);
  357. networkConfigNeeded.push_back( std::pair< SharedPtr<Network>,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY * timerScale)||(!(*network)->hasConfig()))) );
  358. }
  359. }
  360. // Ping active peers, upstreams, and others that we should always contact
  361. _PingPeersThatNeedPing pfunc(RR,tptr,alwaysContact,now);
  362. RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc);
  363. // Run WHOIS to create Peer for alwaysContact addresses that could not be contacted
  364. {
  365. Hashtable< Address,std::vector<InetAddress> >::Iterator i(alwaysContact);
  366. Address *upstreamAddress = (Address *)0;
  367. std::vector<InetAddress> *upstreamStableEndpoints = (std::vector<InetAddress> *)0;
  368. while (i.next(upstreamAddress,upstreamStableEndpoints)) {
  369. RR->sw->requestWhois(tptr,now,*upstreamAddress);
  370. }
  371. }
  372. // Refresh network config or broadcast network updates to members as needed
  373. for(std::vector< std::pair< SharedPtr<Network>,bool > >::const_iterator n(networkConfigNeeded.begin());n!=networkConfigNeeded.end();++n) {
  374. if (n->second) {
  375. n->first->requestConfiguration(tptr);
  376. }
  377. if (! _lowBandwidthMode) {
  378. n->first->sendUpdatesToMembers(tptr);
  379. }
  380. }
  381. // Update online status, post status change as event
  382. const bool oldOnline = _online;
  383. _online = (((now - lastReceivedFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT)||(RR->topology->amUpstream()));
  384. if (oldOnline != _online) {
  385. postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
  386. }
  387. } catch ( ... ) {
  388. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  389. }
  390. } else {
  391. timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck;
  392. }
  393. if ((now - _lastMemoizedTraceSettings) >= (ZT_HOUSEKEEPING_PERIOD / 4)) {
  394. _lastMemoizedTraceSettings = now;
  395. RR->t->updateMemoizedSettings();
  396. }
  397. if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) {
  398. _lastHousekeepingRun = now;
  399. try {
  400. RR->topology->doPeriodicTasks(tptr,now);
  401. RR->sa->clean(now);
  402. RR->mc->clean(now);
  403. } catch ( ... ) {
  404. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  405. }
  406. }
  407. try {
  408. *nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(bondCheckInterval,std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(tptr,now))),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
  409. } catch ( ... ) {
  410. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  411. }
  412. return ZT_RESULT_OK;
  413. }
  414. ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
  415. {
  416. Mutex::Lock _l(_networks_m);
  417. SharedPtr<Network> &nw = _networks[nwid];
  418. if (!nw) {
  419. nw = SharedPtr<Network>(new Network(RR,tptr,nwid,uptr,(const NetworkConfig *)0));
  420. }
  421. return ZT_RESULT_OK;
  422. }
  423. ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
  424. {
  425. ZT_VirtualNetworkConfig ctmp;
  426. void **nUserPtr = (void **)0;
  427. {
  428. Mutex::Lock _l(_networks_m);
  429. SharedPtr<Network> *nw = _networks.get(nwid);
  430. RR->sw->removeNetworkQoSControlBlock(nwid);
  431. if (!nw) {
  432. return ZT_RESULT_OK;
  433. }
  434. if (uptr) {
  435. *uptr = (*nw)->userPtr();
  436. }
  437. (*nw)->externalConfig(&ctmp);
  438. (*nw)->destroy();
  439. nUserPtr = (*nw)->userPtr();
  440. }
  441. if (nUserPtr) {
  442. RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
  443. }
  444. {
  445. Mutex::Lock _l(_networks_m);
  446. _networks.erase(nwid);
  447. }
  448. uint64_t tmp[2];
  449. tmp[0] = nwid;
  450. tmp[1] = 0;
  451. RR->node->stateObjectDelete(tptr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp);
  452. return ZT_RESULT_OK;
  453. }
  454. ZT_ResultCode Node::multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
  455. {
  456. SharedPtr<Network> nw(this->network(nwid));
  457. if (nw) {
  458. nw->multicastSubscribe(tptr,MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
  459. return ZT_RESULT_OK;
  460. } else {
  461. return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
  462. }
  463. }
  464. ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
  465. {
  466. SharedPtr<Network> nw(this->network(nwid));
  467. if (nw) {
  468. nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
  469. return ZT_RESULT_OK;
  470. } else {
  471. return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
  472. }
  473. }
  474. ZT_ResultCode Node::orbit(void *tptr,uint64_t moonWorldId,uint64_t moonSeed)
  475. {
  476. RR->topology->addMoon(tptr,moonWorldId,Address(moonSeed));
  477. return ZT_RESULT_OK;
  478. }
  479. ZT_ResultCode Node::deorbit(void *tptr,uint64_t moonWorldId)
  480. {
  481. RR->topology->removeMoon(tptr,moonWorldId);
  482. return ZT_RESULT_OK;
  483. }
  484. uint64_t Node::address() const
  485. {
  486. return RR->identity.address().toInt();
  487. }
  488. void Node::status(ZT_NodeStatus *status) const
  489. {
  490. status->address = RR->identity.address().toInt();
  491. status->publicIdentity = RR->publicIdentityStr;
  492. status->secretIdentity = RR->secretIdentityStr;
  493. status->online = _online ? 1 : 0;
  494. }
  495. ZT_PeerList *Node::peers() const
  496. {
  497. std::vector< std::pair< Address,SharedPtr<Peer> > > peers(RR->topology->allPeers());
  498. std::sort(peers.begin(),peers.end());
  499. char *buf = (char *)::malloc(sizeof(ZT_PeerList) + (sizeof(ZT_Peer) * peers.size()));
  500. if (!buf) {
  501. return (ZT_PeerList *)0;
  502. }
  503. ZT_PeerList *pl = (ZT_PeerList *)buf;
  504. pl->peers = (ZT_Peer *)(buf + sizeof(ZT_PeerList));
  505. pl->peerCount = 0;
  506. for(std::vector< std::pair< Address,SharedPtr<Peer> > >::iterator pi(peers.begin());pi!=peers.end();++pi) {
  507. ZT_Peer *p = &(pl->peers[pl->peerCount++]);
  508. p->address = pi->second->address().toInt();
  509. p->isBonded = 0;
  510. if (pi->second->remoteVersionKnown()) {
  511. p->versionMajor = pi->second->remoteVersionMajor();
  512. p->versionMinor = pi->second->remoteVersionMinor();
  513. p->versionRev = pi->second->remoteVersionRevision();
  514. } else {
  515. p->versionMajor = -1;
  516. p->versionMinor = -1;
  517. p->versionRev = -1;
  518. }
  519. p->latency = pi->second->latency(_now);
  520. if (p->latency >= 0xffff) {
  521. p->latency = -1;
  522. }
  523. p->role = RR->topology->role(pi->second->identity().address());
  524. std::vector< SharedPtr<Path> > paths(pi->second->paths(_now));
  525. SharedPtr<Path> bestp(pi->second->getAppropriatePath(_now,false));
  526. p->pathCount = 0;
  527. for(std::vector< SharedPtr<Path> >::iterator path(paths.begin());path!=paths.end();++path) {
  528. if((*path)->valid()) {
  529. memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
  530. p->paths[p->pathCount].localSocket = (*path)->localSocket();
  531. p->paths[p->pathCount].localPort = (*path)->localPort();
  532. p->paths[p->pathCount].lastSend = (*path)->lastOut();
  533. p->paths[p->pathCount].lastReceive = (*path)->lastIn();
  534. p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
  535. p->paths[p->pathCount].expired = 0;
  536. p->paths[p->pathCount].preferred = ((*path) == bestp) ? 1 : 0;
  537. p->paths[p->pathCount].scope = (*path)->ipScope();
  538. if (pi->second->bond()) {
  539. p->paths[p->pathCount].latencyMean = (*path)->latencyMean();
  540. p->paths[p->pathCount].latencyVariance = (*path)->latencyVariance();
  541. p->paths[p->pathCount].packetLossRatio = (*path)->packetLossRatio();
  542. p->paths[p->pathCount].packetErrorRatio = (*path)->packetErrorRatio();
  543. p->paths[p->pathCount].assignedFlowCount = (*path)->assignedFlowCount();
  544. p->paths[p->pathCount].relativeQuality = (*path)->relativeQuality();
  545. p->paths[p->pathCount].linkSpeed = (*path)->givenLinkSpeed();
  546. p->paths[p->pathCount].bonded = (*path)->bonded();
  547. p->paths[p->pathCount].eligible = (*path)->eligible();
  548. std::string ifname = std::string((*path)->ifname());
  549. memset(p->paths[p->pathCount].ifname, 0x0, std::min((int)ifname.length() + 1, ZT_MAX_PHYSIFNAME));
  550. memcpy(p->paths[p->pathCount].ifname, ifname.c_str(), std::min((int)ifname.length(), ZT_MAX_PHYSIFNAME));
  551. }
  552. ++p->pathCount;
  553. }
  554. }
  555. if (pi->second->bond()) {
  556. p->isBonded = pi->second->bond();
  557. p->bondingPolicy = pi->second->bondingPolicy();
  558. p->numAliveLinks = pi->second->getNumAliveLinks();
  559. p->numTotalLinks = pi->second->getNumTotalLinks();
  560. }
  561. }
  562. return pl;
  563. }
  564. ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
  565. {
  566. Mutex::Lock _l(_networks_m);
  567. const SharedPtr<Network> *nw = _networks.get(nwid);
  568. if (nw) {
  569. ZT_VirtualNetworkConfig *nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig));
  570. (*nw)->externalConfig(nc);
  571. return nc;
  572. }
  573. return (ZT_VirtualNetworkConfig *)0;
  574. }
  575. ZT_VirtualNetworkList *Node::networks() const
  576. {
  577. Mutex::Lock _l(_networks_m);
  578. char *buf = (char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * _networks.size()));
  579. if (!buf) {
  580. return (ZT_VirtualNetworkList *)0;
  581. }
  582. ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf;
  583. nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList));
  584. nl->networkCount = 0;
  585. Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(*const_cast< Hashtable< uint64_t,SharedPtr<Network> > *>(&_networks));
  586. uint64_t *k = (uint64_t *)0;
  587. SharedPtr<Network> *v = (SharedPtr<Network> *)0;
  588. while (i.next(k,v)) {
  589. (*v)->externalConfig(&(nl->networks[nl->networkCount++]));
  590. }
  591. return nl;
  592. }
  593. void Node::freeQueryResult(void *qr)
  594. {
  595. if (qr) {
  596. ::free(qr);
  597. }
  598. }
  599. int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr)
  600. {
  601. if (Path::isAddressValidForPath(*(reinterpret_cast<const InetAddress *>(addr)))) {
  602. Mutex::Lock _l(_directPaths_m);
  603. if (std::find(_directPaths.begin(),_directPaths.end(),*(reinterpret_cast<const InetAddress *>(addr))) == _directPaths.end()) {
  604. _directPaths.push_back(*(reinterpret_cast<const InetAddress *>(addr)));
  605. return 1;
  606. }
  607. }
  608. return 0;
  609. }
  610. void Node::clearLocalInterfaceAddresses()
  611. {
  612. Mutex::Lock _l(_directPaths_m);
  613. _directPaths.clear();
  614. }
  615. int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
  616. {
  617. try {
  618. if (RR->identity.address().toInt() != dest) {
  619. Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE);
  620. outp.append(typeId);
  621. outp.append(data,len);
  622. outp.compress();
  623. RR->sw->send(tptr,outp,true);
  624. return 1;
  625. }
  626. } catch ( ... ) {}
  627. return 0;
  628. }
  629. void Node::setNetconfMaster(void *networkControllerInstance)
  630. {
  631. RR->localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
  632. if (networkControllerInstance) {
  633. RR->localNetworkController->init(RR->identity, this);
  634. }
  635. }
  636. /****************************************************************************/
  637. /* Node methods used only within node/ */
  638. /****************************************************************************/
  639. bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress)
  640. {
  641. if (!Path::isAddressValidForPath(remoteAddress)) {
  642. return false;
  643. }
  644. if (RR->topology->isProhibitedEndpoint(ztaddr,remoteAddress)) {
  645. return false;
  646. }
  647. {
  648. Mutex::Lock _l(_networks_m);
  649. Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
  650. uint64_t *k = (uint64_t *)0;
  651. SharedPtr<Network> *v = (SharedPtr<Network> *)0;
  652. while (i.next(k,v)) {
  653. if ((*v)->hasConfig()) {
  654. for(unsigned int k=0;k<(*v)->config().staticIpCount;++k) {
  655. if ((*v)->config().staticIps[k].containsAddress(remoteAddress)) {
  656. return false;
  657. }
  658. }
  659. }
  660. }
  661. }
  662. return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
  663. }
  664. uint64_t Node::prng()
  665. {
  666. // https://en.wikipedia.org/wiki/Xorshift#xorshift.2B
  667. uint64_t x = _prngState[0];
  668. const uint64_t y = _prngState[1];
  669. _prngState[0] = y;
  670. x ^= x << 23;
  671. const uint64_t z = x ^ y ^ (x >> 17) ^ (y >> 26);
  672. _prngState[1] = z;
  673. return z + y;
  674. }
  675. ZT_ResultCode Node::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork, const ZT_PhysicalPathConfiguration *pathConfig)
  676. {
  677. RR->topology->setPhysicalPathConfiguration(pathNetwork,pathConfig);
  678. return ZT_RESULT_OK;
  679. }
  680. World Node::planet() const
  681. {
  682. return RR->topology->planet();
  683. }
  684. std::vector<World> Node::moons() const
  685. {
  686. return RR->topology->moons();
  687. }
  688. void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig)
  689. {
  690. _localControllerAuthorizations_m.lock();
  691. _localControllerAuthorizations[_LocalControllerAuth(nwid,destination)] = now();
  692. _localControllerAuthorizations_m.unlock();
  693. if (destination == RR->identity.address()) {
  694. SharedPtr<Network> n(network(nwid));
  695. if (!n) {
  696. return;
  697. }
  698. n->setConfiguration((void *)0,nc,true);
  699. } else {
  700. Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
  701. try {
  702. if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) {
  703. uint64_t configUpdateId = prng();
  704. if (!configUpdateId) {
  705. ++configUpdateId;
  706. }
  707. const unsigned int totalSize = dconf->sizeBytes();
  708. unsigned int chunkIndex = 0;
  709. while (chunkIndex < totalSize) {
  710. const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
  711. Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG);
  712. if (requestPacketId) {
  713. outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
  714. outp.append(requestPacketId);
  715. }
  716. const unsigned int sigStart = outp.size();
  717. outp.append(nwid);
  718. outp.append((uint16_t)chunkLen);
  719. outp.append((const void *)(dconf->data() + chunkIndex),chunkLen);
  720. outp.append((uint8_t)0); // no flags
  721. outp.append((uint64_t)configUpdateId);
  722. outp.append((uint32_t)totalSize);
  723. outp.append((uint32_t)chunkIndex);
  724. C25519::Signature sig(RR->identity.sign(reinterpret_cast<const uint8_t *>(outp.data()) + sigStart,outp.size() - sigStart));
  725. outp.append((uint8_t)1);
  726. outp.append((uint16_t)ZT_C25519_SIGNATURE_LEN);
  727. outp.append(sig.data,ZT_C25519_SIGNATURE_LEN);
  728. outp.compress();
  729. RR->sw->send((void *)0,outp,true);
  730. chunkIndex += chunkLen;
  731. }
  732. }
  733. delete dconf;
  734. } catch ( ... ) {
  735. delete dconf;
  736. throw;
  737. }
  738. }
  739. }
  740. void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
  741. {
  742. if (destination == RR->identity.address()) {
  743. SharedPtr<Network> n(network(rev.networkId()));
  744. if (!n) {
  745. return;
  746. }
  747. n->addCredential((void *)0,RR->identity.address(),rev);
  748. } else {
  749. Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
  750. outp.append((uint8_t)0x00);
  751. outp.append((uint16_t)0);
  752. outp.append((uint16_t)0);
  753. outp.append((uint16_t)1);
  754. rev.serialize(outp);
  755. outp.append((uint16_t)0);
  756. RR->sw->send((void *)0,outp,true);
  757. }
  758. }
  759. void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode, const void *errorData, unsigned int errorDataSize)
  760. {
  761. if (destination == RR->identity.address()) {
  762. SharedPtr<Network> n(network(nwid));
  763. if (!n) {
  764. return;
  765. }
  766. switch(errorCode) {
  767. case NetworkController::NC_ERROR_OBJECT_NOT_FOUND:
  768. case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR:
  769. n->setNotFound(nullptr);
  770. break;
  771. case NetworkController::NC_ERROR_ACCESS_DENIED:
  772. n->setAccessDenied(nullptr);
  773. break;
  774. case NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED: {
  775. //fprintf(stderr, "\n\nGot auth required\n\n");
  776. break;
  777. }
  778. default:
  779. break;
  780. }
  781. } else if (requestPacketId) {
  782. Packet outp(destination,RR->identity.address(),Packet::VERB_ERROR);
  783. outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
  784. outp.append(requestPacketId);
  785. switch(errorCode) {
  786. //case NetworkController::NC_ERROR_OBJECT_NOT_FOUND:
  787. //case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR:
  788. default:
  789. outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
  790. Metrics::pkt_error_obj_not_found_out++;
  791. break;
  792. case NetworkController::NC_ERROR_ACCESS_DENIED:
  793. outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
  794. Metrics::pkt_error_network_access_denied_out++;
  795. break;
  796. case NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED:
  797. outp.append((unsigned char)Packet::ERROR_NETWORK_AUTHENTICATION_REQUIRED);
  798. Metrics::pkt_error_authentication_required_out++;
  799. break;
  800. }
  801. outp.append(nwid);
  802. if ((errorData)&&(errorDataSize > 0)&&(errorDataSize <= 0xffff)) {
  803. outp.append((uint16_t)errorDataSize);
  804. outp.append(errorData, errorDataSize);
  805. }
  806. RR->sw->send((void *)0,outp,true);
  807. } // else we can't send an ERROR() in response to nothing, so discard
  808. }
  809. } // namespace ZeroTier
  810. /****************************************************************************/
  811. /* CAPI bindings */
  812. /****************************************************************************/
  813. extern "C" {
  814. enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now)
  815. {
  816. *node = (ZT_Node *)0;
  817. try {
  818. *node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr,tptr,callbacks,now));
  819. return ZT_RESULT_OK;
  820. } catch (std::bad_alloc &exc) {
  821. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  822. } catch (std::runtime_error &exc) {
  823. return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED;
  824. } catch ( ... ) {
  825. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  826. }
  827. }
  828. void ZT_Node_delete(ZT_Node *node)
  829. {
  830. try {
  831. delete (reinterpret_cast<ZeroTier::Node *>(node));
  832. } catch ( ... ) {}
  833. }
  834. enum ZT_ResultCode ZT_Node_processWirePacket(
  835. ZT_Node *node,
  836. void *tptr,
  837. int64_t now,
  838. int64_t localSocket,
  839. const struct sockaddr_storage *remoteAddress,
  840. const void *packetData,
  841. unsigned int packetLength,
  842. volatile int64_t *nextBackgroundTaskDeadline)
  843. {
  844. try {
  845. return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr,now,localSocket,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
  846. } catch (std::bad_alloc &exc) {
  847. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  848. } catch ( ... ) {
  849. return ZT_RESULT_OK; // "OK" since invalid packets are simply dropped, but the system is still up
  850. }
  851. }
  852. enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
  853. ZT_Node *node,
  854. void *tptr,
  855. int64_t now,
  856. uint64_t nwid,
  857. uint64_t sourceMac,
  858. uint64_t destMac,
  859. unsigned int etherType,
  860. unsigned int vlanId,
  861. const void *frameData,
  862. unsigned int frameLength,
  863. volatile int64_t *nextBackgroundTaskDeadline)
  864. {
  865. try {
  866. return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(tptr,now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline);
  867. } catch (std::bad_alloc &exc) {
  868. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  869. } catch ( ... ) {
  870. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  871. }
  872. }
  873. enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline)
  874. {
  875. try {
  876. return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr,now,nextBackgroundTaskDeadline);
  877. } catch (std::bad_alloc &exc) {
  878. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  879. } catch ( ... ) {
  880. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  881. }
  882. }
  883. enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr)
  884. {
  885. try {
  886. return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid,uptr,tptr);
  887. } catch (std::bad_alloc &exc) {
  888. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  889. } catch ( ... ) {
  890. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  891. }
  892. }
  893. enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr)
  894. {
  895. try {
  896. return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid,uptr,tptr);
  897. } catch (std::bad_alloc &exc) {
  898. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  899. } catch ( ... ) {
  900. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  901. }
  902. }
  903. enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
  904. {
  905. try {
  906. return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr,nwid,multicastGroup,multicastAdi);
  907. } catch (std::bad_alloc &exc) {
  908. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  909. } catch ( ... ) {
  910. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  911. }
  912. }
  913. enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
  914. {
  915. try {
  916. return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(nwid,multicastGroup,multicastAdi);
  917. } catch (std::bad_alloc &exc) {
  918. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  919. } catch ( ... ) {
  920. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  921. }
  922. }
  923. enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,uint64_t moonSeed)
  924. {
  925. try {
  926. return reinterpret_cast<ZeroTier::Node *>(node)->orbit(tptr,moonWorldId,moonSeed);
  927. } catch ( ... ) {
  928. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  929. }
  930. }
  931. enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId)
  932. {
  933. try {
  934. return reinterpret_cast<ZeroTier::Node *>(node)->deorbit(tptr,moonWorldId);
  935. } catch ( ... ) {
  936. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  937. }
  938. }
  939. uint64_t ZT_Node_address(ZT_Node *node)
  940. {
  941. return reinterpret_cast<ZeroTier::Node *>(node)->address();
  942. }
  943. void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status)
  944. {
  945. try {
  946. reinterpret_cast<ZeroTier::Node *>(node)->status(status);
  947. } catch ( ... ) {}
  948. }
  949. ZT_PeerList *ZT_Node_peers(ZT_Node *node)
  950. {
  951. try {
  952. return reinterpret_cast<ZeroTier::Node *>(node)->peers();
  953. } catch ( ... ) {
  954. return (ZT_PeerList *)0;
  955. }
  956. }
  957. ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid)
  958. {
  959. try {
  960. return reinterpret_cast<ZeroTier::Node *>(node)->networkConfig(nwid);
  961. } catch ( ... ) {
  962. return (ZT_VirtualNetworkConfig *)0;
  963. }
  964. }
  965. ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
  966. {
  967. try {
  968. return reinterpret_cast<ZeroTier::Node *>(node)->networks();
  969. } catch ( ... ) {
  970. return (ZT_VirtualNetworkList *)0;
  971. }
  972. }
  973. void ZT_Node_freeQueryResult(ZT_Node *node,void *qr)
  974. {
  975. try {
  976. reinterpret_cast<ZeroTier::Node *>(node)->freeQueryResult(qr);
  977. } catch ( ... ) {}
  978. }
  979. int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr)
  980. {
  981. try {
  982. return reinterpret_cast<ZeroTier::Node *>(node)->addLocalInterfaceAddress(addr);
  983. } catch ( ... ) {
  984. return 0;
  985. }
  986. }
  987. void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node)
  988. {
  989. try {
  990. reinterpret_cast<ZeroTier::Node *>(node)->clearLocalInterfaceAddresses();
  991. } catch ( ... ) {}
  992. }
  993. int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
  994. {
  995. try {
  996. return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(tptr,dest,typeId,data,len);
  997. } catch ( ... ) {
  998. return 0;
  999. }
  1000. }
  1001. void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance)
  1002. {
  1003. try {
  1004. reinterpret_cast<ZeroTier::Node *>(node)->setNetconfMaster(networkControllerInstance);
  1005. } catch ( ... ) {}
  1006. }
  1007. enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node,const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
  1008. {
  1009. try {
  1010. return reinterpret_cast<ZeroTier::Node *>(node)->setPhysicalPathConfiguration(pathNetwork,pathConfig);
  1011. } catch ( ... ) {
  1012. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  1013. }
  1014. }
  1015. void ZT_version(int *major,int *minor,int *revision)
  1016. {
  1017. if (major) {
  1018. *major = ZEROTIER_ONE_VERSION_MAJOR;
  1019. }
  1020. if (minor) {
  1021. *minor = ZEROTIER_ONE_VERSION_MINOR;
  1022. }
  1023. if (revision) {
  1024. *revision = ZEROTIER_ONE_VERSION_REVISION;
  1025. }
  1026. }
  1027. } // extern "C"