GoGlue.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  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: 2024-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 "GoGlue.h"
  14. #include <cstring>
  15. #include <cstdlib>
  16. #include <cerrno>
  17. #include "../../node/Constants.hpp"
  18. #include "../../node/InetAddress.hpp"
  19. #include "../../node/Node.hpp"
  20. #include "../../node/Utils.hpp"
  21. #include "../../node/MAC.hpp"
  22. #include "../../node/Address.hpp"
  23. #include "../../osdep/OSUtils.hpp"
  24. #include "../../osdep/EthernetTap.hpp"
  25. #ifndef __WINDOWS__
  26. #include <unistd.h>
  27. #include <sys/socket.h>
  28. #include <sys/un.h>
  29. #include <arpa/inet.h>
  30. #include <netinet/in.h>
  31. #ifdef __BSD__
  32. #include <net/if.h>
  33. #endif
  34. #ifdef __LINUX__
  35. #ifndef IPV6_DONTFRAG
  36. #define IPV6_DONTFRAG 62
  37. #endif
  38. #endif
  39. #endif // !__WINDOWS__
  40. #include <thread>
  41. #include <mutex>
  42. #include <map>
  43. #include <vector>
  44. #include <set>
  45. #include <memory>
  46. #include <atomic>
  47. #ifdef __WINDOWS__
  48. #define SETSOCKOPT_FLAG_TYPE BOOL
  49. #define SETSOCKOPT_FLAG_TRUE TRUE
  50. #define SETSOCKOPT_FLAG_FALSE FALSE
  51. #else
  52. #define SETSOCKOPT_FLAG_TYPE int
  53. #define SETSOCKOPT_FLAG_TRUE 1
  54. #define SETSOCKOPT_FLAG_FALSE 0
  55. #endif
  56. #ifndef MSG_DONTWAIT
  57. #define MSG_DONTWAIT 0
  58. #endif
  59. using namespace ZeroTier;
  60. struct ZT_GoNodeThread
  61. {
  62. std::string ip;
  63. int port;
  64. int af;
  65. bool primary;
  66. std::atomic<bool> run;
  67. std::thread thr;
  68. };
  69. struct ZT_GoNode_Impl
  70. {
  71. void *goUserPtr;
  72. Node *node;
  73. volatile int64_t nextBackgroundTaskDeadline;
  74. std::string path;
  75. std::atomic<bool> run;
  76. std::map< ZT_SOCKET,ZT_GoNodeThread > threads;
  77. std::mutex threads_l;
  78. std::map< uint64_t,std::shared_ptr<EthernetTap> > taps;
  79. std::mutex taps_l;
  80. std::thread backgroundTaskThread;
  81. };
  82. static const std::string defaultHomePath(OSUtils::platformDefaultHomePath());
  83. const char *ZT_PLATFORM_DEFAULT_HOMEPATH = defaultHomePath.c_str();
  84. /****************************************************************************/
  85. /* These functions are implemented in Go in pkg/zerotier/node.go */
  86. extern "C" int goPathCheckFunc(void *,const ZT_Identity *,int,const void *,int);
  87. extern "C" int goPathLookupFunc(void *,uint64_t,int,const ZT_Identity *,int *,uint8_t [16],int *);
  88. extern "C" void goStateObjectPutFunc(void *,int,const uint64_t [2],const void *,int);
  89. extern "C" int goStateObjectGetFunc(void *,int,const uint64_t [2],void **);
  90. extern "C" void goVirtualNetworkConfigFunc(void *,ZT_GoTap *,uint64_t,int,const ZT_VirtualNetworkConfig *);
  91. extern "C" void goZtEvent(void *,int,const void *);
  92. extern "C" void goHandleTapAddedMulticastGroup(void *,ZT_GoTap *,uint64_t,uint64_t,uint32_t);
  93. extern "C" void goHandleTapRemovedMulticastGroup(void *,ZT_GoTap *,uint64_t,uint64_t,uint32_t);
  94. static void ZT_GoNode_VirtualNetworkConfigFunction(
  95. ZT_Node *node,
  96. void *uptr,
  97. void *tptr,
  98. uint64_t nwid,
  99. void **nptr,
  100. enum ZT_VirtualNetworkConfigOperation op,
  101. const ZT_VirtualNetworkConfig *cfg)
  102. {
  103. goVirtualNetworkConfigFunc(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,reinterpret_cast<ZT_GoTap *>(*nptr),nwid,op,cfg);
  104. }
  105. static void ZT_GoNode_VirtualNetworkFrameFunction(
  106. ZT_Node *node,
  107. void *uptr,
  108. void *tptr,
  109. uint64_t nwid,
  110. void **nptr,
  111. uint64_t srcMac,
  112. uint64_t destMac,
  113. unsigned int etherType,
  114. unsigned int vlanId,
  115. const void *data,
  116. unsigned int len)
  117. {
  118. if (*nptr)
  119. reinterpret_cast<EthernetTap *>(*nptr)->put(MAC(srcMac),MAC(destMac),etherType,data,len);
  120. }
  121. static void ZT_GoNode_EventCallback(
  122. ZT_Node *node,
  123. void *uptr,
  124. void *tptr,
  125. enum ZT_Event et,
  126. const void *data)
  127. {
  128. goZtEvent(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,et,data);
  129. }
  130. static void ZT_GoNode_StatePutFunction(
  131. ZT_Node *node,
  132. void *uptr,
  133. void *tptr,
  134. enum ZT_StateObjectType objType,
  135. const uint64_t id[2],
  136. const void *data,
  137. int len)
  138. {
  139. goStateObjectPutFunc(
  140. reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
  141. objType,
  142. id,
  143. data,
  144. len);
  145. }
  146. static void _freeFunc(void *p) { if (p) free(p); }
  147. static int ZT_GoNode_StateGetFunction(
  148. ZT_Node *node,
  149. void *uptr,
  150. void *tptr,
  151. enum ZT_StateObjectType objType,
  152. const uint64_t id[2],
  153. void **data,
  154. void (**freeFunc)(void *))
  155. {
  156. *freeFunc = &_freeFunc;
  157. return goStateObjectGetFunc(
  158. reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
  159. (int)objType,
  160. id,
  161. data);
  162. }
  163. static ZT_ALWAYS_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *addr,const void *data,const unsigned int len,const unsigned int ipTTL)
  164. {
  165. switch(addr->ss_family) {
  166. case AF_INET:
  167. if ((ipTTL > 0)&&(ipTTL < 255)) {
  168. #ifdef __WINDOWS__
  169. DWORD tmp = (DWORD)ipTTL;
  170. #else
  171. int tmp = (int)ipTTL;
  172. #endif
  173. setsockopt(sock,IPPROTO_IP,IP_TTL,&tmp,sizeof(tmp));
  174. sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in));
  175. tmp = 255;
  176. setsockopt(sock,IPPROTO_IP,IP_TTL,&tmp,sizeof(tmp));
  177. } else {
  178. sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in));
  179. }
  180. break;
  181. case AF_INET6:
  182. // The ipTTL option isn't currently used with IPv6. It's only used
  183. // with IPv4 "firewall opener" / "NAT buster" preamble packets as part
  184. // of IPv4 NAT traversal.
  185. sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in6));
  186. break;
  187. }
  188. }
  189. static int ZT_GoNode_WirePacketSendFunction(
  190. ZT_Node *node,
  191. void *uptr,
  192. void *tptr,
  193. int64_t localSocket,
  194. const struct sockaddr_storage *addr,
  195. const void *data,
  196. unsigned int len,
  197. unsigned int ipTTL)
  198. {
  199. if (localSocket > 0) {
  200. doUdpSend((ZT_SOCKET)localSocket,addr,data,len,ipTTL);
  201. } else {
  202. ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
  203. std::lock_guard<std::mutex> l(gn->threads_l);
  204. for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
  205. if ((t->second.af == addr->ss_family)&&(t->second.primary)) {
  206. doUdpSend(t->first,addr,data,len,ipTTL);
  207. break;
  208. }
  209. }
  210. }
  211. return 0;
  212. }
  213. static int ZT_GoNode_PathCheckFunction(
  214. ZT_Node *node,
  215. void *uptr,
  216. void *tptr,
  217. uint64_t ztAddress,
  218. const ZT_Identity *id,
  219. int64_t localSocket,
  220. const struct sockaddr_storage *sa)
  221. {
  222. switch(sa->ss_family) {
  223. case AF_INET:
  224. return goPathCheckFunc(
  225. reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
  226. id,
  227. AF_INET,
  228. &(reinterpret_cast<const struct sockaddr_in *>(sa)->sin_addr.s_addr),
  229. Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in *>(sa)->sin_port));
  230. case AF_INET6:
  231. return goPathCheckFunc(
  232. reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
  233. id,
  234. AF_INET6,
  235. reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_addr.s6_addr,
  236. Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_port));
  237. }
  238. return 0;
  239. }
  240. static int ZT_GoNode_PathLookupFunction(
  241. ZT_Node *node,
  242. void *uptr,
  243. void *tptr,
  244. uint64_t ztAddress,
  245. const ZT_Identity *id,
  246. int desiredAddressFamily,
  247. struct sockaddr_storage *sa)
  248. {
  249. int family = 0;
  250. uint8_t ip[16];
  251. int port = 0;
  252. const int result = goPathLookupFunc(
  253. reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
  254. ztAddress,
  255. desiredAddressFamily,
  256. id,
  257. &family,
  258. ip,
  259. &port
  260. );
  261. if (result != 0) {
  262. switch(family) {
  263. case AF_INET:
  264. reinterpret_cast<struct sockaddr_in *>(sa)->sin_family = AF_INET;
  265. memcpy(&(reinterpret_cast<struct sockaddr_in *>(sa)->sin_addr.s_addr),ip,4);
  266. reinterpret_cast<struct sockaddr_in *>(sa)->sin_port = Utils::hton((uint16_t)port);
  267. return 1;
  268. case AF_INET6:
  269. reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_family = AF_INET6;
  270. memcpy(reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_addr.s6_addr,ip,16);
  271. reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_port = Utils::hton((uint16_t)port);
  272. return 1;
  273. }
  274. }
  275. return 0;
  276. }
  277. /****************************************************************************/
  278. extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath,uintptr_t userPtr)
  279. {
  280. try {
  281. struct ZT_Node_Callbacks cb;
  282. cb.statePutFunction = &ZT_GoNode_StatePutFunction;
  283. cb.stateGetFunction = &ZT_GoNode_StateGetFunction;
  284. cb.wirePacketSendFunction = &ZT_GoNode_WirePacketSendFunction;
  285. cb.virtualNetworkFrameFunction = &ZT_GoNode_VirtualNetworkFrameFunction;
  286. cb.virtualNetworkConfigFunction = &ZT_GoNode_VirtualNetworkConfigFunction;
  287. cb.eventCallback = &ZT_GoNode_EventCallback;
  288. cb.pathCheckFunction = &ZT_GoNode_PathCheckFunction;
  289. cb.pathLookupFunction = &ZT_GoNode_PathLookupFunction;
  290. ZT_GoNode_Impl *gn = new ZT_GoNode_Impl;
  291. const int64_t now = OSUtils::now();
  292. gn->goUserPtr = reinterpret_cast<void *>(userPtr);
  293. gn->node = new Node(reinterpret_cast<void *>(gn),nullptr,&cb,now);
  294. gn->nextBackgroundTaskDeadline = now;
  295. gn->path = workingPath;
  296. gn->run = true;
  297. gn->backgroundTaskThread = std::thread([gn] {
  298. int64_t lastCheckedTaps = 0;
  299. while (gn->run) {
  300. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  301. const int64_t now = OSUtils::now();
  302. if (now >= gn->nextBackgroundTaskDeadline)
  303. gn->node->processBackgroundTasks(nullptr,now,&(gn->nextBackgroundTaskDeadline));
  304. if ((now - lastCheckedTaps) > 10000) {
  305. lastCheckedTaps = now;
  306. std::vector<MulticastGroup> added,removed;
  307. std::lock_guard<std::mutex> tl(gn->taps_l);
  308. for(auto t=gn->taps.begin();t!=gn->taps.end();++t) {
  309. added.clear();
  310. removed.clear();
  311. t->second->scanMulticastGroups(added,removed);
  312. for(auto g=added.begin();g!=added.end();++g)
  313. goHandleTapAddedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
  314. for(auto g=removed.begin();g!=removed.end();++g)
  315. goHandleTapRemovedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
  316. t->second->syncRoutes();
  317. }
  318. }
  319. }
  320. });
  321. return gn;
  322. } catch ( ... ) {
  323. fprintf(stderr,"FATAL: unable to create new instance of Node (out of memory?)" ZT_EOL_S);
  324. exit(1);
  325. }
  326. }
  327. extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
  328. {
  329. gn->run = false;
  330. gn->threads_l.lock();
  331. for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
  332. t->second.run = false;
  333. shutdown(t->first,SHUT_RDWR);
  334. close(t->first);
  335. t->second.thr.join();
  336. }
  337. gn->threads_l.unlock();
  338. gn->taps_l.lock();
  339. for(auto t=gn->taps.begin();t!=gn->taps.end();++t)
  340. gn->node->leave(t->first,nullptr,nullptr);
  341. gn->taps.clear();
  342. gn->taps_l.unlock();
  343. gn->backgroundTaskThread.join();
  344. gn->node->shutdown(nullptr);
  345. delete gn->node;
  346. delete gn;
  347. }
  348. extern "C" ZT_Node *ZT_GoNode_getNode(ZT_GoNode *gn)
  349. {
  350. return gn->node;
  351. }
  352. // Sets flags and socket options common to both IPv4 and IPv6 UDP sockets
  353. static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
  354. {
  355. int bufSize = 1048576;
  356. while (bufSize > 131072) {
  357. if (setsockopt(udpSock,SOL_SOCKET,SO_RCVBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
  358. break;
  359. bufSize -= 131072;
  360. }
  361. bufSize = 1048576;
  362. while (bufSize > 131072) {
  363. if (setsockopt(udpSock,SOL_SOCKET,SO_SNDBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
  364. break;
  365. bufSize -= 131072;
  366. }
  367. SETSOCKOPT_FLAG_TYPE fl;
  368. #ifdef SO_REUSEPORT
  369. fl = SETSOCKOPT_FLAG_TRUE;
  370. setsockopt(udpSock,SOL_SOCKET,SO_REUSEPORT,(void *)&fl,sizeof(fl));
  371. #endif
  372. #ifndef __LINUX__ // linux wants just SO_REUSEPORT
  373. fl = SETSOCKOPT_FLAG_TRUE;
  374. setsockopt(udpSock,SOL_SOCKET,SO_REUSEADDR,(void *)&fl,sizeof(fl));
  375. #endif
  376. fl = SETSOCKOPT_FLAG_TRUE;
  377. setsockopt(udpSock,SOL_SOCKET,SO_BROADCAST,(void *)&fl,sizeof(fl));
  378. #ifdef IP_DONTFRAG
  379. fl = SETSOCKOPT_FLAG_FALSE;
  380. setsockopt(udpSock,IPPROTO_IP,IP_DONTFRAG,(void *)&fl,sizeof(fl));
  381. #endif
  382. #ifdef IP_MTU_DISCOVER
  383. fl = SETSOCKOPT_FLAG_FALSE;
  384. setsockopt(udpSock,IPPROTO_IP,IP_MTU_DISCOVER,(void *)&fl,sizeof(fl));
  385. #endif
  386. #ifdef SO_BINDTODEVICE
  387. if ((dev)&&(strlen(dev)))
  388. setsockopt(udpSock,SOL_SOCKET,SO_BINDTODEVICE,dev,strlen(dev));
  389. #endif
  390. #if defined(__BSD__) && defined(IP_BOUND_IF)
  391. if ((dev)&&(strlen(dev))) {
  392. int idx = if_nametoindex(dev);
  393. if (idx != 0)
  394. setsockopt(udpSock,IPPROTO_IP,IP_BOUND_IF,(void *)&idx,sizeof(idx));
  395. }
  396. #endif
  397. }
  398. extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port,const int primary)
  399. {
  400. if (strchr(ip,':')) {
  401. struct sockaddr_in6 in6;
  402. memset(&in6,0,sizeof(in6));
  403. in6.sin6_family = AF_INET6;
  404. if (inet_pton(AF_INET6,ip,&(in6.sin6_addr)) <= 0)
  405. return errno;
  406. in6.sin6_port = htons((uint16_t)port);
  407. ZT_SOCKET udpSock = socket(AF_INET6,SOCK_DGRAM,0);
  408. if (udpSock == ZT_INVALID_SOCKET)
  409. return errno;
  410. setCommonUdpSocketSettings(udpSock,dev);
  411. SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
  412. setsockopt(udpSock,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&fl,sizeof(fl));
  413. #ifdef IPV6_DONTFRAG
  414. fl = SETSOCKOPT_FLAG_FALSE;
  415. setsockopt(udpSock,IPPROTO_IPV6,IPV6_DONTFRAG,&fl,sizeof(fl));
  416. #endif
  417. if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in6),sizeof(in6)) != 0)
  418. return errno;
  419. {
  420. std::lock_guard<std::mutex> l(gn->threads_l);
  421. ZT_GoNodeThread &gnt = gn->threads[udpSock];
  422. gnt.ip = ip;
  423. gnt.port = port;
  424. gnt.af = AF_INET6;
  425. gnt.primary = (primary != 0);
  426. gnt.run = true;
  427. gnt.thr = std::thread([udpSock,gn,&gnt] {
  428. struct sockaddr_in6 in6;
  429. socklen_t salen;
  430. char buf[16384];
  431. while (gnt.run) {
  432. salen = sizeof(in6);
  433. int s = (int)recvfrom(udpSock,buf,sizeof(buf),0,reinterpret_cast<struct sockaddr *>(&in6),&salen);
  434. if (s > 0) {
  435. gn->node->processWirePacket(&gnt,OSUtils::now(),(int64_t)udpSock,reinterpret_cast<const struct sockaddr_storage *>(&in6),buf,(unsigned int)s,&(gn->nextBackgroundTaskDeadline));
  436. } else {
  437. // If something goes bad with this socket such as its interface vanishing, it
  438. // will eventually be closed by higher level (Go) code. Until then prevent the
  439. // system from consuming too much CPU.
  440. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  441. }
  442. }
  443. });
  444. }
  445. } else {
  446. struct sockaddr_in in;
  447. memset(&in,0,sizeof(in));
  448. in.sin_family = AF_INET;
  449. if (inet_pton(AF_INET,ip,&(in.sin_addr)) <= 0)
  450. return errno;
  451. in.sin_port = htons((uint16_t)port);
  452. ZT_SOCKET udpSock = socket(AF_INET,SOCK_DGRAM,0);
  453. if (udpSock == ZT_INVALID_SOCKET)
  454. return errno;
  455. setCommonUdpSocketSettings(udpSock,dev);
  456. #ifdef SO_NO_CHECK
  457. SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
  458. setsockopt(udpSock,SOL_SOCKET,SO_NO_CHECK,&fl,sizeof(fl));
  459. #endif
  460. if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in),sizeof(in)) != 0)
  461. return errno;
  462. {
  463. std::lock_guard<std::mutex> l(gn->threads_l);
  464. ZT_GoNodeThread &gnt = gn->threads[udpSock];
  465. gnt.ip = ip;
  466. gnt.port = port;
  467. gnt.af = AF_INET6;
  468. gnt.primary = (primary != 0);
  469. gnt.run = true;
  470. gnt.thr = std::thread([udpSock,gn,&gnt] {
  471. struct sockaddr_in in4;
  472. socklen_t salen;
  473. char buf[16384];
  474. while (gnt.run) {
  475. salen = sizeof(in4);
  476. int s = (int)recvfrom(udpSock,buf,sizeof(buf),0,reinterpret_cast<struct sockaddr *>(&in4),&salen);
  477. if (s > 0) {
  478. gn->node->processWirePacket(&gnt,OSUtils::now(),(int64_t)udpSock,reinterpret_cast<const struct sockaddr_storage *>(&in4),buf,(unsigned int)s,&(gn->nextBackgroundTaskDeadline));
  479. }
  480. }
  481. });
  482. }
  483. }
  484. return 0;
  485. }
  486. extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port)
  487. {
  488. {
  489. std::lock_guard<std::mutex> l(gn->threads_l);
  490. for(auto t=gn->threads.begin();t!=gn->threads.end();) {
  491. if ((t->second.ip == ip)&&(t->second.port == port)) {
  492. t->second.run = false;
  493. shutdown(t->first,SHUT_RDWR);
  494. close(t->first);
  495. t->second.thr.join();
  496. gn->threads.erase(t++);
  497. } else ++t;
  498. }
  499. }
  500. return 0;
  501. }
  502. static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
  503. {
  504. ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
  505. gn->node->processVirtualNetworkFrame(tptr,OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&(gn->nextBackgroundTaskDeadline));
  506. }
  507. extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid)
  508. {
  509. try {
  510. std::lock_guard<std::mutex> l(gn->taps_l);
  511. auto existingTap = gn->taps.find(nwid);
  512. if (existingTap != gn->taps.end())
  513. return (ZT_GoTap *)existingTap->second.get();
  514. char tmp[256];
  515. OSUtils::ztsnprintf(tmp,sizeof(tmp),"ZeroTier Network %.16llx",(unsigned long long)nwid);
  516. std::shared_ptr<EthernetTap> tap(EthernetTap::newInstance(nullptr,gn->path.c_str(),MAC(Address(gn->node->address()),nwid),ZT_DEFAULT_MTU,0,nwid,tmp,&tapFrameHandler,gn));
  517. if (!tap)
  518. return nullptr;
  519. gn->taps[nwid] = tap;
  520. gn->node->join(nwid,tap.get(),nullptr);
  521. return (ZT_GoTap *)tap.get();
  522. } catch ( ... ) {
  523. return nullptr;
  524. }
  525. }
  526. extern "C" void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid)
  527. {
  528. std::lock_guard<std::mutex> l(gn->taps_l);
  529. auto existingTap = gn->taps.find(nwid);
  530. if (existingTap != gn->taps.end()) {
  531. gn->node->leave(nwid,nullptr,nullptr);
  532. gn->taps.erase(existingTap);
  533. }
  534. }
  535. /****************************************************************************/
  536. extern "C" void ZT_GoTap_setEnabled(ZT_GoTap *tap,int enabled)
  537. {
  538. reinterpret_cast<EthernetTap *>(tap)->setEnabled(enabled != 0);
  539. }
  540. extern "C" int ZT_GoTap_addIp(ZT_GoTap *tap,int af,const void *ip,int netmaskBits)
  541. {
  542. switch(af) {
  543. case AF_INET:
  544. return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,4,(unsigned int)netmaskBits)) ? 1 : 0);
  545. case AF_INET6:
  546. return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,16,(unsigned int)netmaskBits)) ? 1 : 0);
  547. }
  548. return 0;
  549. }
  550. extern "C" int ZT_GoTap_removeIp(ZT_GoTap *tap,int af,const void *ip,int netmaskBits)
  551. {
  552. switch(af) {
  553. case AF_INET:
  554. return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,4,(unsigned int)netmaskBits)) ? 1 : 0);
  555. case AF_INET6:
  556. return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,16,(unsigned int)netmaskBits)) ? 1 : 0);
  557. }
  558. return 0;
  559. }
  560. extern "C" int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize)
  561. {
  562. auto ips = reinterpret_cast<EthernetTap *>(tap)->ips();
  563. unsigned int p = 0;
  564. uint8_t *const b = reinterpret_cast<uint8_t *>(buf);
  565. for(auto ip=ips.begin();ip!=ips.end();++ip) {
  566. if ((p + 6) > bufSize)
  567. break;
  568. const uint8_t *const ipd = reinterpret_cast<const uint8_t *>(ip->rawIpData());
  569. if (ip->isV4()) {
  570. b[p++] = AF_INET;
  571. b[p++] = ipd[0];
  572. b[p++] = ipd[1];
  573. b[p++] = ipd[2];
  574. b[p++] = ipd[3];
  575. b[p++] = (uint8_t)ip->netmaskBits();
  576. } else if (ip->isV6()) {
  577. if ((p + 18) <= bufSize) {
  578. b[p++] = AF_INET6;
  579. for(int j=0;j<16;++j)
  580. b[p++] = ipd[j];
  581. b[p++] = (uint8_t)ip->netmaskBits();
  582. }
  583. }
  584. }
  585. return (int)p;
  586. }
  587. extern "C" void ZT_GoTap_deviceName(ZT_GoTap *tap,char nbuf[256])
  588. {
  589. Utils::scopy(nbuf,256,reinterpret_cast<EthernetTap *>(tap)->deviceName().c_str());
  590. }
  591. extern "C" void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName)
  592. {
  593. reinterpret_cast<EthernetTap *>(tap)->setFriendlyName(friendlyName);
  594. }
  595. extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu)
  596. {
  597. reinterpret_cast<EthernetTap *>(tap)->setMtu(mtu);
  598. }
  599. extern "C" int ZT_GoTap_addRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric)
  600. {
  601. InetAddress target,via;
  602. switch(targetAf) {
  603. case AF_INET:
  604. target.set(targetIp,4,(unsigned int)targetNetmaskBits);
  605. break;
  606. case AF_INET6:
  607. target.set(targetIp,16,(unsigned int)targetNetmaskBits);
  608. break;
  609. }
  610. switch(viaAf) {
  611. case AF_INET:
  612. via.set(viaIp,4,0);
  613. break;
  614. case AF_INET6:
  615. via.set(viaIp,16,0);
  616. break;
  617. }
  618. return reinterpret_cast<EthernetTap *>(tap)->addRoute(target,via,metric);
  619. }
  620. extern "C" int ZT_GoTap_removeRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric)
  621. {
  622. InetAddress target,via;
  623. switch(targetAf) {
  624. case AF_INET:
  625. target.set(targetIp,4,(unsigned int)targetNetmaskBits);
  626. break;
  627. case AF_INET6:
  628. target.set(targetIp,16,(unsigned int)targetNetmaskBits);
  629. break;
  630. }
  631. switch(viaAf) {
  632. case AF_INET:
  633. via.set(viaIp,4,0);
  634. break;
  635. case AF_INET6:
  636. via.set(viaIp,16,0);
  637. break;
  638. }
  639. return reinterpret_cast<EthernetTap *>(tap)->removeRoute(target,via,metric);
  640. }