diff --git a/src/java/ZeroTier.java b/src/java/ZeroTier.java deleted file mode 100644 index 7015c73..0000000 --- a/src/java/ZeroTier.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2024-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -package com.zerotier.libzt; - -import java.net.*; - -public class ZeroTier -{ - ////////////////////////////////////////////////////////////////////////////// - // Control API error codes // - ////////////////////////////////////////////////////////////////////////////// - - // Everything is ok - public static int ZTS_ERR_OK = 0; - // Error - public static int ZTS_ERR = -1; - // A argument provided by the user application is invalid (e.g. out of range, NULL, etc) - public static int ZTS_ERR_INVALID_ARG = -2; - // The service isn't initialized or is for some reason currently unavailable. Try again. - public static int ZTS_ERR_SERVICE = -3; - // For some reason this API operation is not permitted or doesn't make sense at this time. - public static int ZTS_ERR_INVALID_OP = -4; - // The call succeeded, but no object or relevant result was available - public static int ZTS_ERR_NO_RESULT = -5; - // General internal failure - public static int ZTS_ERR_GENERAL = -6; - - ////////////////////////////////////////////////////////////////////////////// - // Static initialization // - ////////////////////////////////////////////////////////////////////////////// - - static - { - // loads libzt.so or libzt.dylib - System.loadLibrary("zt"); - // Give the native code a reference to this VM (for callbacks) - if (init() != ZTS_ERR_OK) { - throw new ExceptionInInitializerError("JNI init() failed (see GetJavaVM())"); - } - } - - ////////////////////////////////////////////////////////////////////////////// - // Control API event codes // - ////////////////////////////////////////////////////////////////////////////// - - public static int EVENT_NONE = -1; - // Node-specific events - public static int EVENT_NODE_UP = 0; - public static int EVENT_NODE_OFFLINE = 1; - public static int EVENT_NODE_ONLINE = 2; - public static int EVENT_NODE_DOWN = 3; - public static int EVENT_NODE_IDENTITY_COLLISION = 4; - // libzt node events - public static int EVENT_NODE_UNRECOVERABLE_ERROR = 16; - public static int EVENT_NODE_NORMAL_TERMINATION = 17; - // Network-specific events - public static int EVENT_NETWORK_NOT_FOUND = 32; - public static int EVENT_NETWORK_CLIENT_TOO_OLD = 33; - public static int EVENT_NETWORK_REQUESTING_CONFIG = 34; - public static int EVENT_NETWORK_OK = 35; - public static int EVENT_NETWORK_ACCESS_DENIED = 36; - public static int EVENT_NETWORK_READY_IP4 = 37; - public static int EVENT_NETWORK_READY_IP6 = 38; - public static int EVENT_NETWORK_READY_IP4_IP6 = 39; - public static int EVENT_NETWORK_DOWN = 40; - // lwIP netif events - public static int EVENT_NETIF_UP_IP4 = 64; - public static int EVENT_NETIF_UP_IP6 = 65; - public static int EVENT_NETIF_DOWN_IP4 = 66; - public static int EVENT_NETIF_DOWN_IP6 = 67; - public static int EVENT_NETIF_REMOVED = 68; - public static int EVENT_NETIF_LINK_UP = 69; - public static int EVENT_NETIF_LINK_DOWN = 70; - public static int EVENT_NETIF_NEW_ADDRESS = 71; - // Peer events - public static int EVENT_PEER_P2P = 96; - public static int EVENT_PEER_RELAY = 97; - public static int EVENT_PEER_UNREACHABLE = 98; - - ////////////////////////////////////////////////////////////////////////////// - // ZeroTier Constants // - ////////////////////////////////////////////////////////////////////////////// - - public static int ZT_MAX_PEER_NETWORK_PATHS = 16; - - ////////////////////////////////////////////////////////////////////////////// - // Socket API Constants // - ////////////////////////////////////////////////////////////////////////////// - - // Socket protocol types - public static int SOCK_STREAM = 0x00000001; - public static int SOCK_DGRAM = 0x00000002; - public static int SOCK_RAW = 0x00000003; - // Socket family types - public static int AF_INET = 0x00000002; - public static int AF_INET6 = 0x0000000a; - public static int PF_INET = AF_INET; - public static int PF_INET6 = AF_INET6; - // Used as level numbers for setsockopt() and getsockopt() - public static int IPPROTO_IP = 0x00000000; - public static int IPPROTO_ICMP = 0x00000001; - public static int IPPROTO_TCP = 0x00000006; - public static int IPPROTO_UDP = 0x00000011; - public static int IPPROTO_IPV6 = 0x00000029; - public static int IPPROTO_ICMPV6 = 0x0000003a; - public static int IPPROTO_UDPLITE = 0x00000088; - public static int IPPROTO_RAW = 0x000000ff; - // send() and recv() flags - public static int MSG_PEEK = 0x00000001; - public static int MSG_WAITALL = 0x00000002; - public static int MSG_OOB = 0x00000004; - public static int MSG_DONTWAIT = 0x00000008; - public static int MSG_MORE = 0x00000010; - // fnctl() commands - public static int F_GETFL = 0x00000003; - public static int F_SETFL = 0x00000004; - // fnctl() flags - public static int O_NONBLOCK = 0x00000001; - public static int O_NDELAY = 0x00000001; - // Shutdown commands - public static int SHUT_RD = 0x00000000; - public static int SHUT_WR = 0x00000001; - public static int SHUT_RDWR = 0x00000002; - // ioctl() commands - public static int FIONREAD = 0x4008667F; - public static int FIONBIO = 0x8008667E; - // Socket level option number - public static int SOL_SOCKET = 0x00000FFF; - // Socket options - public static int SO_REUSEADDR = 0x00000004; - public static int SO_KEEPALIVE = 0x00000008; - public static int SO_BROADCAST = 0x00000020; - // Socket options - public static int SO_DEBUG = 0x00000001; // NOT YET SUPPORTED - public static int SO_ACCEPTCONN = 0x00000002; - public static int SO_DONTROUTE = 0x00000010; // NOT YET SUPPORTED - public static int SO_USELOOPBACK = 0x00000040; // NOT YET SUPPORTED - public static int SO_LINGER = 0x00000080; - public static int SO_DONTLINGER = ((int)(~SO_LINGER)); - public static int SO_OOBINLINE = 0x00000100; // NOT YET SUPPORTED - public static int SO_REUSEPORT = 0x00000200; // NOT YET SUPPORTED - public static int SO_SNDBUF = 0x00001001; // NOT YET SUPPORTED - public static int SO_RCVBUF = 0x00001002; - public static int SO_SNDLOWAT = 0x00001003; // NOT YET SUPPORTED - public static int SO_RCVLOWAT = 0x00001004; // NOT YET SUPPORTED - public static int SO_SNDTIMEO = 0x00001005; - public static int SO_RCVTIMEO = 0x00001006; - public static int SO_ERROR = 0x00001007; - public static int SO_TYPE = 0x00001008; - public static int SO_CONTIMEO = 0x00001009; // NOT YET SUPPORTED - public static int SO_NO_CHECK = 0x0000100a; - // IPPROTO_IP options - public static int IP_TOS = 0x00000001; - public static int IP_TTL = 0x00000002; - // IPPROTO_TCP options - public static int TCP_NODELAY = 0x00000001; - public static int TCP_KEEPALIVE = 0x00000002; - public static int TCP_KEEPIDLE = 0x00000003; - public static int TCP_KEEPINTVL = 0x00000004; - public static int TCP_KEEPCNT = 0x00000005; - - ////////////////////////////////////////////////////////////////////////////// - // Statistics // - ////////////////////////////////////////////////////////////////////////////// - - public static int STATS_PROTOCOL_LINK = 0; - public static int STATS_PROTOCOL_ETHARP = 1; - public static int STATS_PROTOCOL_IP = 2; - public static int STATS_PROTOCOL_UDP = 3; - public static int STATS_PROTOCOL_TCP = 4; - public static int STATS_PROTOCOL_ICMP = 5; - public static int STATS_PROTOCOL_IP_FRAG = 6; - public static int STATS_PROTOCOL_IP6 = 7; - public static int STATS_PROTOCOL_ICMP6 = 8; - public static int STATS_PROTOCOL_IP6_FRAG = 9; - - public static native int get_protocol_stats(int protocolNum, ZeroTierProtoStats stats); - - ////////////////////////////////////////////////////////////////////////////// - // ZeroTier Service Controls // - ////////////////////////////////////////////////////////////////////////////// - - public static native int start(String path, ZeroTierEventListener callbackClass, int port); - public static native int stop(); - public static native int restart(); - public static native int join(long nwid); - public static native int leave(long nwid); - public static native long get_node_id(); - public static native int get_num_assigned_addresses(long nwid); - public static native void get_6plane_addr(long nwid, long nodeId, ZeroTierSocketAddress addr); - public static native void get_rfc4193_addr(long nwid, long nodeId, ZeroTierSocketAddress addr); - public static native int get_node_status(); - public static native int get_network_status(long networkId); - public static native int get_peer_status(long peerId); - public static native int get_peer(long peerId, ZeroTierPeerDetails details); - - ////////////////////////////////////////////////////////////////////////////// - // Socket API // - ////////////////////////////////////////////////////////////////////////////// - - public static native int socket(int family, int type, int protocol); - public static native int connect(int fd, ZeroTierSocketAddress addr); - public static native int bind(int fd, ZeroTierSocketAddress addr); - public static native int listen(int fd, int backlog); - public static native int accept(int fd, ZeroTierSocketAddress addr); - public static native int accept4(int fd, String addr, int port); - - public static native int setsockopt(int fd, int level, int optname, ZeroTierSocketOptionValue optval); - public static native int getsockopt(int fd, int level, int optname, ZeroTierSocketOptionValue optval); - - public static native int read(int fd, byte[] buf); - public static native int read_offset(int fd, byte[] buf, int offset, int len); - public static native int read_length(int fd, byte[] buf, int len); - public static native int recv(int fd, byte[] buf, int flags); - public static native int recvfrom(int fd, byte[] buf, int flags, ZeroTierSocketAddress addr); - - public static native int write(int fd, byte[] buf); - public static native int write_byte(int fd, byte b); - public static native int write_offset(int fd, byte[] buf, int offset, int len); - public static native int sendto(int fd, byte[] buf, int flags, ZeroTierSocketAddress addr); - public static native int send(int fd, byte[] buf, int flags); - - public static native int shutdown(int fd, int how); - public static native int close(int fd); - - public static native boolean getsockname(int fd, ZeroTierSocketAddress addr); - public static native int getpeername(int fd, ZeroTierSocketAddress addr); - public static native int fcntl(int sock, int cmd, int flag); - public static native int ioctl(int fd, long request, ZeroTierIoctlArg arg); - public static native int select(int nfds, ZeroTierFileDescriptorSet readfds, ZeroTierFileDescriptorSet writefds, ZeroTierFileDescriptorSet exceptfds, int timeout_sec, int timeout_usec); - - ////////////////////////////////////////////////////////////////////////////// - // Internal - Do not call // - ////////////////////////////////////////////////////////////////////////////// - - public static native int init(); // Only to be called by static initializer of this class -} diff --git a/src/java/ZeroTierEventListener.java b/src/java/ZeroTierEventListener.java deleted file mode 100644 index fd5e54e..0000000 --- a/src/java/ZeroTierEventListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.zerotier.libzt; - -public interface ZeroTierEventListener { - - /* - * Called when an even occurs in the native section of the ZeroTier library service - */ - public void onZeroTierEvent(long nwid, int eventCode); -} \ No newline at end of file diff --git a/src/java/ZeroTierFileDescriptorSet.java b/src/java/ZeroTierFileDescriptorSet.java deleted file mode 100644 index 000902b..0000000 --- a/src/java/ZeroTierFileDescriptorSet.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.zerotier.libzt; - -public class ZeroTierFileDescriptorSet -{ - byte[] fds_bits = new byte[1024]; - - public void CLR(int fd) - { - fds_bits[fd] = 0x00; - } - - public boolean ISSET(int fd) - { - return fds_bits[fd] == 0x01; - } - - public void SET(int fd) - { - fds_bits[fd] = 0x01; - } - - public void ZERO() - { - for (int i=0; i<1024; i++) { - fds_bits[i] = 0x00; - } - } -} \ No newline at end of file diff --git a/src/java/ZeroTierInputStream.java b/src/java/ZeroTierInputStream.java deleted file mode 100644 index 7a02d3a..0000000 --- a/src/java/ZeroTierInputStream.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.io.*; -import java.util.Objects; - -public class ZeroTierInputStream extends InputStream -{ - private static final int MAX_SKIP_BUFFER_SIZE = 2048; - private static final int DEFAULT_BUFFER_SIZE = 8192; - - /* - * File descriptor used by lower native layer - */ - int zfd; - - /* - * - */ - public int available() - throws IOException - { - return 0; // NOT YET SUPPORTED - } - - /* - * - */ - public void close​() - throws IOException - { - /* Note: this operation currently only stops RX on a socket that is shared - between both I/OStreams. This means that closing this stream will only shutdown - that aspect of the socket but not actually close it and free resources. Resources - will be properly freed when the socket implementation's close() is called or if - both I/OStreams are closed separately */ - ZeroTier.shutdown(zfd, ZeroTier.SHUT_RD); - zfd = -1; - } - - /* - * - */ - public void mark​(int readlimit) - { - System.err.println("mark​: ZeroTierInputStream does not currently support this feature"); - } - - /* - * - */ - public void reset​() - throws IOException - { - System.err.println("reset​: ZeroTierInputStream does not currently support this feature"); - } - - /* - * - */ - public boolean markSupported​() - { - return false; // mark() is not supported - } - - /* - * - */ - public long transferTo​(OutputStream out) - throws IOException - { - Objects.requireNonNull(out, "out must not be null"); - int bytesTransferred = 0, bytesRead; - byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; - while (((bytesRead = ZeroTier.read(zfd, buf)) >= 0)) { - out.write(buf, 0, bytesRead); - bytesTransferred += bytesRead; - } - return bytesTransferred; - } - - /* - * - */ - public int read​() - throws IOException - { - byte[] buf = new byte[1]; - // Unlike a native read(), if nothing is read we should return -1 - int retval = ZeroTier.read(zfd, buf); - if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) { - return -1; - } - if (retval < 0) { - throw new IOException("read​(), errno="+retval); - } - return buf[0]; - } - - /* - * - */ - public int read​(byte[] b) - throws IOException - { - Objects.requireNonNull(b, "input byte array must not be null"); - // Unlike a native read(), if nothing is read we should return -1 - int retval = ZeroTier.read(zfd, b); - if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) { - return -1; - } - if (retval < 0) { - throw new IOException("read​(b), errno="+retval); - } - return retval; - } - - /* - * - */ - public int read​(byte[] b, int off, int len) - throws IOException - { - Objects.requireNonNull(b, "input byte array must not be null"); - if ((off < 0) | (len < 0) | (len > b.length - off)) { - throw new IndexOutOfBoundsException("invalid argument"); - } - if (len == 0) { - return 0; - } - // Unlike a native read(), if nothing is read we should return -1 - int retval = ZeroTier.read_offset(zfd, b, off, len); - if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) { - return -1; - } - if (retval < 0) { - throw new IOException("read​(b,off,len), errno="+retval); - } - //System.out.println("readNBytes​(byte[] b, int off="+off+", int len="+len+")="+retval); - return retval; - } - - /* - * - */ - public byte[] readAllBytes​() - throws IOException - { - //System.out.println("readAllBytes​()"); - ZeroTierIoctlArg ztarg = new ZeroTierIoctlArg(); - int err = ZeroTier.ioctl(zfd, ZeroTier.FIONREAD, ztarg); - byte[] buf = new byte[ztarg.integer]; - int retval = ZeroTier.read(zfd, buf); - if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) { - // No action needed - } - if (retval < 0) { - throw new IOException("readAllBytes​(b,off,len), errno="+retval); - } - return buf; - } - - /* - * - */ - public int readNBytes​(byte[] b, int off, int len) - throws IOException - { - Objects.requireNonNull(b, "input byte array must not be null"); - if ((off < 0) | (len < 0) | (len > b.length - off)) { - throw new IndexOutOfBoundsException("invalid argument"); - } - if (len == 0) { - return 0; - } - int retval = ZeroTier.read_offset(zfd, b, off, len); - if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) { - // No action needed - } - if (retval < 0) { - throw new IOException("readNBytes​(b,off,len), errno="+retval); - } - //System.out.println("readNBytes​(byte[] b, int off="+off+", int len="+len+")="+retval); - return retval; - } - - /* - * - */ - public long skip​(long n) - throws IOException - { - //System.out.println("skip()"); - if (n <= 0) { - return 0; - } - long bytesRemaining = n, bytesRead; - int bufSize = (int)Math.min(MAX_SKIP_BUFFER_SIZE, bytesRemaining); - byte[] buf = new byte[bufSize]; - while (bytesRemaining > 0) { - if ((bytesRead = ZeroTier.read_length(zfd, buf, (int)Math.min(bufSize, bytesRemaining))) < 0) { - break; - } - bytesRemaining -= bytesRead; - } - return n - bytesRemaining; // skipped - } -} \ No newline at end of file diff --git a/src/java/ZeroTierIoctlArg.java b/src/java/ZeroTierIoctlArg.java deleted file mode 100644 index 54c6131..0000000 --- a/src/java/ZeroTierIoctlArg.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.zerotier.libzt; - -public class ZeroTierIoctlArg -{ - int integer; // General integer to be used or updated by the zts_ioctl() call -} \ No newline at end of file diff --git a/src/java/ZeroTierOutputStream.java b/src/java/ZeroTierOutputStream.java deleted file mode 100644 index dd39a8a..0000000 --- a/src/java/ZeroTierOutputStream.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.io.*; -import java.util.Arrays; -import java.util.Objects; - -class ZeroTierOutputStream extends OutputStream -{ - /* - * File descriptor used by lower native layer - */ - int zfd; - - /* - * - */ - public void flush() - throws IOException - { - // System.err.println("flush: ZeroTierOutputStream does not currently support this feature"); - // Not fully supported since we don't maintain a buffer - } - - /* - * - */ - public void close() - throws IOException - { - /* Note: this operation currently only stops RX on a socket that is shared - between both I/OStreams. This means that closing this stream will only shutdown - that aspect of the socket but not actually close it and free resources. Resources - will be properly freed when the socket implementation's close() is called or if - both I/OStreams are closed separately */ - ZeroTier.shutdown(zfd, ZeroTier.SHUT_WR); - zfd = -1; - } - - /* - * - */ - public void write(byte[] b) - throws IOException - { - int err = ZeroTier.write(zfd, b); - if (err < 0) { - throw new IOException("write(b[]), errno="+err); - } - } - - /* - * - */ - public void write(byte[] b, int off, int len) - throws IOException - { - Objects.requireNonNull(b, "input byte array must not be null"); - if ((off < 0) | (len < 0) | (off+len > b.length)) { - throw new IndexOutOfBoundsException("write(b,off,len)"); - } - int err = ZeroTier.write_offset(zfd, b, off, len); - if (err < 0) { - throw new IOException("write(b[],off,len), errno="+err); - } - } - - /* - * - */ - public void write(int b) - throws IOException - { - byte lowByte = (byte)(b & 0xFF); - int err = ZeroTier.write_byte(zfd, lowByte); - if (err < 0) { - throw new IOException("write(b), errno="+err); - } - } -} \ No newline at end of file diff --git a/src/java/ZeroTierPeerDetails.java b/src/java/ZeroTierPeerDetails.java deleted file mode 100644 index 49e8383..0000000 --- a/src/java/ZeroTierPeerDetails.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZeroTierSocketAddress; - -public class ZeroTierPeerDetails -{ - /** - * ZeroTier address (40 bits) - */ - public long address; - - /** - * Remote major version or -1 if not known - */ - public int versionMajor; - - /** - * Remote minor version or -1 if not known - */ - public int versionMinor; - - /** - * Remote revision or -1 if not known - */ - public int versionRev; - - /** - * Last measured latency in milliseconds or -1 if unknown - */ - public int latency; - - /** - * What trust hierarchy role does this device have? - */ - public int role; - - /** - * Number of paths (size of paths[]) - */ - public int pathCount; - - /** - * Known network paths to peer - */ - public ZeroTierSocketAddress[] paths = new ZeroTierSocketAddress[ZeroTier.ZT_MAX_PEER_NETWORK_PATHS]; -} \ No newline at end of file diff --git a/src/java/ZeroTierProtoStats.java b/src/java/ZeroTierProtoStats.java deleted file mode 100644 index 6070dd0..0000000 --- a/src/java/ZeroTierProtoStats.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -public class ZeroTierProtoStats -{ - public int xmit; /* Transmitted packets. */ - public int recv; /* Received packets. */ - public int fw; /* Forwarded packets. */ - public int drop; /* Dropped packets. */ - public int chkerr; /* Checksum error. */ - public int lenerr; /* Invalid length error. */ - public int memerr; /* Out of memory error. */ - public int rterr; /* Routing error. */ - public int proterr; /* Protocol error. */ - public int opterr; /* Error in options. */ - public int err; /* Misc error. */ - public int cachehit; -} \ No newline at end of file diff --git a/src/java/ZeroTierSSLSocketFactory.java b/src/java/ZeroTierSSLSocketFactory.java deleted file mode 100644 index 2930f7a..0000000 --- a/src/java/ZeroTierSSLSocketFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTierSocket; - -import java.net.*; -import javax.net.SocketFactory; -import java.io.IOException; -import java.io.InputStream; -import java.security.*; -import java.util.Locale; - -import javax.net.ssl.SSLSocketFactory; - -public class ZeroTierSSLSocketFactory extends SSLSocketFactory -{ - private final SSLSocketFactory delegate; - - /* - * - */ - public ZeroTierSSLSocketFactory(SSLSocketFactory delegate) - { - this.delegate = delegate; - } - - /* - * - */ - public Socket createSocket(Socket s, String host, int port, boolean autoClose) - throws IOException - { - ZeroTierSocket zs = new ZeroTierSocket(); - zs.connect((SocketAddress)new InetSocketAddress(host, port), 10); - return delegate.createSocket(zs, host, port, autoClose); - } - - /* - * - */ - public Socket createSocket(Socket s, InputStream consumed, boolean autoClose) - throws IOException - { - throw new UnsupportedOperationException(); - } - - /* - * - */ - public Socket createSocket(InetAddress a,int b,InetAddress c,int d) - throws IOException - { - ZeroTierSocket s = new ZeroTierSocket(); - return delegate.createSocket(a, b, c, d); - } - - /* - * - */ - public Socket createSocket(InetAddress a,int b) - throws IOException - { - ZeroTierSocket s = new ZeroTierSocket(); - return delegate.createSocket(a, b); - } - - /* - * - */ - public Socket createSocket(String a,int b,InetAddress c,int d) - throws IOException - { - ZeroTierSocket s = new ZeroTierSocket(); - return delegate.createSocket(a, b, c, d); - } - - /* - * - */ - public Socket createSocket(String a,int b) - throws IOException - { - ZeroTierSocket s = new ZeroTierSocket(); - return delegate.createSocket(a, b); - } - - /* - * - */ - public String [] getSupportedCipherSuites() - { - return new String[0]; - } - - /* - * - */ - public String [] getDefaultCipherSuites() - { - return new String[0]; - } -} diff --git a/src/java/ZeroTierSocket.java b/src/java/ZeroTierSocket.java deleted file mode 100644 index 4ccebb5..0000000 --- a/src/java/ZeroTierSocket.java +++ /dev/null @@ -1,748 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZeroTierSocketAddress; -import com.zerotier.libzt.ZeroTierSocketImpl; -import com.zerotier.libzt.ZeroTierSocketImplFactory; -import com.zerotier.libzt.ZeroTierInputStream; -import com.zerotier.libzt.ZeroTierOutputStream; - -import java.io.*; -import java.net.*; -import java.util.Objects; -import java.nio.channels.SocketChannel; -import java.net.InetAddress; - -public class ZeroTierSocket extends Socket -{ - /* - * Factory designated to create the underlying ZeroTierSocket implementation - */ - static ZeroTierSocketImplFactory factory = new ZeroTierSocketImplFactory(); - - /* - * Underlying implementation of this ZeroTierSocket - */ - ZeroTierSocketImpl impl; - - /* - * Misc. state flags - */ - private boolean created = false; - private boolean closed = false; - private boolean connected = false; - private boolean bound = false; - private boolean inputShutdown = false; - private boolean outputShutdown = false; - - /* - * Creates and sets the implementation - */ - void setImpl() - { - if (factory != null) { - impl = factory.createSocketImpl(); - } - if (impl != null) { - impl.setSocket(this); - } - } - - /* - * Returns the underlying socket implementation - */ - private ZeroTierSocketImpl getImpl() - throws SocketException - { - if (!created) { - try { - impl.create(true); - } - catch (IOException ex) { - throw (SocketException) new SocketException().initCause(ex); - } - created = true; - } - return impl; - } - - /* - * Create the underlying socket implementation - */ - void createImpl(boolean stream) - throws SocketException - { - if (impl == null) { - setImpl(); - } - try { - impl.create(stream); - created = true; - } - catch (IOException ex) { - throw new SocketException(ex.getMessage()); - } - } - - /* - * Constructor for ZeroTierSocket - */ - public ZeroTierSocket() - throws IOException - { - this((InetAddress)null, 0, null, 0); - } - - /* - * Creates an unconnected socket - */ - protected ZeroTierSocket(ZeroTierSocketImpl impl) - throws SocketException - { - this.impl = impl; - if (impl != null) { - this.impl.setSocket(this); - } - } - - /* - * Constructor for ZeroTierSocket - */ - public ZeroTierSocket(InetAddress raddr, int rport, InetAddress laddr, int lport) - throws IOException - { - setImpl(); - - try { - if (laddr != null) { - bind(new InetSocketAddress(laddr, lport)); - } - if (raddr != null) { - connect(new InetSocketAddress(raddr, rport)); - } - } - catch (Exception ex) - { - try { - close(); - } - catch (IOException _ex) { - ex.addSuppressed(_ex); - } - throw ex; - } - } - - /* - * Constructor for ZeroTierSocket - */ - public ZeroTierSocket(InetAddress address, int port) - throws IOException - { - this(address, port, null, 0); - } - - /* - * Constructor for ZeroTierSocket - */ - public ZeroTierSocket(String address, int port) - throws IOException - { - this(InetAddress.getByName(address), port, null, 0); - } - - /* - * Constructor for ZeroTierSocket - */ - public ZeroTierSocket(String address, int port, InetAddress localHost, int localPort) - throws IOException - { - this(InetAddress.getByName(address), port, localHost, localPort); - } - - /* - * Binds the socket to a local address - */ - public void bind(SocketAddress localAddr) - throws IOException - { - if (isSocketBound()) { - throw new SocketException("bind: ZeroTierSocket is already bound"); - } - if (isSocketClosed()) { - throw new SocketException("bind: ZeroTierSocket is closed"); - } - if (localAddr != null && (!(localAddr instanceof InetSocketAddress))) { - throw new IllegalArgumentException("bind: Unsupported address type"); - } - InetSocketAddress addr = (InetSocketAddress)localAddr; - if (addr != null && addr.isUnresolved()) { - throw new SocketException("bind: Unresolved address"); - } - if (addr == null) { - addr = new InetSocketAddress(0); - } - getImpl().bind(addr.getAddress(), addr.getPort()); - bound = true; - } - - /* - * Closes the socket - */ - public synchronized void close() - throws IOException - { - if (isSocketClosed()) { - return; - } - getOutputStream().flush(); - impl.close(); - closed = true; - } - - /* - * Connects the socket to a remote address - */ - public void connect(SocketAddress remoteAddr) - throws IOException - { - connect(remoteAddr, 0); - } - - /* - * Connects the socket to a remote address - */ - public void connect(SocketAddress remoteAddr, int timeout) - throws IOException - { - if (isSocketClosed()) { - throw new SocketException("connect: ZeroTierSocket is closed"); - } - if (isSocketConnected()) { - throw new SocketException("connect: already connected"); - } - if (remoteAddr == null) { - throw new IllegalArgumentException("connect: The address can't be null"); - } - if (!(remoteAddr instanceof InetSocketAddress)) { - throw new IllegalArgumentException("connect: Unsupported address type"); - } - if (timeout < 0) { - throw new IllegalArgumentException("connect: timeout cannot be negative"); - } - if (!created) { - createImpl(true); - } - getImpl().connect(remoteAddr, 0); - bound = true; - connected = true; - } - - /* - * Returns the associated Channel - */ - public SocketChannel getChannel​() - { - System.err.println("getChannel​: ZeroTierSocket does not currently support this feature"); - return null; - } - - /* - * Returns the address to which the socket is connected - */ - public InetAddress getInetAddress​() - { - if (!isSocketConnected()) { - return null; - } - try { - return getImpl().getInetAddress(); - } - catch (SocketException ex) { - // Not Reachable - } - return null; - } - - /* - * Returns the input stream - */ - public ZeroTierInputStream getInputStream() - throws IOException - { - if (!isSocketConnected()) { - throw new SocketException("ZeroTierSocket is not connected"); - } - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (isInputStreamShutdown()) { - throw new SocketException("ZeroTierSocket input is shutdown"); - } - return getImpl().getInputStream(); - } - - /* - * Returns whether SO_KEEPALIVE is enabled - */ - public boolean getKeepAlive() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - return ((Boolean) getImpl().getOption(ZeroTier.SO_KEEPALIVE)).booleanValue(); - } - - /* - * Returns the local address to which the socket is bound - */ - public InetAddress getLocalAddress() - { - System.err.println("getLocalAddress: ZeroTierSocket does not currently support this feature"); - /* - // This is for backward compatibility - if (!isSocketBound()) { - return InetAddress.anyLocalAddress(); - } - InetAddress inAddr = null; - try { - inAddr = (InetAddress) getImpl().getOption(ZeroTier.SO_BINDADDR); - if (inAddr.isAnyLocalAddress()) { - inAddr = InetAddress.anyLocalAddress(); - } - } - catch (Exception ex) { - // "0.0.0.0" - inAddr = InetAddress.anyLocalAddress(); - } - return inAddr; - */ - return null; - } - - /* - * Return the local port to which the socket is bound - */ - public int getLocalPort() - { - if (!isSocketBound()) { - return -1; - } - try { - return getImpl().getLocalPort(); - } - catch(SocketException ex) { - // Unreachable - } - return -1; - } - - /* - * Returns the address of the endpoint that the socket is bound to. - */ - public SocketAddress getLocalSocketAddress() - { - if (!isSocketBound()) { - return null; - } - return new InetSocketAddress(getLocalAddress(), getLocalPort()); - } - - /* - * Returns whether SO_OOBINLINE is enabled. - */ - public boolean getOOBInline​() - throws SocketException - { - System.err.println("getOOBInline​: ZeroTierSocket does not currently support this feature"); - return false; - } - - /* - * Returns the output stream. - */ - public ZeroTierOutputStream getOutputStream() - throws IOException - { - if (!isSocketConnected()) { - throw new SocketException("ZeroTierSocket is not connected"); - } - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (isOutputStreamShutdown()) { - throw new SocketException("ZeroTierSocket output is shutdown"); - } - return getImpl().getOutputStream(); - } - - /* - * Return the remote port to which the socket is connected - */ - public int getPort() - { - if (!isSocketConnected()) { - return 0; - } - try { - return getImpl().getPort(); - } - catch (SocketException ex) { - // Not reachable - } - return -1; - } - - /* - * Returns SO_RCVBUF - */ - public synchronized int getReceiveBufferSize() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - Object opt = getImpl().getOption(ZeroTier.SO_RCVBUF); - int sz = 0; - if (opt instanceof Integer) { - sz = ((Integer)opt).intValue(); - } - return sz; - } - - /* - * Returns the remote address to which this socket is connected - */ - public SocketAddress getRemoteSocketAddress() - { - if (!isSocketConnected()) { - return null; - } - return new InetSocketAddress(getInetAddress(), getPort()); - } - - /* - * Checks whether SO_REUSEADDR is enabled. - */ - public boolean getReuseAddress() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - return ((Boolean)(getImpl().getOption(ZeroTier.SO_REUSEADDR))).booleanValue(); - } - - /* - * Returns SO_SNDBUF. - */ - public synchronized int getSendBufferSize() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - int sz = 0; - Object opt = getImpl().getOption(ZeroTier.SO_SNDBUF); - if (opt instanceof Integer) { - sz = ((Integer)opt).intValue(); - } - return sz; - } - - /* - * Returns SO_LINGER. - */ - public int getSoLinger() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - Object opt = getImpl().getOption(ZeroTier.SO_LINGER); - if (opt instanceof Integer) { - return ((Integer)opt).intValue(); - } - return -1; - } - - /* - * Returns SO_TIMEOUT. - */ - public synchronized int getSoTimeout() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - Object opt = getImpl().getOption(ZeroTier.SO_RCVTIMEO); - if (opt instanceof Integer) { - return ((Integer)opt).intValue(); - } - else { - return 0; - } - } - - /* - * Checks whether TCP_NODELAY is enabled. - */ - public boolean getTcpNoDelay() - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - return ((Boolean)getImpl().getOption(ZeroTier.TCP_NODELAY)).booleanValue(); - } - - /* - * Gets traffic class or type-of-service in the IP header for packets sent from this Socket - */ - public int getTrafficClass​() - throws SocketException - { - System.err.println("getTrafficClass​: ZeroTierSocket does not currently support this feature"); - return 0; - } - - /* - * Returns whether or not the socket is bound to a local interface. - */ - public boolean isSocketBound​() - { - return bound; - } - - /* - * Returns whether or not the socket has been closed. - */ - public boolean isSocketClosed​() - { - return closed; - } - - /* - * Returns whether or not the socket is connected to a remote host. - */ - public boolean isSocketConnected​() - { - return connected; - } - - /* - * Returns whether the input aspect of the socket has been disabled. - */ - public boolean isInputStreamShutdown​() - { - return inputShutdown; - } - - /* - * Returns whether the output aspect of the socket has been disabled. - */ - public boolean isOutputStreamShutdown​() - { - return outputShutdown; - } - - /* - * Send a byte of urgent data on the socket. - */ - public void sendUrgentData​(int data) - throws IOException - { - System.err.println("sendUrgentData​: ZeroTierSocket does not currently support this feature"); - } - - /* - * Enable or disable SO_KEEPALIVE. - */ - public void setKeepAlive(boolean on) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - getImpl().setOption(ZeroTier.SO_KEEPALIVE, Boolean.valueOf(on)); - } - - /* - * Enable or disable SO_OOBINLINE. - */ - public void setOOBInline​(boolean on) - throws SocketException - { - System.err.println("setOOBInline​: ZeroTierSocket does not currently support this feature"); - } - - /* - * Set performance preferences. - */ - public void setPerformancePreferences​(int connectionTime, int latency, int bandwidth) - { - System.err.println("setPerformancePreferences​: ZeroTierSocket does not currently support this feature"); - } - - /* - * Set SO_RCVBUF. - */ - public synchronized void setReceiveBufferSize(int size) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (size <= 0) { - throw new IllegalArgumentException("invalid receive buffer size argument"); - } - getImpl().setOption(ZeroTier.SO_RCVBUF, new Integer(size)); - } - - /* - * Enable or disable SO_REUSEADDR. - */ - public void setReuseAddress(boolean on) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - getImpl().setOption(ZeroTier.SO_REUSEADDR, Boolean.valueOf(on)); - } - - /* - * Set SO_SNDBUF. - */ - public synchronized void setSendBufferSize(int size) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (size < 0) { - throw new IllegalArgumentException("size argument cannot be negative"); - } - getImpl().setOption(ZeroTier.SO_SNDBUF, new Integer(size)); - } - - /* - * Set Socket implementation factory for all clients. - */ - public static void setSocketImplFactory​(ZeroTierSocketImplFactory fact) - throws IOException - { - if (factory != null) { - throw new SocketException("ZeroTierSocket factory is already defined"); - } - factory = fact; - } - - /* - * Enable or disable SO_LINGER time (seconds). - */ - public void setSoLinger(boolean on, int linger) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (!on) { - getImpl().setOption(ZeroTier.SO_LINGER, new Boolean(on)); - } - else { - if (linger < 0) { - throw new IllegalArgumentException("linger argument is invalid"); - } - if (linger > 0xFFFF) { - linger = 0xFFFF; - } - getImpl().setOption(ZeroTier.SO_LINGER, new Integer(linger)); - } - } - - /* - * Enable or disable SO_TIMEOUT with the specified timeout, in milliseconds. - */ - public void setSoTimeout​(int timeout) - throws SocketException - { - if (timeout < 0) { - throw new IllegalArgumentException("timeout argument cannot be negative"); - } - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - getImpl().setOption(ZeroTier.SO_RCVTIMEO, new Integer(timeout)); - } - - /* - * Enable or disable TCP_NODELAY (Nagle's algorithm). - */ - public void setTcpNoDelay(boolean on) - throws SocketException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - getImpl().setOption(ZeroTier.TCP_NODELAY, Boolean.valueOf(on)); - } - - /* - * Sets traffic class or ToS. - */ - public void setTrafficClass​(int tc) - throws SocketException - { - System.err.println("setTrafficClass​: ZeroTierSocket does not currently support this feature"); - } - - /* - * Disable the input stream for this socket. - */ - public void shutdownInput() - throws IOException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (isInputStreamShutdown()) { - throw new SocketException("ZeroTierSocket input is already shutdown"); - } - if (!isSocketConnected()) { - throw new SocketException("ZeroTierSocket is not connected"); - } - getImpl().shutdownInput(); - inputShutdown = true; - } - - /* - * Disable the output stream for this socket. - */ - public void shutdownOutput() - throws IOException - { - if (isSocketClosed()) { - throw new SocketException("ZeroTierSocket is closed"); - } - if (isOutputStreamShutdown()) { - throw new SocketException("ZeroTierSocket output is already shutdown"); - } - if (!isSocketConnected()) { - throw new SocketException("ZeroTierSocket is not connected"); - } - getImpl().shutdownOutput(); - outputShutdown = true; - } - - /* - * Gets the underlying implementation's file descriptor. - */ - /* - public FileDescriptor getFileDescriptor() - { - return impl.getFileDescriptor(); - } - */ -} \ No newline at end of file diff --git a/src/java/ZeroTierSocketAddress.java b/src/java/ZeroTierSocketAddress.java deleted file mode 100644 index e773c09..0000000 --- a/src/java/ZeroTierSocketAddress.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.net.InetAddress; - -// Designed to transport address information across the JNI boundary -public class ZeroTierSocketAddress -{ - public byte[] _ip6 = new byte[16]; - public byte[] _ip4 = new byte[4]; - - public int _family; - public int _port; // Also reused for netmask or prefix - - public ZeroTierSocketAddress() {} - - public ZeroTierSocketAddress(String ipStr, int port) - { - if(ipStr.contains(":")) { - _family = ZeroTier.AF_INET6; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip6 = ip.getAddress(); - } - catch (Exception e) { } - } - else if(ipStr.contains(".")) { - _family = ZeroTier.AF_INET; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip4 = ip.getAddress(); - } - catch (Exception e) { } - } - _port = port; - } - - public int getPort() { return _port; } - public int getNetmask() { return _port; } - public int getPrefix() { return _port; } - - public String ipString() - { - if (_family == ZeroTier.AF_INET) { - try { - InetAddress inet = InetAddress.getByAddress(_ip4); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - if (_family == ZeroTier.AF_INET6) { - try { - InetAddress inet = InetAddress.getByAddress(_ip6); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - return ""; - } - - public String toString() { return ipString() + ":" + _port; } - public String toCIDR() { return ipString() + "/" + _port; } -} diff --git a/src/java/ZeroTierSocketFactory.java b/src/java/ZeroTierSocketFactory.java deleted file mode 100644 index 0e79a65..0000000 --- a/src/java/ZeroTierSocketFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZeroTierSocket; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import javax.net.SocketFactory; -import java.util.Objects; - -public class ZeroTierSocketFactory extends SocketFactory -{ - public ZeroTierSocketFactory() { } - - public static SocketFactory getDefault() - { - return null; - } - - public Socket createSocket() - throws IOException, UnknownHostException - { - return new ZeroTierSocket(); - } - - public Socket createSocket(String host, int port) - throws IOException, UnknownHostException - { - return new ZeroTierSocket(host, port); - } - - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) - throws IOException, UnknownHostException - { - return new ZeroTierSocket(host, port, localHost, localPort); - } - - public Socket createSocket(InetAddress host, int port) - throws IOException - { - return new ZeroTierSocket(host, port); - } - - public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) - throws IOException - { - return new ZeroTierSocket(address, port, localAddress, localPort); - } -} diff --git a/src/java/ZeroTierSocketImpl.java b/src/java/ZeroTierSocketImpl.java deleted file mode 100644 index cbb21d7..0000000 --- a/src/java/ZeroTierSocketImpl.java +++ /dev/null @@ -1,771 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZeroTierSocketAddress; -import com.zerotier.libzt.ZeroTierInputStream; -import com.zerotier.libzt.ZeroTierOutputStream; -import com.zerotier.libzt.ZeroTierSocketOptionValue; - -import java.io.*; -import java.net.*; -import java.util.Objects; -import java.lang.Object; -import java.net.SocketImpl; -import java.net.InetSocketAddress; -import java.util.Set; -import java.lang.Boolean; - -import com.zerotier.libzt.ZeroTier; - -public class ZeroTierSocketImpl extends SocketImpl -{ - private int defaultProtocol = 0; - - /* - * File descriptor from lower native layer - */ - private int zfd = -1; - private int zfd4 = -1; - private int zfd6 = -1; - - /* - * Input and Output streams - */ - private ZeroTierInputStream in = new ZeroTierInputStream(); - private ZeroTierOutputStream out = new ZeroTierOutputStream(); - - Socket socket = null; - ServerSocket serverSocket = null; - - /* - * The remote address the socket is connected to - */ - protected InetAddress address; - - /* - * Sets the underlying file descriptor valud for the SocketImpl as well as the Input/OutputStream - */ - private void setNativeFileDescriptor(int fd) - { - zfd = fd; - in.zfd = fd; - out.zfd = fd; - } - - /* - * Various socket options that are cached from calls to setOption() before - * the socket exists. - */ - private int _so_rcvtimeo; - private boolean _so_keepalive; - private int _so_sndbuf; - private int _so_rcvbuf; - private boolean _so_reuseaddr; - private int _so_linger; - private int _so_tos; - private boolean _so_nodelay; - - private void setCachedSocketOptions(int fd) - { - if (fd < 0) { - return; - } - - // If we previously received a setSoTimeout() call but were unable to process it due - // to the fact that the underlying socket didn't even exist yet, do so now. - int err = 0; - ZeroTierSocketOptionValue optval = new ZeroTierSocketOptionValue(); - - try { - // SO_TIMEOUT - if (_so_rcvtimeo > 0) { - optval.isInteger = true; - optval.isBoolean = false; - optval.integerValue = ((Integer)_so_rcvtimeo).intValue(); - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_RCVTIMEO, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_RCVTIMEO"); - } - } - // SO_KEEPALIVE - if (_so_keepalive == true) { - optval.isInteger = false; - optval.isBoolean = true; - optval.booleanValue = ((Boolean)_so_keepalive).booleanValue() ? true : false; - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_KEEPALIVE, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_KEEPALIVE"); - } - } - // SO_SNDBUF - if (_so_sndbuf > 0) { - optval.isInteger = true; - optval.isBoolean = false; - optval.integerValue = ((Integer)_so_sndbuf).intValue(); - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_SNDBUF, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_SNDBUF"); - } - } - // SO_RCVBUF - if (_so_rcvbuf > 0) { - optval.isInteger = true; - optval.isBoolean = false; - optval.integerValue = ((Integer)_so_rcvbuf).intValue(); - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_RCVBUF, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_RCVBUF"); - } - } - // SO_REUSEADDR - if (_so_reuseaddr == true) { - optval.isInteger = false; - optval.isBoolean = true; - optval.booleanValue = ((Boolean)_so_reuseaddr).booleanValue() ? true : false; - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_REUSEADDR, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_REUSEADDR"); - } - } - // SO_LINGER - if (_so_linger > 0) { - optval.isInteger = true; - optval.isBoolean = false; - optval.integerValue = ((Integer)_so_linger).intValue(); - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.SO_LINGER, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached SO_LINGER"); - } - } - // IP_TOS - if (_so_tos > 0) { - optval.isInteger = true; - optval.isBoolean = false; - optval.integerValue = ((Integer)_so_tos).intValue(); - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.IP_TOS, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached IP_TOS"); - } - } - // TCP_NODELAY - if (_so_nodelay == true) { - optval.isInteger = false; - optval.isBoolean = true; - optval.booleanValue = ((Boolean)_so_nodelay).booleanValue() ? true : false; - if ((err = ZeroTier.setsockopt(fd, ZeroTier.SOL_SOCKET, ZeroTier.TCP_NODELAY, optval)) < 0) { - throw new IOException("socket("+fd+"), errno="+err+", unable to set previously cached TCP_NODELAY"); - } - } - } - catch (Exception e) { - System.err.println(e); - } - } - - /* - * Constructor which creates a new ZeroTierSocketImpl - */ - public ZeroTierSocketImpl() - { - if ((zfd > -1) | (zfd4 > -1) | (zfd6 > -1)) { return; } - try { - create(true); - } catch (Exception x) { - System.err.println("error creating ZeroTierSocketImpl instance: " + x); - } - in.zfd = zfd; - out.zfd = zfd; - } - - /* - * Constructor to be called when an underlying ZeroTier socket already exists (does not create a new ZeroTierSocketImpl) - */ - public ZeroTierSocketImpl(int fd) { - setNativeFileDescriptor(fd); - } - - /* - * Creates a new ZeroTier socket in the native layer - */ - protected void create(boolean stream) - throws IOException - { - /* - * The native-layer socket is only created once a connect/bind call is made, this is due to the fact - * that beforehand we have no way to determine whether we should create an AF_INET or AF_INET6 socket, - * as a result, this method intentionally does nothing. - */ - } - - /* - * Creates the underlying libzt socket. - * - * This does the real work that can't be done in the constructor. This is because the socket address type - * isn't known until a connect() or bind() request is given. Additionally we cache the value provided by any - * setSoTimeout() calls and implement it immediately after creation. - */ - private void createAppropriateSocketImpl(InetAddress addr) - throws IOException - { - if ((zfd > -1) | (zfd4 > -1) | (zfd6 > -1)) { - return; // Socket already created - } - if(addr instanceof Inet4Address) { - if ((zfd4 = ZeroTier.socket(ZeroTier.AF_INET, ZeroTier.SOCK_STREAM, defaultProtocol)) < 0) { - throw new IOException("socket(), errno="+zfd4+", see: libzt/ext/lwip/src/include/errno.h"); - } - setCachedSocketOptions(zfd4); - } - /* - * Since Java creates sockets capable of handling IPV4 and IPV6, we must simulate this. We do this by - * creating two sockets (one of each type) - */ - if(addr instanceof Inet6Address) { - if ((zfd4 = ZeroTier.socket(ZeroTier.AF_INET, ZeroTier.SOCK_STREAM, defaultProtocol)) < 0) { - throw new IOException("socket(), errno="+zfd4+", see: libzt/ext/lwip/src/include/errno.h"); - } - if ((zfd6 = ZeroTier.socket(ZeroTier.AF_INET6, ZeroTier.SOCK_STREAM, defaultProtocol)) < 0) { - throw new IOException("socket(), errno="+zfd6+", see: libzt/ext/lwip/src/include/errno.h"); - } - setCachedSocketOptions(zfd4); - setCachedSocketOptions(zfd6); - } - } - - /* - * Return the remote address the socket is connected to - */ - protected InetAddress getInetAddress() - { - return address; - } - - /* - * Connects the socket to a remote address - */ - protected void connect(String host, int port) - throws IOException - { - // TODO: Refactor and consolidate the connect() logic for all three methods - createAppropriateSocketImpl(InetAddress.getByName(host)); - if ((zfd4 < 0) & (zfd6 < 0)) { - throw new IOException("invalid fd"); - } - int err; - InetAddress address = InetAddress.getByName(host); - ZeroTierSocketAddress zt_addr = new ZeroTierSocketAddress(host, port); - if (address instanceof Inet4Address) { - if ((err = ZeroTier.connect(zfd4, zt_addr)) < 0) { - throw new IOException("connect(), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd4); - } - if (address instanceof Inet6Address) { - if ((err = ZeroTier.connect(zfd6, zt_addr)) < 0) { - throw new IOException("connect(), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd6); - } - super.port = port; - } - - /* - * Connects the socket to a remote address - */ - protected void connect(InetAddress address, int port) - throws IOException - { - // TODO: Refactor and consolidate the connect() logic for all three methods - createAppropriateSocketImpl(address); - if ((zfd4 < 0) & (zfd6 < 0)) { - throw new IOException("invalid fd"); - } - int err; - ZeroTierSocketAddress zt_addr = new ZeroTierSocketAddress(address.getHostAddress(), port); - if (address instanceof Inet4Address) { - if ((err = ZeroTier.connect(zfd4, zt_addr)) < 0) { - throw new IOException("connect(), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd4); - } - if (address instanceof Inet6Address) { - if ((err = ZeroTier.connect(zfd6, zt_addr)) < 0) { - throw new IOException("connect(), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd6); - } - super.port = port; - } - - /* - * Connects the socket to a remote address - */ - protected void connect(SocketAddress address, int timeout) - throws IOException - { - // TODO: Refactor and consolidate the connect() logic for all three methods - //System.out.println("host="+((InetSocketAddress)address).getHostString()+", port="+((InetSocketAddress)address).getPort() + ", timeout="+timeout); - createAppropriateSocketImpl(((InetSocketAddress)address).getAddress()); - if ((zfd4 < 0) & (zfd6 < 0)) { - throw new IOException("invalid fd"); - } - ZeroTierSocketAddress zt_addr = null; - int err; - int port = ((InetSocketAddress)address).getPort(); - if (((InetSocketAddress)address).getAddress() instanceof Inet4Address) { - zt_addr = new ZeroTierSocketAddress(((InetSocketAddress)address).getHostString(), ((InetSocketAddress)address).getPort()); - if ((err = ZeroTier.connect(zfd4, zt_addr)) < 0) { - throw new IOException("connect("+zfd4+"), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd4); - } - if (((InetSocketAddress)address).getAddress() instanceof Inet6Address) { - zt_addr = new ZeroTierSocketAddress(((InetSocketAddress)address).getHostString(), ((InetSocketAddress)address).getPort()); - if ((err = ZeroTier.connect(zfd6, zt_addr)) < 0) { - throw new IOException("connect("+zfd6+"), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - setNativeFileDescriptor(zfd6); - } - super.port = port; - } - - /* - * Binds the socket to a local address. - * - * If this gets a bind() request on [::] it will create a both an IPv4 and an IPv6 - * socket. This is because we might receive a subsequent listen() and accept() request - * and want to accept an IPv6 connection. (or) we may get a connect() request with - * an IPv4 address. In the latter case we must abandon the IPv6 socket and use the IPv4 - * socket exclusively. - */ - protected void bind(InetAddress host, int port) - throws IOException - { - createAppropriateSocketImpl(host); - /* - After this point we may have either a) created a single IPv4 socket, or b) created - an IPv4 and IPv6 socket in anticipation of either verion being used - */ - //System.out.println("host="+host.toString()+", port="+port); - int err; - if ((zfd < 0) & (zfd4 < 0) & (zfd6 < 0)) { - throw new IOException("invalid fd"); - } - ZeroTierSocketAddress zt_addr = new ZeroTierSocketAddress(host.getHostAddress(), port); - - if (zfd6 > -1) { - // Since an IPv6 socket and accept IPv4 connections we will only bind to this address - if ((err = ZeroTier.bind(zfd6, zt_addr)) < 0) { - throw new IOException("bind("+zfd6+"), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - super.localport = port; - return; - } - if (zfd4 > -1) { - // Otherwise, just bind to the regular IPv4 address - if ((err = ZeroTier.bind(zfd4, zt_addr)) < 0) { - throw new IOException("bind("+zfd4+"), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - super.localport = port; - return; - } - - } - - /* - * Puts the socket into a listening state. - * - * We listen on the IPv6 socket since it can listen for IPv4 connections - */ - protected void listen(int backlog) - throws IOException - { - int err; - if ((zfd6 < 0) | (backlog < 0)) { - throw new IOException("invalid fd and/or backlog"); - } - if ((err = ZeroTier.listen(zfd6, backlog)) < 0) { - throw new IOException("listen("+zfd6+"), errno="+err+", see: libzt/ext/lwip/src/include/errno.h"); - } - } - - /* - * Accepts an incoming connection. - * - * We accept on the IPv6 socket since it can accept IPv4 connections - */ - protected void accept(SocketImpl si) - throws IOException - { - if (zfd6 < 0) { - throw new IOException("invalid fd"); - } - int accetpedFd = -1; - ZeroTierSocketAddress addr = new ZeroTierSocketAddress(); - if ((accetpedFd = ZeroTier.accept(zfd6, addr)) < 0) { - throw new IOException("accept("+zfd6+"), errno="+accetpedFd+", see: libzt/ext/lwip/src/include/errno.h"); - } - // Give the new socket fd from the native layer to the new unconnected ZeroTierSocketImpl - ((ZeroTierSocketImpl)si).setFileDescriptor(accetpedFd); - } - - /* - * Returns the input stream for this socket - */ - protected ZeroTierInputStream getInputStream() - throws IOException - { - if (in == null) { - throw new IOException(); - } - return in; - } - - /* - * Returns the output stream for this socket - */ - protected ZeroTierOutputStream getOutputStream() - throws IOException - { - if (out == null) { - throw new IOException(); - } - return out; - } - - /* - * Returns the remote port to which this socket is connected - */ - protected int getPort() - { - return super.port; - } - - /* - * Returns the local port to which this socket is bound - */ - protected int getLocalPort() - { - return super.localport; - } - - /* - * Returns whether this socket implementation supports urgent data (hint: it doesn't) - */ - protected boolean supportsUrgentData() - { - return false; - } - - /* - * - */ - void setSocket(ZeroTierSocket soc) - { - this.socket = soc; - } - - /* - * - */ - Socket getSocket() - { - return socket; - } - - /* - * - */ - /* - void setServerSocket(ZeroTierServerSocket soc) - { - this.serverSocket = soc; - } - */ - - /* - * - */ - ServerSocket getServerSocket() - { - return serverSocket; - } - - /* - * Return the number of bytes that can be read from the socket without blocking - */ - protected int available() - throws IOException - { - // TODO - return 0; - } - - /* - * Closes the socket - */ - protected void close() - throws IOException - { - if (zfd > -1) { - ZeroTier.close(zfd); - } - if (zfd4 > -1) { - ZeroTier.close(zfd4); - } - if (zfd6 > -1) { - ZeroTier.close(zfd6); - } - } - - /* - * Send one byte of urgent data on the socket - */ - protected void sendUrgentData(int data) - throws IOException - { - System.err.println("sendUrgentData: ZeroTierSocketImpl does not currently support this feature"); - } - - /* - * Gets some specified socket option - */ - public Object getOption(int optID) - throws SocketException - { - // Call native layer - ZeroTierSocketOptionValue optval = new ZeroTierSocketOptionValue(); - int option = -1; - int level = -1; - - if (zfd < 0) { // If we haven't committed to a socket version yet, cache the value - if (optID == SocketOptions.SO_TIMEOUT || optID == ZeroTier.SO_RCVTIMEO) { - return Integer.valueOf(_so_rcvtimeo); - } - if (optID == SocketOptions.SO_KEEPALIVE || optID == ZeroTier.SO_KEEPALIVE) { - return Boolean.valueOf(_so_keepalive); - } - if (optID == SocketOptions.SO_SNDBUF || optID == ZeroTier.SO_SNDBUF) { - return Integer.valueOf(_so_sndbuf); - } - if (optID == SocketOptions.SO_RCVBUF || optID == ZeroTier.SO_RCVBUF) { - return Integer.valueOf(_so_rcvbuf); - } - if (optID == SocketOptions.SO_REUSEADDR || optID == ZeroTier.SO_REUSEADDR) { - return Boolean.valueOf(_so_reuseaddr); - } - if (optID == SocketOptions.SO_LINGER || optID == ZeroTier.SO_LINGER) { - return Integer.valueOf(_so_linger); - } - if (optID == SocketOptions.IP_TOS || optID == ZeroTier.IP_TOS) { - return Integer.valueOf(_so_tos); - } - if (optID == SocketOptions.TCP_NODELAY || optID == ZeroTier.TCP_NODELAY) { - return Boolean.valueOf(_so_nodelay); - } - } - else { - if (optID == SocketOptions.SO_TIMEOUT || optID == ZeroTier.SO_RCVTIMEO) { - option = ZeroTier.SO_RCVTIMEO; - level = ZeroTier.SOL_SOCKET; - } - if (optID == SocketOptions.SO_KEEPALIVE || optID == ZeroTier.SO_KEEPALIVE) { - option = ZeroTier.SO_KEEPALIVE; - level = ZeroTier.SOL_SOCKET; - } - if (optID == SocketOptions.SO_SNDBUF || optID == ZeroTier.SO_SNDBUF) { - option = ZeroTier.SO_SNDBUF; - level = ZeroTier.SOL_SOCKET; - } - if (optID == SocketOptions.SO_RCVBUF || optID == ZeroTier.SO_RCVBUF) { - option = ZeroTier.SO_RCVBUF; - level = ZeroTier.SOL_SOCKET; - } - if (optID == SocketOptions.SO_REUSEADDR || optID == ZeroTier.SO_REUSEADDR) { - option = ZeroTier.SO_REUSEADDR; - level = ZeroTier.SOL_SOCKET; - } - if (optID == SocketOptions.SO_LINGER || optID == ZeroTier.SO_LINGER) { - option = ZeroTier.SO_LINGER; - level = ZeroTier.SOL_SOCKET; - } - // IP - if (optID == SocketOptions.IP_TOS || optID == ZeroTier.IP_TOS) { - option = ZeroTier.IP_TOS; - level = ZeroTier.IPPROTO_IP; - } - // TCP - if (optID == SocketOptions.TCP_NODELAY || optID == ZeroTier.TCP_NODELAY) { - option = ZeroTier.TCP_NODELAY; - level = ZeroTier.IPPROTO_TCP; - } - ZeroTier.getsockopt(zfd, level, option, optval); - // Convert native layer's response into Java object of some sort - if (optval.isBoolean) { - return Boolean.valueOf(optval.booleanValue); - } - if (optval.isInteger) { - return Integer.valueOf(optval.integerValue); - } - } - return null; - } - - /* - * Sets a socket option to a specified value. This method should be able to handle SocketOptions values - * as well as native ZeroTier.* options - */ - public void setOption(int optID, Object value) - throws SocketException - { - if (value == null) { - throw new UnsupportedOperationException(); - } - - int option = -1; - int level = -1; - - ZeroTierSocketOptionValue optval = new ZeroTierSocketOptionValue(); - - if (zfd < 0) { // If we haven't committed to a socket version yet, cache the value - if (optID == SocketOptions.SO_TIMEOUT || optID == ZeroTier.SO_RCVTIMEO) { - _so_rcvtimeo = ((Integer)value).intValue(); return; - } - if (optID == SocketOptions.SO_KEEPALIVE || optID == ZeroTier.SO_KEEPALIVE) { - _so_keepalive = ((Boolean)value).booleanValue() ? true : false; return; - } - if (optID == SocketOptions.SO_SNDBUF || optID == ZeroTier.SO_SNDBUF) { - _so_sndbuf = ((Integer)value).intValue(); return; - } - if (optID == SocketOptions.SO_RCVBUF || optID == ZeroTier.SO_RCVBUF) { - _so_rcvbuf = ((Integer)value).intValue(); return; - } - if (optID == SocketOptions.SO_REUSEADDR || optID == ZeroTier.SO_REUSEADDR) { - _so_reuseaddr = ((Boolean)value).booleanValue() ? true : false; return; - } - if (optID == SocketOptions.SO_LINGER || optID == ZeroTier.SO_LINGER) { - _so_linger = ((Integer)value).intValue(); return; - } - if (optID == SocketOptions.IP_TOS || optID == ZeroTier.IP_TOS) { - _so_tos = ((Integer)value).intValue(); return; - } - if (optID == SocketOptions.TCP_NODELAY || optID == ZeroTier.TCP_NODELAY) { - _so_nodelay = ((Boolean)value).booleanValue() ? true : false; return; - } - } - else { - // SOL - if (optID == SocketOptions.SO_TIMEOUT || optID == ZeroTier.SO_RCVTIMEO) { - option = ZeroTier.SO_RCVTIMEO; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isInteger = true; - optval.integerValue = ((Integer)value).intValue(); - } - } - - if (optID == SocketOptions.SO_KEEPALIVE || optID == ZeroTier.SO_KEEPALIVE) { - option = ZeroTier.SO_KEEPALIVE; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isBoolean = true; - optval.booleanValue = ((Boolean)value).booleanValue() ? true : false; - } - } - if (optID == SocketOptions.SO_SNDBUF || optID == ZeroTier.SO_SNDBUF) { - option = ZeroTier.SO_SNDBUF; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isInteger = true; - optval.integerValue = ((Integer)value).intValue(); - } - } - if (optID == SocketOptions.SO_RCVBUF || optID == ZeroTier.SO_RCVBUF) { - option = ZeroTier.SO_RCVBUF; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isInteger = true; - optval.integerValue = ((Integer)value).intValue(); - } - } - if (optID == SocketOptions.SO_REUSEADDR || optID == ZeroTier.SO_REUSEADDR) { - option = ZeroTier.SO_REUSEADDR; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isBoolean = true; - optval.booleanValue = ((Boolean)value).booleanValue() ? true : false; - } - } - if (optID == SocketOptions.SO_LINGER || optID == ZeroTier.SO_LINGER) { - option = ZeroTier.SO_LINGER; - level = ZeroTier.SOL_SOCKET; - if (value instanceof Integer) { - optval.isInteger = true; - optval.integerValue = ((Integer)value).intValue(); - } - } - // IP - if (optID == SocketOptions.IP_TOS || optID == ZeroTier.IP_TOS) { - option = ZeroTier.IP_TOS; - level = ZeroTier.IPPROTO_IP; - if (value instanceof Integer) { - optval.isInteger = true; - optval.integerValue = ((Integer)value).intValue(); - } - } - // TCP - if (optID == SocketOptions.TCP_NODELAY || optID == ZeroTier.TCP_NODELAY) { - option = ZeroTier.TCP_NODELAY; - level = ZeroTier.IPPROTO_TCP; - if (value instanceof Integer) { - optval.isBoolean = true; - optval.booleanValue = ((Boolean)value).booleanValue() ? true : false; - } - } - - if (option < 0) { // No option was properly set - //throw new UnsupportedOperationException(); - } - ZeroTier.setsockopt(zfd, level, option, optval); - } - } - - /* - * Disables the input aspect of the socket - */ - public void shutdownInput() - { - ZeroTier.shutdown(zfd, ZeroTier.SHUT_RD); - // Alternatively: getInputStream().close(); - } - - /* - * Disables the output aspect of the socket - */ - public void shutdownOutput() - { - ZeroTier.shutdown(zfd, ZeroTier.SHUT_WR); - // Alternatively: getOutputStream().close(); - } - - /* - * Sets the file descriptor - */ - public void setFileDescriptor(int fd) - { - zfd = fd; - } - - /* - * Resets the socket - */ - void reset() - throws IOException - { - localport = 0; - address = null; - port = 0; - } -/* - public FileDescriptor getFileDescriptor() - { - // TODO: Should probably remove this for production - System.out.println("getFileDescriptor(), zfd="+zfd); - ParcelFileDescriptor pfd = ParcelFileDescriptor.adoptFd(zfd); - return pfd.getFileDescriptor(); - } -*/ -} \ No newline at end of file diff --git a/src/java/ZeroTierSocketImplFactory.java b/src/java/ZeroTierSocketImplFactory.java deleted file mode 100644 index f04bf95..0000000 --- a/src/java/ZeroTierSocketImplFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZeroTierSocketImpl; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import javax.net.SocketFactory; -import java.net.SocketImplFactory; -import java.util.Objects; - - -public class ZeroTierSocketImplFactory implements SocketImplFactory -{ - /* - * Does nothing - */ - public ZeroTierSocketImplFactory() { } - - /* - * Produces a ZeroTierSocketImpl - */ - public ZeroTierSocketImpl createSocketImpl() - { - return new ZeroTierSocketImpl(); - } -} diff --git a/src/java/ZeroTierSocketOptionValue.java b/src/java/ZeroTierSocketOptionValue.java deleted file mode 100644 index 15bbfef..0000000 --- a/src/java/ZeroTierSocketOptionValue.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.zerotier.libzt; - -public class ZeroTierSocketOptionValue -{ - public boolean isBoolean = false; - public boolean booleanValue; - - public boolean isInteger = false; - public int integerValue; - - public boolean isTimeval = false; - public int tv_sec; // seconds - public int tv_usec; // microseconds -} \ No newline at end of file