GoGlue.cpp 19 KB

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