Node.cpp 35 KB

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