GoNode.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*
  2. * Copyright (c)2019 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: 2023-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by vergnn 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include "GoNode.h"
  14. #include "../../node/Constants.hpp"
  15. #include "../../node/InetAddress.hpp"
  16. #include "../../node/Node.hpp"
  17. #include "../../node/Utils.hpp"
  18. #include "../../osdep/OSUtils.hpp"
  19. #include "../../osdep/BlockingQueue.hpp"
  20. #include "../../osdep/EthernetTap.hpp"
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <errno.h>
  24. #ifndef __WINDOWS__
  25. #include <errno.h>
  26. #include <signal.h>
  27. #include <unistd.h>
  28. #include <fcntl.h>
  29. #include <sys/time.h>
  30. #include <sys/types.h>
  31. #include <sys/select.h>
  32. #include <sys/socket.h>
  33. #include <sys/un.h>
  34. #include <arpa/inet.h>
  35. #include <netinet/in.h>
  36. #include <netinet/ip6.h>
  37. #include <netinet/tcp.h>
  38. #ifdef __BSD__
  39. #include <net/if.h>
  40. #endif
  41. #ifdef __LINUX__
  42. #ifndef IPV6_DONTFRAG
  43. #define IPV6_DONTFRAG 62
  44. #endif
  45. #endif
  46. #endif // !__WINDOWS__
  47. #include <thread>
  48. #include <mutex>
  49. #include <map>
  50. #include <vector>
  51. #include <array>
  52. #include <set>
  53. #ifdef __WINDOWS__
  54. #define SETSOCKOPT_FLAG_TYPE BOOL
  55. #define SETSOCKOPT_FLAG_TRUE TRUE
  56. #define SETSOCKOPT_FLAG_FALSE FALSE
  57. #else
  58. #define SETSOCKOPT_FLAG_TYPE int
  59. #define SETSOCKOPT_FLAG_TRUE 1
  60. #define SETSOCKOPT_FLAG_FALSE 0
  61. #endif
  62. #ifndef MSG_DONTWAIT
  63. #define MSG_DONTWAIT 0
  64. #endif
  65. using namespace ZeroTier;
  66. struct ZT_GoNodeThread
  67. {
  68. std::string ip;
  69. int port;
  70. int af;
  71. std::atomic_bool run;
  72. std::thread thr;
  73. };
  74. struct ZT_GoNode_Impl
  75. {
  76. Node *node;
  77. volatile int64_t nextBackgroundTaskDeadline;
  78. int (*goPathCheckFunc)(ZT_GoNode *,ZT_Node *,uint64_t ztAddress,const void *);
  79. int (*goPathLookupFunc)(ZT_GoNode *,ZT_Node *,int desiredAddressFamily,void *);
  80. int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize);
  81. std::map< ZT_SOCKET,ZT_GoNodeThread > threads;
  82. std::mutex threads_l;
  83. BlockingQueue<ZT_GoNodeEvent> eq;
  84. };
  85. //////////////////////////////////////////////////////////////////////////////
  86. static int ZT_GoNode_VirtualNetworkConfigFunction(
  87. ZT_Node *node,
  88. void *uptr,
  89. void *tptr,
  90. uint64_t nwid,
  91. void **nptr,
  92. enum ZT_VirtualNetworkConfigOperation op,
  93. const ZT_VirtualNetworkConfig *cfg)
  94. {
  95. ZT_GoNodeEvent ev;
  96. ev.type = ZT_GONODE_EVENT_NETWORK_CONFIG_UPDATE;
  97. ev.data.nconf.op = op;
  98. if (cfg)
  99. ev.data.nconf.conf = *cfg;
  100. reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
  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. ZT_GoNodeEvent ev;
  126. ev.type = ZT_GONODE_EVENT_ZTEVENT;
  127. ev.data.zt.type = et;
  128. reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
  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. if (len < ZT_MAX_STATE_OBJECT_SIZE) { // sanity check
  140. ZT_GoNodeEvent ev;
  141. ev.type = (len >= 0) ? ZT_GONODE_EVENT_STATE_PUT : ZT_GONODE_EVENT_STATE_DELETE;
  142. if (len > 0) {
  143. memcpy(ev.data.sobj.data,data,len);
  144. ev.data.sobj.len = (unsigned int)len;
  145. }
  146. ev.data.sobj.objType = objType;
  147. ev.data.sobj.id[0] = id[0];
  148. ev.data.sobj.id[1] = id[1];
  149. reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
  150. }
  151. }
  152. static int ZT_GoNode_StateGetFunction(
  153. ZT_Node *node,
  154. void *uptr,
  155. void *tptr,
  156. enum ZT_StateObjectType objType,
  157. const uint64_t id[2],
  158. void *buf,
  159. unsigned int buflen)
  160. {
  161. return reinterpret_cast<ZT_GoNode *>(uptr)->goStateObjectGetFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,(int)objType,id,buf,buflen);
  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 void 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 != -1)&&(localSocket != ZT_INVALID_SOCKET)) {
  200. doUdpSend((ZT_SOCKET)localSocket,addr,data,len,ipTTL);
  201. } else {
  202. ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
  203. std::set<std::string> ipsSentFrom;
  204. std::lock_guard<std::mutex> l(gn->threads_l);
  205. for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
  206. if (t->second.af == addr->ss_family) {
  207. if (ipsSentFrom.insert(t->second.ip).second) {
  208. doUdpSend(t->first,addr,data,len,ipTTL);
  209. }
  210. }
  211. }
  212. }
  213. }
  214. static int ZT_GoNode_PathCheckFunction(
  215. ZT_Node *node,
  216. void *uptr,
  217. void *tptr,
  218. uint64_t ztAddress,
  219. int64_t localSocket,
  220. const struct sockaddr_storage *sa)
  221. {
  222. return reinterpret_cast<ZT_GoNode *>(uptr)->goPathCheckFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,ztAddress,sa);
  223. }
  224. static int ZT_GoNode_PathLookupFunction(
  225. ZT_Node *node,
  226. void *uptr,
  227. void *tptr,
  228. uint64_t ztAddress,
  229. int desiredAddressFamily,
  230. struct sockaddr_storage *sa)
  231. {
  232. return reinterpret_cast<ZT_GoNode *>(uptr)->goPathLookupFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,desiredAddressFamily,sa);
  233. }
  234. static void ZT_GoNode_DNSResolver(
  235. ZT_Node *node,
  236. void *uptr,
  237. void *tptr,
  238. const enum ZT_DNSRecordType *types,
  239. unsigned int numTypes,
  240. const char *name,
  241. uintptr_t requestId)
  242. {
  243. ZT_GoNodeEvent ev;
  244. ev.type = ZT_GONODE_EVENT_DNS_GET_TXT;
  245. Utils::scopy(ev.data.dns.dnsName,sizeof(ev.data.dns.dnsName),name);
  246. reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
  247. }
  248. //////////////////////////////////////////////////////////////////////////////
  249. extern "C" ZT_GoNode *ZT_GoNode_new(
  250. int (*goPathCheckFunc)(ZT_GoNode *,ZT_Node *,uint64_t ztAddress,const void *),
  251. int (*goPathLookupFunc)(ZT_GoNode *,ZT_Node *,int desiredAddressFamily,void *),
  252. int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize)
  253. )
  254. {
  255. try {
  256. struct ZT_Node_Callbacks cb;
  257. cb.virtualNetworkConfigFunction = &ZT_GoNode_VirtualNetworkConfigFunction;
  258. cb.virtualNetworkFrameFunction = &ZT_GoNode_VirtualNetworkFrameFunction;
  259. cb.eventCallback = &ZT_GoNode_EventCallback;
  260. cb.statePutFunction = &ZT_GoNode_StatePutFunction;
  261. cb.stateGetFunction = &ZT_GoNode_StateGetFunction;
  262. cb.pathCheckFunction = &ZT_GoNode_PathCheckFunction;
  263. cb.pathLookupFunction = &ZT_GoNode_PathLookupFunction;
  264. cb.dnsResolver = &ZT_GoNode_DNSResolver;
  265. ZT_GoNode_Impl *gn = new ZT_GoNode_Impl;
  266. const int64_t now = OSUtils::now();
  267. gn->node = new Node(reinterpret_cast<void *>(gn),nullptr,&cb,now);
  268. gn->nextBackgroundTaskDeadline = now;
  269. gn->goPathCheckFunc = goPathCheckFunc;
  270. gn->goPathLookupFunc = goPathLookupFunc;
  271. gn->goStateObjectGetFunc = goStateObjectGetFunc;
  272. return gn;
  273. } catch ( ... ) {
  274. fprintf(stderr,"FATAL: unable to create new instance of Node (out of memory?)" ZT_EOL_S);
  275. exit(1);
  276. }
  277. }
  278. extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
  279. {
  280. ZT_GoNodeEvent sd;
  281. sd.type = ZT_GONODE_EVENT_SHUTDOWN;
  282. gn->eq.post(sd);
  283. std::vector<std::thread> th;
  284. gn->threads_l.lock();
  285. for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
  286. t->second.run = false;
  287. shutdown(t->first,SHUT_RDWR);
  288. close(t->first);
  289. th.emplace_back(t->second.thr);
  290. }
  291. gn->threads_l.unlock();
  292. for(auto t=th.begin();t!=th.end();++t)
  293. t->join();
  294. delete gn->node;
  295. delete gn;
  296. }
  297. extern "C" ZT_Node *ZT_GoNode_getNode(ZT_GoNode *gn)
  298. {
  299. return gn->node;
  300. }
  301. // Sets flags and socket options common to both IPv4 and IPv6 UDP sockets
  302. static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
  303. {
  304. int bufSize = 1048576;
  305. while (bufSize > 131072) {
  306. if (setsockopt(udpSock,SOL_SOCKET,SO_RCVBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
  307. break;
  308. bufSize -= 131072;
  309. }
  310. bufSize = 1048576;
  311. while (bufSize > 131072) {
  312. if (setsockopt(udpSock,SOL_SOCKET,SO_SNDBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
  313. break;
  314. bufSize -= 131072;
  315. }
  316. SETSOCKOPT_FLAG_TYPE fl;
  317. #ifdef SO_REUSEPORT
  318. fl = SETSOCKOPT_FLAG_TRUE;
  319. setsockopt(udpSock,SOL_SOCKET,SO_REUSEPORT,(void *)&fl,sizeof(fl));
  320. #endif
  321. #ifndef __LINUX__ // linux wants just SO_REUSEPORT
  322. fl = SETSOCKOPT_FLAG_TRUE;
  323. setsockopt(udpSock,SOL_SOCKET,SO_REUSEADDR,(void *)&fl,sizeof(fl));
  324. #endif
  325. fl = SETSOCKOPT_FLAG_TRUE;
  326. setsockopt(udpSock,SOL_SOCKET,SO_BROADCAST,(void *)&fl,sizeof(fl));
  327. #ifdef IP_DONTFRAG
  328. fl = SETSOCKOPT_FLAG_FALSE;
  329. setsockopt(udpSock,IPPROTO_IP,IP_DONTFRAG,(void *)&fl,sizeof(fl));
  330. #endif
  331. #ifdef IP_MTU_DISCOVER
  332. fl = SETSOCKOPT_FLAG_FALSE;
  333. setsockopt(udpSock,IPPROTO_IP,IP_MTU_DISCOVER,(void *)&fl,sizeof(fl));
  334. #endif
  335. #ifdef SO_BINDTODEVICE
  336. if ((dev)&&(strlen(dev)))
  337. setsockopt(udpSock,SOL_SOCKET,SO_BINDTODEVICE,dev,strlen(dev));
  338. #endif
  339. #if defined(__BSD__) && defined(IP_BOUND_IF)
  340. if ((dev)&&(strlen(dev))) {
  341. int idx = if_nametoindex(dev);
  342. if (idx != 0)
  343. setsockopt(udpSock,IPPROTO_IP,IP_BOUND_IF,(void *)&idx,sizeof(idx));
  344. }
  345. #endif
  346. }
  347. extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port)
  348. {
  349. if (strchr(ip,':')) {
  350. struct sockaddr_in6 in6;
  351. memset(&in6,0,sizeof(in6));
  352. in6.sin6_family = AF_INET6;
  353. if (inet_pton(AF_INET6,ip,&(in6.sin6_addr)) <= 0)
  354. return errno;
  355. in6.sin6_port = htons((uint16_t)port);
  356. ZT_SOCKET udpSock = socket(AF_INET6,SOCK_DGRAM,0);
  357. if (udpSock == ZT_INVALID_SOCKET)
  358. return errno;
  359. setCommonUdpSocketSettings(udpSock,dev);
  360. SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
  361. setsockopt(udpSock,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&fl,sizeof(fl));
  362. #ifdef IPV6_DONTFRAG
  363. fl = SETSOCKOPT_FLAG_FALSE;
  364. setsockopt(udpSock,IPPROTO_IPV6,IPV6_DONTFRAG,&fl,sizeof(fl));
  365. #endif
  366. if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in6),sizeof(in6)) != 0)
  367. return errno;
  368. {
  369. std::lock_guard<std::mutex> l(gn->threads_l);
  370. ZT_GoNodeThread &gnt = gn->threads[udpSock];
  371. gnt.ip = ip;
  372. gnt.port = port;
  373. gnt.af = AF_INET6;
  374. gnt.run = true;
  375. gnt.thr = std::thread([udpSock,gn,&gnt] {
  376. struct sockaddr_in6 in6;
  377. socklen_t salen;
  378. char buf[16384];
  379. while (gnt.run) {
  380. salen = sizeof(in6);
  381. int s = (int)recvfrom(udpSock,buf,sizeof(buf),0,reinterpret_cast<struct sockaddr *>(&in6),&salen);
  382. if (s > 0) {
  383. gn->node->processWirePacket(&gnt,OSUtils::now(),(int64_t)udpSock,reinterpret_cast<const struct sockaddr_storage *>(&in6),buf,(unsigned int)s,&(gn->nextBackgroundTaskDeadline));
  384. }
  385. }
  386. });
  387. }
  388. } else {
  389. struct sockaddr_in in;
  390. memset(&in,0,sizeof(in));
  391. in.sin_family = AF_INET;
  392. if (inet_pton(AF_INET,ip,&(in.sin_addr)) <= 0)
  393. return errno;
  394. in.sin_port = htons((uint16_t)port);
  395. ZT_SOCKET udpSock = socket(AF_INET,SOCK_DGRAM,0);
  396. if (udpSock == ZT_INVALID_SOCKET)
  397. return errno;
  398. setCommonUdpSocketSettings(udpSock,dev);
  399. #ifdef SO_NO_CHECK
  400. SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
  401. setsockopt(udpSock,SOL_SOCKET,SO_NO_CHECK,&fl,sizeof(fl));
  402. #endif
  403. if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in),sizeof(in)) != 0)
  404. return errno;
  405. {
  406. std::lock_guard<std::mutex> l(gn->threads_l);
  407. ZT_GoNodeThread &gnt = gn->threads[udpSock];
  408. gnt.ip = ip;
  409. gnt.port = port;
  410. gnt.af = AF_INET6;
  411. gnt.run = true;
  412. gnt.thr = std::thread([udpSock,gn,&gnt] {
  413. struct sockaddr_in in4;
  414. socklen_t salen;
  415. char buf[16384];
  416. while (gnt.run) {
  417. salen = sizeof(in4);
  418. int s = (int)recvfrom(udpSock,buf,sizeof(buf),0,reinterpret_cast<struct sockaddr *>(&in4),&salen);
  419. if (s > 0) {
  420. gn->node->processWirePacket(&gnt,OSUtils::now(),(int64_t)udpSock,reinterpret_cast<const struct sockaddr_storage *>(&in4),buf,(unsigned int)s,&(gn->nextBackgroundTaskDeadline));
  421. }
  422. }
  423. });
  424. }
  425. }
  426. return 0;
  427. }
  428. extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port)
  429. {
  430. {
  431. std::lock_guard<std::mutex> l(gn->threads_l);
  432. for(auto t=gn->threads.begin();t!=gn->threads.end();) {
  433. if ((t->second.ip == ip)&&(t->second.port == port)) {
  434. t->second.run = false;
  435. shutdown(t->first,SHUT_RDWR);
  436. close(t->first);
  437. t->second.thr.join();
  438. gn->threads.erase(t++);
  439. } else ++t;
  440. }
  441. }
  442. }
  443. extern "C" int ZT_GoNode_waitForEvent(ZT_GoNode *gn,ZT_GoNodeEvent *ev)
  444. {
  445. gn->eq.get(*ev);
  446. }