Node.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  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. package com.zerotier.sdk;
  28. import java.net.InetSocketAddress;
  29. import java.util.ArrayList;
  30. import java.io.IOException;
  31. /**
  32. * A ZeroTier One node
  33. */
  34. public class Node {
  35. static {
  36. try {
  37. System.loadLibrary("ZeroTierOneJNI");
  38. } catch (UnsatisfiedLinkError e) {
  39. try {
  40. if(System.getProperty("os.name").startsWith("Windows")) {
  41. System.out.println("Arch: " + System.getProperty("sun.arch.data.model"));
  42. if(System.getProperty("sun.arch.data.model").equals("64")) {
  43. NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win64.dll");
  44. } else {
  45. NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win32.dll");
  46. }
  47. } else if(System.getProperty("os.name").startsWith("Mac")) {
  48. NativeUtils.loadLibraryFromJar("/lib/libZeroTierOneJNI.jnilib");
  49. } else {
  50. // TODO: Linux
  51. }
  52. } catch (IOException ioe) {
  53. ioe.printStackTrace();
  54. }
  55. }
  56. }
  57. private static final String TAG = "NODE";
  58. /**
  59. * Node ID for JNI purposes.
  60. * Currently set to the now value passed in at the constructor
  61. */
  62. private final long nodeId;
  63. /**
  64. * Create a new ZeroTier One node
  65. *
  66. * @param now Current clock in milliseconds
  67. */
  68. public Node(long now) {
  69. this.nodeId = now;
  70. }
  71. /**
  72. * Init a new ZeroTier One node
  73. *
  74. * <p>Note that this can take a few seconds the first time it's called, as it
  75. * will generate an identity.</p>
  76. *
  77. * @param getListener User written instance of the {@link DataStoreGetListener} interface called to get objects from persistent storage. This instance must be unique per Node object.
  78. * @param putListener User written instance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
  79. * @param sender User written instance of the {@link PacketSender} interface to send ZeroTier packets out over the wire.
  80. * @param eventListener User written instance of the {@link EventListener} interface to receive status updates and non-fatal error notices. This instance must be unique per Node object.
  81. * @param frameListener User written instance of the {@link VirtualNetworkFrameListener} interface to send a frame out to a virtual network port.
  82. * @param configListener User written instance of the {@link VirtualNetworkConfigListener} interface to be called when virtual LANs are created, deleted, or their config parameters change. This instance must be unique per Node object.
  83. * @param pathChecker User written instance of the {@link PathChecker} interface. Not required and can be null.
  84. */
  85. public ResultCode init(
  86. DataStoreGetListener getListener,
  87. DataStorePutListener putListener,
  88. PacketSender sender,
  89. EventListener eventListener,
  90. VirtualNetworkFrameListener frameListener,
  91. VirtualNetworkConfigListener configListener,
  92. PathChecker pathChecker) throws NodeException {
  93. ResultCode rc = node_init(
  94. nodeId,
  95. getListener,
  96. putListener,
  97. sender,
  98. eventListener,
  99. frameListener,
  100. configListener,
  101. pathChecker);
  102. if(rc != ResultCode.RESULT_OK) {
  103. throw new NodeException(rc.toString());
  104. }
  105. return rc;
  106. }
  107. public boolean isInited() {
  108. return node_isInited(nodeId);
  109. }
  110. /**
  111. * Close this Node.
  112. *
  113. * <p>The Node object can no longer be used once this method is called.</p>
  114. */
  115. public void close() {
  116. node_delete(nodeId);
  117. }
  118. @Override
  119. protected void finalize() {
  120. close();
  121. }
  122. /**
  123. * Process a frame from a virtual network port
  124. *
  125. * @param now Current clock in milliseconds
  126. * @param nwid ZeroTier 64-bit virtual network ID
  127. * @param sourceMac Source MAC address (least significant 48 bits)
  128. * @param destMac Destination MAC address (least significant 48 bits)
  129. * @param etherType 16-bit Ethernet frame type
  130. * @param vlanId 10-bit VLAN ID or 0 if none
  131. * @param frameData Frame payload data
  132. * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
  133. * @return OK (0) or error code if a fatal error condition has occurred
  134. */
  135. public ResultCode processVirtualNetworkFrame(
  136. long now,
  137. long nwid,
  138. long sourceMac,
  139. long destMac,
  140. int etherType,
  141. int vlanId,
  142. byte[] frameData,
  143. long[] nextBackgroundTaskDeadline) {
  144. return processVirtualNetworkFrame(
  145. nodeId, now, nwid, sourceMac, destMac, etherType, vlanId,
  146. frameData, nextBackgroundTaskDeadline);
  147. }
  148. /**
  149. * Process a packet received from the physical wire
  150. *
  151. * @param now Current clock in milliseconds
  152. * @param remoteAddress Origin of packet
  153. * @param packetData Packet data
  154. * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
  155. * @return OK (0) or error code if a fatal error condition has occurred
  156. */
  157. public ResultCode processWirePacket(
  158. long now,
  159. long localSocket,
  160. InetSocketAddress remoteAddress,
  161. byte[] packetData,
  162. long[] nextBackgroundTaskDeadline) {
  163. return processWirePacket(
  164. nodeId, now, localSocket, remoteAddress, packetData,
  165. nextBackgroundTaskDeadline);
  166. }
  167. /**
  168. * Perform periodic background operations
  169. *
  170. * @param now Current clock in milliseconds
  171. * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
  172. * @return OK (0) or error code if a fatal error condition has occurred
  173. */
  174. public ResultCode processBackgroundTasks(long now, long[] nextBackgroundTaskDeadline) {
  175. return processBackgroundTasks(nodeId, now, nextBackgroundTaskDeadline);
  176. }
  177. /**
  178. * Join a network
  179. *
  180. * <p>This may generate calls to the port config callback before it returns,
  181. * or these may be deferred if a netconf is not available yet.</p>
  182. *
  183. * <p>If we are already a member of the network, nothing is done and OK is
  184. * returned.</p>
  185. *
  186. * @param nwid 64-bit ZeroTier network ID
  187. * @return OK (0) or error code if a fatal error condition has occurred
  188. */
  189. public ResultCode join(long nwid) {
  190. return join(nodeId, nwid);
  191. }
  192. /**
  193. * Leave a network
  194. *
  195. * <p>If a port has been configured for this network this will generate a call
  196. * to the port config callback with a NULL second parameter to indicate that
  197. * the port is now deleted.</p>
  198. *
  199. * @param nwid 64-bit network ID
  200. * @return OK (0) or error code if a fatal error condition has occurred
  201. */
  202. public ResultCode leave(long nwid) {
  203. return leave(nodeId, nwid);
  204. }
  205. /**
  206. * Subscribe to an Ethernet multicast group
  207. *
  208. * <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
  209. * broadcast address) but with an ADI equal to each IPv4 address in host
  210. * byte order. This converts ARP from a non-scalable broadcast protocol to
  211. * a scalable multicast protocol with perfect address specificity.</p>
  212. *
  213. * <p>If this is not done, ARP will not work reliably.</p>
  214. *
  215. * <p>Multiple calls to subscribe to the same multicast address will have no
  216. * effect. It is perfectly safe to do this.</p>
  217. *
  218. * <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
  219. *
  220. * @param nwid 64-bit network ID
  221. * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
  222. * @return OK (0) or error code if a fatal error condition has occurred
  223. */
  224. public ResultCode multicastSubscribe(
  225. long nwid,
  226. long multicastGroup) {
  227. return multicastSubscribe(nodeId, nwid, multicastGroup, 0);
  228. }
  229. /**
  230. * Subscribe to an Ethernet multicast group
  231. *
  232. * <p>ADI stands for additional distinguishing information. This defaults to zero
  233. * and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
  234. * and this must be done.</p>
  235. *
  236. * <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
  237. * broadcast address) but with an ADI equal to each IPv4 address in host
  238. * byte order. This converts ARP from a non-scalable broadcast protocol to
  239. * a scalable multicast protocol with perfect address specificity.</p>
  240. *
  241. * <p>If this is not done, ARP will not work reliably.</p>
  242. *
  243. * <p>Multiple calls to subscribe to the same multicast address will have no
  244. * effect. It is perfectly safe to do this.</p>
  245. *
  246. * <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
  247. *
  248. * @param nwid 64-bit network ID
  249. * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
  250. * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
  251. * @return OK (0) or error code if a fatal error condition has occurred
  252. */
  253. public ResultCode multicastSubscribe(
  254. long nwid,
  255. long multicastGroup,
  256. long multicastAdi) {
  257. return multicastSubscribe(nodeId, nwid, multicastGroup, multicastAdi);
  258. }
  259. /**
  260. * Unsubscribe from an Ethernet multicast group (or all groups)
  261. *
  262. * <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
  263. * you are not subscribed to a group this has no effect.</p>
  264. *
  265. * <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
  266. *
  267. * @param nwid 64-bit network ID
  268. * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
  269. * @return OK (0) or error code if a fatal error condition has occurred
  270. */
  271. public ResultCode multicastUnsubscribe(
  272. long nwid,
  273. long multicastGroup) {
  274. return multicastUnsubscribe(nodeId, nwid, multicastGroup, 0);
  275. }
  276. /**
  277. * Unsubscribe from an Ethernet multicast group (or all groups)
  278. *
  279. * <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
  280. * you are not subscribed to a group this has no effect.</p>
  281. *
  282. * <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
  283. *
  284. * <p>ADI stands for additional distinguishing information. This defaults to zero
  285. * and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
  286. * and this must be done.</p>
  287. *
  288. * @param nwid 64-bit network ID
  289. * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
  290. * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
  291. * @return OK (0) or error code if a fatal error condition has occurred
  292. */
  293. public ResultCode multicastUnsubscribe(
  294. long nwid,
  295. long multicastGroup,
  296. long multicastAdi) {
  297. return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
  298. }
  299. /**
  300. * Add or update a moon
  301. *
  302. * Moons are persisted in the data store in moons.d/, so this can persist
  303. * across invocations if the contents of moon.d are scanned and orbit is
  304. * called for each on startup.
  305. *
  306. * @param moonWorldId Moon's world ID
  307. * @param moonSeed If non-zero, the ZeroTier address of any member of the moon to query for moon definition
  308. * @return Error if moon was invalid or failed to be added
  309. */
  310. public ResultCode orbit(
  311. long moonWorldId,
  312. long moonSeed) {
  313. return orbit(nodeId, moonWorldId, moonSeed);
  314. }
  315. /**
  316. * Remove a moon (does nothing if not present)
  317. *
  318. * @param moonWorldId World ID of moon to remove
  319. * @return Error if anything bad happened
  320. */
  321. public ResultCode deorbit(
  322. long moonWorldId) {
  323. return deorbit(nodeId, moonWorldId);
  324. }
  325. /**
  326. * Get this node's 40-bit ZeroTier address
  327. *
  328. * @return ZeroTier address (least significant 40 bits of 64-bit int)
  329. */
  330. public long address() {
  331. return address(nodeId);
  332. }
  333. /**
  334. * Get the status of this node
  335. *
  336. * @return @{link NodeStatus} struct with the current node status.
  337. */
  338. public NodeStatus status() {
  339. return status(nodeId);
  340. }
  341. /**
  342. * Get a list of known peer nodes
  343. *
  344. * @return List of known peers or NULL on failure
  345. */
  346. public Peer[] peers() {
  347. return peers(nodeId);
  348. }
  349. /**
  350. * Get the status of a virtual network
  351. *
  352. * @param nwid 64-bit network ID
  353. * @return {@link VirtualNetworkConfig} or NULL if we are not a member of this network
  354. */
  355. public VirtualNetworkConfig networkConfig(long nwid) {
  356. return networkConfig(nodeId, nwid);
  357. }
  358. /**
  359. * Enumerate and get status of all networks
  360. *
  361. * @return List of networks or NULL on failure
  362. */
  363. public VirtualNetworkConfig[] networks() {
  364. return networks(nodeId);
  365. }
  366. /**
  367. * Get ZeroTier One version
  368. *
  369. * @return {@link Version} object with ZeroTierOne version information.
  370. */
  371. public Version getVersion() {
  372. return version();
  373. }
  374. //
  375. // function declarations for JNI
  376. //
  377. private native ResultCode node_init(
  378. long nodeId,
  379. DataStoreGetListener dataStoreGetListener,
  380. DataStorePutListener dataStorePutListener,
  381. PacketSender packetSender,
  382. EventListener eventListener,
  383. VirtualNetworkFrameListener virtualNetworkFrameListener,
  384. VirtualNetworkConfigListener virtualNetworkConfigListener,
  385. PathChecker pathChecker);
  386. private native boolean node_isInited(long nodeId);
  387. private native void node_delete(long nodeId);
  388. private native ResultCode processVirtualNetworkFrame(
  389. long nodeId,
  390. long now,
  391. long nwid,
  392. long sourceMac,
  393. long destMac,
  394. int etherType,
  395. int vlanId,
  396. byte[] frameData,
  397. long[] nextBackgroundTaskDeadline);
  398. private native ResultCode processWirePacket(
  399. long nodeId,
  400. long now,
  401. long localSocket,
  402. InetSocketAddress remoteAddress,
  403. byte[] packetData,
  404. long[] nextBackgroundTaskDeadline);
  405. private native ResultCode processBackgroundTasks(
  406. long nodeId,
  407. long now,
  408. long[] nextBackgroundTaskDeadline);
  409. private native ResultCode join(long nodeId, long nwid);
  410. private native ResultCode leave(long nodeId, long nwid);
  411. private native ResultCode multicastSubscribe(
  412. long nodeId,
  413. long nwid,
  414. long multicastGroup,
  415. long multicastAdi);
  416. private native ResultCode multicastUnsubscribe(
  417. long nodeId,
  418. long nwid,
  419. long multicastGroup,
  420. long multicastAdi);
  421. private native ResultCode orbit(
  422. long nodeId,
  423. long moonWorldId,
  424. long moonSeed);
  425. private native ResultCode deorbit(
  426. long nodeId,
  427. long moonWorldId);
  428. private native long address(long nodeId);
  429. private native NodeStatus status(long nodeId);
  430. private native VirtualNetworkConfig networkConfig(long nodeId, long nwid);
  431. private native Version version();
  432. private native Peer[] peers(long nodeId);
  433. private native VirtualNetworkConfig[] networks(long nodeId);
  434. }