GoGlue.cpp 19 KB

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