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