com_zerotierone_sdk_Node.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2015 ZeroTier, Inc.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * --
  19. *
  20. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #include "com_zerotierone_sdk_Node.h"
  28. #include "ZT_jnicache.h"
  29. #include "ZT_jniutils.h"
  30. #include <ZeroTierOne.h>
  31. #include "Mutex.hpp"
  32. #include <map>
  33. #include <string>
  34. #include <cassert>
  35. #include <cstring>
  36. #include <cinttypes> // for PRId64
  37. #define LOG_TAG "Node"
  38. namespace {
  39. struct JniRef
  40. {
  41. JniRef(
  42. int64_t id,
  43. JavaVM *jvm,
  44. jobject dataStoreGetListenerLocalIn,
  45. jobject dataStorePutListenerLocalIn,
  46. jobject packetSenderLocalIn,
  47. jobject eventListenerLocalIn,
  48. jobject frameListenerLocalIn,
  49. jobject configListenerLocalIn,
  50. jobject pathCheckerLocalIn)
  51. : id(id)
  52. , jvm(jvm)
  53. , node()
  54. , dataStoreGetListener()
  55. , dataStorePutListener()
  56. , packetSender()
  57. , eventListener()
  58. , frameListener()
  59. , configListener()
  60. , pathChecker()
  61. , inited() {
  62. JNIEnv *env;
  63. GETENV(env, jvm);
  64. dataStoreGetListener = env->NewGlobalRef(dataStoreGetListenerLocalIn);
  65. dataStorePutListener = env->NewGlobalRef(dataStorePutListenerLocalIn);
  66. packetSender = env->NewGlobalRef(packetSenderLocalIn);
  67. eventListener = env->NewGlobalRef(eventListenerLocalIn);
  68. frameListener = env->NewGlobalRef(frameListenerLocalIn);
  69. configListener = env->NewGlobalRef(configListenerLocalIn);
  70. pathChecker = env->NewGlobalRef(pathCheckerLocalIn);
  71. };
  72. ~JniRef()
  73. {
  74. JNIEnv *env;
  75. GETENV(env, jvm);
  76. env->DeleteGlobalRef(dataStoreGetListener);
  77. env->DeleteGlobalRef(dataStorePutListener);
  78. env->DeleteGlobalRef(packetSender);
  79. env->DeleteGlobalRef(eventListener);
  80. env->DeleteGlobalRef(frameListener);
  81. env->DeleteGlobalRef(configListener);
  82. env->DeleteGlobalRef(pathChecker);
  83. }
  84. int64_t id;
  85. JavaVM *jvm;
  86. ZT_Node *node;
  87. jobject dataStoreGetListener;
  88. jobject dataStorePutListener;
  89. jobject packetSender;
  90. jobject eventListener;
  91. jobject frameListener;
  92. jobject configListener;
  93. jobject pathChecker;
  94. bool inited;
  95. bool finishInitializing();
  96. };
  97. int VirtualNetworkConfigFunctionCallback(
  98. ZT_Node *node,
  99. void *userData,
  100. void *threadData,
  101. uint64_t nwid,
  102. void **,
  103. enum ZT_VirtualNetworkConfigOperation operation,
  104. const ZT_VirtualNetworkConfig *config)
  105. {
  106. LOGV("VirtualNetworkConfigFunctionCallback");
  107. JniRef *ref = (JniRef*)userData;
  108. JNIEnv *env;
  109. GETENV(env, ref->jvm);
  110. if (ref->configListener == NULL) {
  111. LOGE("configListener is NULL");
  112. return -100;
  113. }
  114. jobject operationObject = createVirtualNetworkConfigOperation(env, operation);
  115. if(env->ExceptionCheck() || operationObject == NULL)
  116. {
  117. return -101;
  118. }
  119. if (config == NULL) {
  120. LOGE("Config is NULL");
  121. return -102;
  122. }
  123. jobject networkConfigObject = newNetworkConfig(env, *config);
  124. if(env->ExceptionCheck() || networkConfigObject == NULL)
  125. {
  126. return -103;
  127. }
  128. return env->CallIntMethod(
  129. ref->configListener,
  130. VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method,
  131. (jlong)nwid, operationObject, networkConfigObject);
  132. }
  133. void VirtualNetworkFrameFunctionCallback(ZT_Node *node,
  134. void *userData,
  135. void *threadData,
  136. uint64_t nwid,
  137. void**,
  138. uint64_t sourceMac,
  139. uint64_t destMac,
  140. unsigned int etherType,
  141. unsigned int vlanid,
  142. const void *frameData,
  143. unsigned int frameLength)
  144. {
  145. LOGV("VirtualNetworkFrameFunctionCallback");
  146. #ifndef NDEBUG
  147. unsigned char* local = (unsigned char*)frameData;
  148. LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]);
  149. #endif
  150. JniRef *ref = (JniRef*)userData;
  151. assert(ref->node == node);
  152. JNIEnv *env;
  153. GETENV(env, ref->jvm);
  154. if (ref->frameListener == NULL) {
  155. LOGE("frameListener is NULL");
  156. return;
  157. }
  158. const unsigned char *bytes = static_cast<const unsigned char*>(frameData);
  159. jbyteArray dataArray = newByteArray(env, bytes, frameLength);
  160. if(env->ExceptionCheck() || dataArray == NULL)
  161. {
  162. return;
  163. }
  164. env->CallVoidMethod(ref->frameListener, VirtualNetworkFrameListener_onVirtualNetworkFrame_method, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, dataArray);
  165. }
  166. void EventCallback(ZT_Node *node,
  167. void *userData,
  168. void *threadData,
  169. enum ZT_Event event,
  170. const void *data) {
  171. LOGV("EventCallback");
  172. JniRef *ref = (JniRef *) userData;
  173. if (ref->node != node && event != ZT_EVENT_UP) {
  174. LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event);
  175. return;
  176. }
  177. JNIEnv *env;
  178. GETENV(env, ref->jvm);
  179. if (ref->eventListener == NULL) {
  180. LOGE("eventListener is NULL");
  181. return;
  182. }
  183. jobject eventObject = createEvent(env, event);
  184. if (env->ExceptionCheck() || eventObject == NULL) {
  185. return;
  186. }
  187. switch (event) {
  188. case ZT_EVENT_UP: {
  189. LOGD("Event Up");
  190. env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject);
  191. break;
  192. }
  193. case ZT_EVENT_OFFLINE: {
  194. LOGD("Event Offline");
  195. env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject);
  196. break;
  197. }
  198. case ZT_EVENT_ONLINE: {
  199. LOGD("Event Online");
  200. env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject);
  201. break;
  202. }
  203. case ZT_EVENT_DOWN: {
  204. LOGD("Event Down");
  205. env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject);
  206. break;
  207. }
  208. case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: {
  209. LOGV("Identity Collision");
  210. // call onEvent()
  211. env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject);
  212. }
  213. break;
  214. case ZT_EVENT_TRACE: {
  215. LOGV("Trace Event");
  216. // call onTrace()
  217. if (data == NULL) {
  218. break;
  219. }
  220. const char *message = (const char *) data;
  221. jstring messageStr = env->NewStringUTF(message);
  222. env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, messageStr);
  223. }
  224. break;
  225. case ZT_EVENT_USER_MESSAGE:
  226. case ZT_EVENT_REMOTE_TRACE:
  227. default:
  228. break;
  229. }
  230. }
  231. void StatePutFunction(
  232. ZT_Node *node,
  233. void *userData,
  234. void *threadData,
  235. enum ZT_StateObjectType type,
  236. const uint64_t id[2],
  237. const void *buffer,
  238. int bufferLength) {
  239. char p[4096] = {0};
  240. bool secure = false;
  241. switch (type) {
  242. case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
  243. snprintf(p, sizeof(p), "identity.public");
  244. break;
  245. case ZT_STATE_OBJECT_IDENTITY_SECRET:
  246. snprintf(p, sizeof(p), "identity.secret");
  247. secure = true;
  248. break;
  249. case ZT_STATE_OBJECT_PLANET:
  250. snprintf(p, sizeof(p), "planet");
  251. break;
  252. case ZT_STATE_OBJECT_MOON:
  253. snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]);
  254. break;
  255. case ZT_STATE_OBJECT_NETWORK_CONFIG:
  256. snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]);
  257. break;
  258. case ZT_STATE_OBJECT_PEER:
  259. snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]);
  260. break;
  261. default:
  262. return;
  263. }
  264. if (strlen(p) < 1) {
  265. return;
  266. }
  267. JniRef *ref = (JniRef*)userData;
  268. JNIEnv *env;
  269. GETENV(env, ref->jvm);
  270. if (ref->dataStorePutListener == NULL) {
  271. LOGE("dataStorePutListener is NULL");
  272. return;
  273. }
  274. jstring nameStr = env->NewStringUTF(p);
  275. if (bufferLength >= 0) {
  276. LOGD("JNI: Write file: %s", p);
  277. const unsigned char *bytes = static_cast<const unsigned char *>(buffer);
  278. jbyteArray bufferObj = newByteArray(env, bytes, bufferLength);
  279. if(env->ExceptionCheck() || bufferObj == NULL)
  280. {
  281. return;
  282. }
  283. env->CallIntMethod(ref->dataStorePutListener,
  284. DataStorePutListener_onDataStorePut_method,
  285. nameStr, bufferObj, secure);
  286. } else {
  287. LOGD("JNI: Delete file: %s", p);
  288. env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, nameStr);
  289. }
  290. }
  291. int StateGetFunction(
  292. ZT_Node *node,
  293. void *userData,
  294. void *threadData,
  295. ZT_StateObjectType type,
  296. const uint64_t id[2],
  297. void *buffer,
  298. unsigned int bufferLength) {
  299. char p[4096] = {0};
  300. switch (type) {
  301. case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
  302. snprintf(p, sizeof(p), "identity.public");
  303. break;
  304. case ZT_STATE_OBJECT_IDENTITY_SECRET:
  305. snprintf(p, sizeof(p), "identity.secret");
  306. break;
  307. case ZT_STATE_OBJECT_PLANET:
  308. snprintf(p, sizeof(p), "planet");
  309. break;
  310. case ZT_STATE_OBJECT_MOON:
  311. snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]);
  312. break;
  313. case ZT_STATE_OBJECT_NETWORK_CONFIG:
  314. snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]);
  315. break;
  316. case ZT_STATE_OBJECT_PEER:
  317. snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]);
  318. break;
  319. default:
  320. return -100;
  321. }
  322. if (strlen(p) < 1) {
  323. return -101;
  324. }
  325. JniRef *ref = (JniRef*)userData;
  326. JNIEnv *env;
  327. GETENV(env, ref->jvm);
  328. if (ref->dataStoreGetListener == NULL) {
  329. LOGE("dataStoreGetListener is NULL");
  330. return -102;
  331. }
  332. jstring nameStr = env->NewStringUTF(p);
  333. if(nameStr == NULL)
  334. {
  335. LOGE("Error creating name string object");
  336. return -103; // out of memory
  337. }
  338. jbyteArray bufferObj = newByteArray(env, bufferLength);
  339. if(env->ExceptionCheck() || bufferObj == NULL)
  340. {
  341. return -104;
  342. }
  343. LOGV("Calling onDataStoreGet(%s, %p)", p, buffer);
  344. int retval = (int)env->CallLongMethod(
  345. ref->dataStoreGetListener,
  346. DataStoreGetListener_onDataStoreGet_method,
  347. nameStr,
  348. bufferObj);
  349. LOGV("onDataStoreGet returned %d", retval);
  350. if(retval > 0)
  351. {
  352. void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL);
  353. memcpy(buffer, data, retval);
  354. env->ReleasePrimitiveArrayCritical(bufferObj, data, 0);
  355. }
  356. return retval;
  357. }
  358. int WirePacketSendFunction(ZT_Node *node,
  359. void *userData,
  360. void *threadData,
  361. int64_t localSocket,
  362. const struct sockaddr_storage *remoteAddress,
  363. const void *buffer,
  364. unsigned int bufferSize,
  365. unsigned int ttl)
  366. {
  367. LOGV("WirePacketSendFunction(%" PRId64 ", %p, %p, %d, %u)", localSocket, remoteAddress, buffer, bufferSize, ttl);
  368. JniRef *ref = (JniRef*)userData;
  369. assert(ref->node == node);
  370. JNIEnv *env;
  371. GETENV(env, ref->jvm);
  372. if (ref->packetSender == NULL) {
  373. LOGE("packetSender is NULL");
  374. return -100;
  375. }
  376. //
  377. // may be NULL
  378. //
  379. jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress);
  380. if (env->ExceptionCheck()) {
  381. return -101;
  382. }
  383. const unsigned char *bytes = static_cast<const unsigned char *>(buffer);
  384. jbyteArray bufferObj = newByteArray(env, bytes, bufferSize);
  385. if (env->ExceptionCheck() || bufferObj == NULL)
  386. {
  387. return -102;
  388. }
  389. int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj, 0);
  390. LOGV("JNI Packet Sender returned: %d", retval);
  391. return retval;
  392. }
  393. int PathCheckFunction(ZT_Node *node,
  394. void *userPtr,
  395. void *threadPtr,
  396. uint64_t address,
  397. int64_t localSocket,
  398. const struct sockaddr_storage *remoteAddress)
  399. {
  400. JniRef *ref = (JniRef*)userPtr;
  401. assert(ref->node == node);
  402. if(ref->pathChecker == NULL) {
  403. return true;
  404. }
  405. JNIEnv *env;
  406. GETENV(env, ref->jvm);
  407. //
  408. // may be NULL
  409. //
  410. jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress);
  411. if (env->ExceptionCheck()) {
  412. return true;
  413. }
  414. return env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj);
  415. }
  416. int PathLookupFunction(ZT_Node *node,
  417. void *userPtr,
  418. void *threadPtr,
  419. uint64_t address,
  420. int ss_family,
  421. struct sockaddr_storage *result)
  422. {
  423. JniRef *ref = (JniRef*)userPtr;
  424. assert(ref->node == node);
  425. if(ref->pathChecker == NULL) {
  426. return false;
  427. }
  428. JNIEnv *env;
  429. GETENV(env, ref->jvm);
  430. jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family);
  431. if(sockAddressObject == NULL)
  432. {
  433. LOGE("Unable to call onPathLookup implementation");
  434. return false;
  435. }
  436. *result = fromSocketAddressObject(env, sockAddressObject);
  437. if (env->ExceptionCheck() || isSocketAddressEmpty(*result)) {
  438. return false;
  439. }
  440. return true;
  441. }
  442. typedef std::map<int64_t, JniRef*> NodeMap;
  443. NodeMap nodeMap;
  444. ZeroTier::Mutex nodeMapMutex;
  445. bool isInited(int64_t nodeId) {
  446. ZeroTier::Mutex::Lock lock(nodeMapMutex);
  447. NodeMap::iterator found = nodeMap.find(nodeId);
  448. if (found == nodeMap.end()) {
  449. //
  450. // not in map yet, or has been removed from map
  451. //
  452. return false;
  453. }
  454. JniRef *ref = found->second;
  455. assert(ref);
  456. return ref->inited;
  457. }
  458. bool JniRef::finishInitializing() {
  459. ZeroTier::Mutex::Lock lock(nodeMapMutex);
  460. NodeMap::iterator found = nodeMap.find(id);
  461. if (found != nodeMap.end()) {
  462. //
  463. // already in map
  464. //
  465. LOGE("Cannot finish initializing; node is already in map");
  466. return false;
  467. }
  468. nodeMap.insert(std::make_pair(id, this));
  469. assert(!inited);
  470. inited = true;
  471. return true;
  472. }
  473. ZT_Node* findNode(int64_t nodeId)
  474. {
  475. ZeroTier::Mutex::Lock lock(nodeMapMutex);
  476. NodeMap::iterator found = nodeMap.find(nodeId);
  477. assert(found != nodeMap.end());
  478. JniRef *ref = found->second;
  479. assert(ref);
  480. return ref->node;
  481. }
  482. JniRef *removeRef(int64_t nodeId) {
  483. ZeroTier::Mutex::Lock lock(nodeMapMutex);
  484. NodeMap::iterator found = nodeMap.find(nodeId);
  485. if (found == nodeMap.end()) {
  486. return nullptr;
  487. }
  488. JniRef *ref = found->second;
  489. assert(ref);
  490. nodeMap.erase(nodeId);
  491. return ref;
  492. }
  493. }
  494. #ifdef __cplusplus
  495. extern "C" {
  496. #endif
  497. JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
  498. {
  499. setupJNICache(vm);
  500. return JNI_VERSION_1_6;
  501. }
  502. JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
  503. {
  504. teardownJNICache(vm);
  505. }
  506. /*
  507. * Class: com_zerotier_sdk_Node
  508. * Method: node_init
  509. * Signature: (JLcom/zerotier/sdk/DataStoreGetListener;Lcom/zerotier/sdk/DataStorePutListener;Lcom/zerotier/sdk/PacketSender;Lcom/zerotier/sdk/EventListener;Lcom/zerotier/sdk/VirtualNetworkFrameListener;Lcom/zerotier/sdk/VirtualNetworkConfigListener;Lcom/zerotier/sdk/PathChecker;)Lcom/zerotier/sdk/ResultCode;
  510. */
  511. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
  512. JNIEnv *env, jobject obj, jlong now, jobject dataStoreGetListener,
  513. jobject dataStorePutListener, jobject packetSender, jobject eventListener,
  514. jobject frameListener, jobject configListener,
  515. jobject pathChecker)
  516. {
  517. LOGV("Creating ZT_Node struct");
  518. jobject resultObject = ResultCode_RESULT_OK_enum;
  519. JavaVM *vm;
  520. GETJAVAVM(env, vm);
  521. assert(dataStoreGetListener != NULL);
  522. assert(dataStorePutListener != NULL);
  523. assert(packetSender != NULL);
  524. assert(frameListener != NULL);
  525. assert(configListener != NULL);
  526. assert(eventListener != NULL);
  527. //
  528. // OPTIONAL, pathChecker may be NULL
  529. //
  530. // assert(pathChecker != NULL);
  531. ZT_Node_Callbacks callbacks{};
  532. callbacks.stateGetFunction = &StateGetFunction;
  533. callbacks.statePutFunction = &StatePutFunction;
  534. callbacks.wirePacketSendFunction = &WirePacketSendFunction;
  535. callbacks.virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback;
  536. callbacks.virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback;
  537. callbacks.eventCallback = &EventCallback;
  538. callbacks.pathCheckFunction = &PathCheckFunction;
  539. callbacks.pathLookupFunction = &PathLookupFunction;
  540. //
  541. // a bit of a confusing dance here where ref and node both know about each other
  542. //
  543. JniRef *ref = new JniRef(
  544. now,
  545. vm,
  546. dataStoreGetListener,
  547. dataStorePutListener,
  548. packetSender,
  549. eventListener,
  550. frameListener,
  551. configListener,
  552. pathChecker);
  553. ZT_Node *node;
  554. ZT_ResultCode rc = ZT_Node_new(
  555. &node,
  556. ref,
  557. NULL,
  558. &callbacks,
  559. (int64_t)now);
  560. if(rc != ZT_RESULT_OK)
  561. {
  562. LOGE("Error creating Node: %d", rc);
  563. resultObject = createResultObject(env, rc);
  564. if (env->ExceptionCheck() || resultObject == NULL) {
  565. return NULL;
  566. }
  567. if(node)
  568. {
  569. ZT_Node_delete(node);
  570. node = NULL;
  571. }
  572. delete ref;
  573. ref = NULL;
  574. return resultObject;
  575. }
  576. //
  577. // node is now updated
  578. //
  579. ref->node = node;
  580. if (!ref->finishInitializing()) {
  581. LOGE("finishInitializing() failed");
  582. return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
  583. }
  584. return resultObject;
  585. }
  586. /*
  587. * Class: com_zerotier_sdk_Node
  588. * Method: node_isInited
  589. * Signature: (J)Z
  590. */
  591. JNIEXPORT jboolean JNICALL Java_com_zerotier_sdk_Node_node_1isInited
  592. (JNIEnv *env, jobject obj, jlong nodeId) {
  593. return isInited(nodeId);
  594. }
  595. /*
  596. * Class: com_zerotier_sdk_Node
  597. * Method: node_delete
  598. * Signature: (J)V
  599. */
  600. JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete(
  601. JNIEnv *env, jobject obj, jlong id)
  602. {
  603. LOGV("Destroying ZT_Node struct");
  604. int64_t nodeId = (int64_t)id;
  605. JniRef *ref = removeRef(nodeId);
  606. if (!ref) {
  607. return;
  608. }
  609. ZT_Node_delete(ref->node);
  610. delete ref;
  611. }
  612. /*
  613. * Class: com_zerotier_sdk_Node
  614. * Method: processVirtualNetworkFrame
  615. * Signature: (JJJJJII[B[J)Lcom/zerotier/sdk/ResultCode;
  616. */
  617. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
  618. JNIEnv *env, jobject obj,
  619. jlong id,
  620. jlong in_now,
  621. jlong in_nwid,
  622. jlong in_sourceMac,
  623. jlong in_destMac,
  624. jint in_etherType,
  625. jint in_vlanId,
  626. jbyteArray in_frameData,
  627. jlongArray out_nextBackgroundTaskDeadline)
  628. {
  629. int64_t nodeId = (int64_t) id;
  630. ZT_Node *node = findNode(nodeId);
  631. unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
  632. if(nbtd_len < 1)
  633. {
  634. // array for next background task length has 0 elements!
  635. return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
  636. }
  637. int64_t now = (int64_t)in_now;
  638. uint64_t nwid = (uint64_t)in_nwid;
  639. uint64_t sourceMac = (uint64_t)in_sourceMac;
  640. uint64_t destMac = (uint64_t)in_destMac;
  641. unsigned int etherType = (unsigned int)in_etherType;
  642. unsigned int vlanId = (unsigned int)in_vlanId;
  643. unsigned int frameLength = env->GetArrayLength(in_frameData);
  644. void *frameData = env->GetPrimitiveArrayCritical(in_frameData, NULL);
  645. void *localData = malloc(frameLength);
  646. memcpy(localData, frameData, frameLength);
  647. env->ReleasePrimitiveArrayCritical(in_frameData, frameData, 0);
  648. int64_t nextBackgroundTaskDeadline = 0;
  649. ZT_ResultCode rc = ZT_Node_processVirtualNetworkFrame(
  650. node,
  651. NULL,
  652. now,
  653. nwid,
  654. sourceMac,
  655. destMac,
  656. etherType,
  657. vlanId,
  658. (const void*)localData,
  659. frameLength,
  660. &nextBackgroundTaskDeadline);
  661. free(localData);
  662. jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
  663. outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
  664. env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
  665. return createResultObject(env, rc);
  666. }
  667. /*
  668. * Class: com_zerotier_sdk_Node
  669. * Method: processWirePacket
  670. * Signature: (JJJLjava/net/InetSocketAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
  671. */
  672. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
  673. JNIEnv *env, jobject obj,
  674. jlong id,
  675. jlong in_now,
  676. jlong in_localSocket,
  677. jobject in_remoteAddress,
  678. jbyteArray in_packetData,
  679. jlongArray out_nextBackgroundTaskDeadline)
  680. {
  681. int64_t nodeId = (int64_t) id;
  682. ZT_Node *node = findNode(nodeId);
  683. unsigned int nbtd_len = (unsigned int)env->GetArrayLength(out_nextBackgroundTaskDeadline);
  684. if(nbtd_len < 1)
  685. {
  686. LOGE("nbtd_len < 1");
  687. return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
  688. }
  689. int64_t now = (int64_t)in_now;
  690. sockaddr_storage remoteAddress = fromSocketAddressObject(env, in_remoteAddress);
  691. if (env->ExceptionCheck() || isSocketAddressEmpty(remoteAddress)) {
  692. return NULL;
  693. }
  694. unsigned int packetLength = (unsigned int)env->GetArrayLength(in_packetData);
  695. if(packetLength == 0)
  696. {
  697. LOGE("Empty packet?!?");
  698. return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
  699. }
  700. void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL);
  701. void *localData = malloc(packetLength);
  702. memcpy(localData, packetData, packetLength);
  703. env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0);
  704. int64_t nextBackgroundTaskDeadline = 0;
  705. ZT_ResultCode rc = ZT_Node_processWirePacket(
  706. node,
  707. NULL,
  708. now,
  709. in_localSocket,
  710. &remoteAddress,
  711. localData,
  712. packetLength,
  713. &nextBackgroundTaskDeadline);
  714. if(rc != ZT_RESULT_OK)
  715. {
  716. LOGE("ZT_Node_processWirePacket returned: %d", rc);
  717. }
  718. free(localData);
  719. jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
  720. outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
  721. env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
  722. return createResultObject(env, rc);
  723. }
  724. /*
  725. * Class: com_zerotier_sdk_Node
  726. * Method: processBackgroundTasks
  727. * Signature: (JJ[J)Lcom/zerotier/sdk/ResultCode;
  728. */
  729. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks(
  730. JNIEnv *env, jobject obj,
  731. jlong id,
  732. jlong in_now,
  733. jlongArray out_nextBackgroundTaskDeadline)
  734. {
  735. int64_t nodeId = (int64_t) id;
  736. ZT_Node *node = findNode(nodeId);
  737. unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
  738. if(nbtd_len < 1)
  739. {
  740. return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
  741. }
  742. int64_t now = (int64_t)in_now;
  743. int64_t nextBackgroundTaskDeadline = 0;
  744. ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, NULL, now, &nextBackgroundTaskDeadline);
  745. jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
  746. outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
  747. env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
  748. return createResultObject(env, rc);
  749. }
  750. /*
  751. * Class: com_zerotier_sdk_Node
  752. * Method: join
  753. * Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
  754. */
  755. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join(
  756. JNIEnv *env, jobject obj, jlong id, jlong in_nwid)
  757. {
  758. int64_t nodeId = (int64_t) id;
  759. ZT_Node *node = findNode(nodeId);
  760. uint64_t nwid = (uint64_t)in_nwid;
  761. ZT_ResultCode rc = ZT_Node_join(node, nwid, NULL, NULL);
  762. return createResultObject(env, rc);
  763. }
  764. /*
  765. * Class: com_zerotier_sdk_Node
  766. * Method: leave
  767. * Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
  768. */
  769. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave(
  770. JNIEnv *env, jobject obj, jlong id, jlong in_nwid)
  771. {
  772. int64_t nodeId = (int64_t) id;
  773. ZT_Node *node = findNode(nodeId);
  774. uint64_t nwid = (uint64_t)in_nwid;
  775. ZT_ResultCode rc = ZT_Node_leave(node, nwid, NULL, NULL);
  776. return createResultObject(env, rc);
  777. }
  778. /*
  779. * Class: com_zerotier_sdk_Node
  780. * Method: multicastSubscribe
  781. * Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
  782. */
  783. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe(
  784. JNIEnv *env, jobject obj,
  785. jlong id,
  786. jlong in_nwid,
  787. jlong in_multicastGroup,
  788. jlong in_multicastAdi)
  789. {
  790. int64_t nodeId = (int64_t) id;
  791. ZT_Node *node = findNode(nodeId);
  792. uint64_t nwid = (uint64_t)in_nwid;
  793. uint64_t multicastGroup = (uint64_t)in_multicastGroup;
  794. unsigned long multicastAdi = (unsigned long)in_multicastAdi;
  795. ZT_ResultCode rc = ZT_Node_multicastSubscribe(
  796. node, NULL, nwid, multicastGroup, multicastAdi);
  797. return createResultObject(env, rc);
  798. }
  799. /*
  800. * Class: com_zerotier_sdk_Node
  801. * Method: multicastUnsubscribe
  802. * Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
  803. */
  804. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe(
  805. JNIEnv *env, jobject obj,
  806. jlong id,
  807. jlong in_nwid,
  808. jlong in_multicastGroup,
  809. jlong in_multicastAdi)
  810. {
  811. int64_t nodeId = (int64_t) id;
  812. ZT_Node *node = findNode(nodeId);
  813. uint64_t nwid = (uint64_t)in_nwid;
  814. uint64_t multicastGroup = (uint64_t)in_multicastGroup;
  815. unsigned long multicastAdi = (unsigned long)in_multicastAdi;
  816. ZT_ResultCode rc = ZT_Node_multicastUnsubscribe(
  817. node, nwid, multicastGroup, multicastAdi);
  818. return createResultObject(env, rc);
  819. }
  820. /*
  821. * Class: com_zerotier_sdk_Node
  822. * Method: orbit
  823. * Signature: (JJJ)Lcom/zerotier/sdk/ResultCode;
  824. */
  825. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit(
  826. JNIEnv *env, jobject obj,
  827. jlong id,
  828. jlong in_moonWorldId,
  829. jlong in_moonSeed)
  830. {
  831. int64_t nodeId = (int64_t)id;
  832. ZT_Node *node = findNode(nodeId);
  833. uint64_t moonWorldId = (uint64_t)in_moonWorldId;
  834. uint64_t moonSeed = (uint64_t)in_moonSeed;
  835. ZT_ResultCode rc = ZT_Node_orbit(node, NULL, moonWorldId, moonSeed);
  836. return createResultObject(env, rc);
  837. }
  838. /*
  839. * Class: com_zerotier_sdk_Node
  840. * Method: deorbit
  841. * Signature: (JJ)L/com/zerotier/sdk/ResultCode;
  842. */
  843. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit(
  844. JNIEnv *env, jobject obj,
  845. jlong id,
  846. jlong in_moonWorldId)
  847. {
  848. int64_t nodeId = (int64_t)id;
  849. ZT_Node *node = findNode(nodeId);
  850. uint64_t moonWorldId = (uint64_t)in_moonWorldId;
  851. ZT_ResultCode rc = ZT_Node_deorbit(node, NULL, moonWorldId);
  852. return createResultObject(env, rc);
  853. }
  854. /*
  855. * Class: com_zerotier_sdk_Node
  856. * Method: address
  857. * Signature: (J)J
  858. */
  859. JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address(
  860. JNIEnv *env , jobject obj, jlong id)
  861. {
  862. int64_t nodeId = (int64_t) id;
  863. ZT_Node *node = findNode(nodeId);
  864. uint64_t address = ZT_Node_address(node);
  865. return (jlong)address;
  866. }
  867. /*
  868. * Class: com_zerotier_sdk_Node
  869. * Method: status
  870. * Signature: (J)Lcom/zerotier/sdk/NodeStatus;
  871. */
  872. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
  873. (JNIEnv *env, jobject obj, jlong id)
  874. {
  875. int64_t nodeId = (int64_t) id;
  876. ZT_Node *node = findNode(nodeId);
  877. ZT_NodeStatus nodeStatus;
  878. ZT_Node_status(node, &nodeStatus);
  879. return newNodeStatus(env, nodeStatus);
  880. }
  881. /*
  882. * Class: com_zerotier_sdk_Node
  883. * Method: networkConfig
  884. * Signature: (JJ)Lcom/zerotier/sdk/VirtualNetworkConfig;
  885. */
  886. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig(
  887. JNIEnv *env, jobject obj, jlong id, jlong nwid)
  888. {
  889. int64_t nodeId = (int64_t) id;
  890. ZT_Node *node = findNode(nodeId);
  891. ZT_VirtualNetworkConfig *vnetConfig = ZT_Node_networkConfig(node, nwid);
  892. jobject vnetConfigObject = newNetworkConfig(env, *vnetConfig);
  893. ZT_Node_freeQueryResult(node, vnetConfig);
  894. return vnetConfigObject;
  895. }
  896. /*
  897. * Class: com_zerotier_sdk_Node
  898. * Method: version
  899. * Signature: ()Lcom/zerotier/sdk/Version;
  900. */
  901. JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version(
  902. JNIEnv *env, jobject obj)
  903. {
  904. int major = 0;
  905. int minor = 0;
  906. int revision = 0;
  907. ZT_version(&major, &minor, &revision);
  908. return newVersion(env, major, minor, revision);
  909. }
  910. /*
  911. * Class: com_zerotier_sdk_Node
  912. * Method: peers
  913. * Signature: (J)[Lcom/zerotier/sdk/Peer;
  914. */
  915. JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
  916. JNIEnv *env, jobject obj, jlong id)
  917. {
  918. int64_t nodeId = (int64_t) id;
  919. ZT_Node *node = findNode(nodeId);
  920. ZT_PeerList *peerList = ZT_Node_peers(node);
  921. if(peerList == NULL)
  922. {
  923. LOGE("ZT_Node_peers returned NULL");
  924. return NULL;
  925. }
  926. jobjectArray peerArrayObj = newPeerArray(env, peerList->peers, peerList->peerCount);
  927. ZT_Node_freeQueryResult(node, peerList);
  928. peerList = NULL;
  929. return peerArrayObj;
  930. }
  931. /*
  932. * Class: com_zerotier_sdk_Node
  933. * Method: networks
  934. * Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig;
  935. */
  936. JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
  937. JNIEnv *env, jobject obj, jlong id)
  938. {
  939. int64_t nodeId = (int64_t) id;
  940. ZT_Node *node = findNode(nodeId);
  941. ZT_VirtualNetworkList *networkList = ZT_Node_networks(node);
  942. if(networkList == NULL)
  943. {
  944. return NULL;
  945. }
  946. jobjectArray networkListObject = newVirtualNetworkConfigArray(env, networkList->networks, networkList->networkCount);
  947. ZT_Node_freeQueryResult(node, networkList);
  948. return networkListObject;
  949. }
  950. #ifdef __cplusplus
  951. } // extern "C"
  952. #endif