Android API update
This commit is contained in:
@@ -30,8 +30,10 @@ import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.ZipError;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
public class SDK {
|
||||
@@ -49,70 +51,178 @@ public class SDK {
|
||||
|
||||
// ZeroTier service controls
|
||||
public native void zt_start_service(String homeDir);
|
||||
public native void zt_join_network(String nwid);
|
||||
public native void zt_leave_network(String nwid);
|
||||
public native ArrayList<String> zt_get_addresses(String nwid);
|
||||
public native boolean zt_running();
|
||||
public void start_service(String homeDir) {
|
||||
zt_start_service(homeDir);
|
||||
}
|
||||
|
||||
public native void zt_join_network(String nwid);
|
||||
public void join_network(String nwid) {
|
||||
zt_join_network(nwid);
|
||||
}
|
||||
|
||||
public native void zt_leave_network(String nwid);
|
||||
public void leave_network(String nwid) {
|
||||
zt_leave_network(nwid);
|
||||
}
|
||||
|
||||
public native ArrayList<String> zt_get_addresses(String nwid);
|
||||
public ArrayList<String> get_addresses(String nwid) {
|
||||
return zt_get_addresses(nwid);
|
||||
}
|
||||
|
||||
public native int zt_get_proxy_port(String nwid);
|
||||
public int get_proxy_port(String nwid) {
|
||||
return zt_get_proxy_port(nwid);
|
||||
}
|
||||
|
||||
public native boolean zt_running();
|
||||
public boolean running() {
|
||||
return zt_running();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- socket() ---------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
// Direct-call API
|
||||
// --- These calls skip the intercept and interface directly via the RPC mechanism
|
||||
public native int zt_socket(int family, int type, int protocol);
|
||||
public int socket(int family, int type, int protocol) {
|
||||
return zt_socket(family, type, protocol);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- connect() --------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_connect(int fd, String addr, int port);
|
||||
|
||||
public int connect(int sock, ZTAddress zaddr, String nwid) {
|
||||
return connect(sock, zaddr.Address(), zaddr.Port(), nwid);
|
||||
}
|
||||
|
||||
public int connect(int sock, String addr, int port, String nwid)
|
||||
{
|
||||
int err = -1;
|
||||
ArrayList<String> addresses = new ArrayList<String>();
|
||||
while (err < 0) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
addresses = zt_get_addresses(nwid);
|
||||
if (addresses.size() > 0) {
|
||||
if(!addresses.get(0).startsWith("-1.-1.-1.-1/-1")) {
|
||||
err = zt_connect(sock, addr, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------ bind() ----------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_bind(int fd, String addr, int port);
|
||||
|
||||
public int bind(int sock, ZTAddress zaddr, String nwid) {
|
||||
return bind(sock, zaddr.Address(), zaddr.Port(), nwid);
|
||||
}
|
||||
public int bind(int sock, String addr, int port, String nwid) {
|
||||
int err = -1;
|
||||
ArrayList<String> addresses = new ArrayList<String>();
|
||||
while (err < 0) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
addresses = zt_get_addresses(nwid);
|
||||
if (addresses.size() > 0) {
|
||||
if(!addresses.get(0).startsWith("-1.-1.-1.-1/-1")) {
|
||||
err = zt_bind(sock, addr, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ---------------------------------- accept4() ---------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_accept4(int fd, String addr, int port);
|
||||
public int accept4(int fd, String addr, int port) {
|
||||
return zt_accept4(fd,addr,port);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ---------------------------------- accept() ----------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_accept(int fd, ZeroTier.ZTAddress addr);
|
||||
public int accept(int fd, ZeroTier.ZTAddress addr) {
|
||||
return zt_accept(fd, addr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- listen() ---------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_listen(int fd, int backlog);
|
||||
public int listen(int fd, int backlog) {
|
||||
return zt_listen(fd,backlog);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- close() ----------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_close(int fd);
|
||||
public int close(int fd) {
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------ read() ----------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_read(int fd, byte[] buf, int len);
|
||||
public int read(int fd, byte[] buf, int len) {
|
||||
return zt_read(fd, buf, len);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- write() ----------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_write(int fd, byte[] buf, int len);
|
||||
public int write(int fd, byte[] buf, int len) {
|
||||
return zt_write(fd, buf, len);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ----------------------------------- sendto() ---------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_sendto(int fd, byte[] buf, int len, int flags, ZeroTier.ZTAddress addr);
|
||||
public int sendto(int fd, byte[] buf, int len, int flags, ZeroTier.ZTAddress addr){
|
||||
return zt_sendto(fd,buf,len,flags,addr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// ---------------------------------- recvfrom() --------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
public native int zt_recvfrom(int fd, byte[] buf, int len, int flags, ZeroTier.ZTAddress addr);
|
||||
public int recvfrom(int fd, byte[] buf, int len, int flags, ZeroTier.ZTAddress addr){
|
||||
return zt_recvfrom(fd,buf,len,flags,addr);
|
||||
}
|
||||
|
||||
//public static native int zt_getsockopt(int fd, int type, int protocol);
|
||||
//public static native int zt_setsockopt(int fd, int type, int protocol);
|
||||
//public static native int zt_getsockname(int fd, int type, int protocol);
|
||||
public native int zt_close(int fd);
|
||||
public native int zt_read(int fd, byte[] buf, int len);
|
||||
public native int zt_write(int fd, byte[] buf, int len);
|
||||
|
||||
// --- Below is experimental
|
||||
|
||||
// Converts a numerical fd to a FileDescriptor
|
||||
public static native FileDescriptor zt_getFileDescriptor(int fd);
|
||||
|
||||
// Returns a pair of I/O streams for the given fd
|
||||
public static Pair<FileInputStream, FileOutputStream> zt_getFileStreams(int fd)
|
||||
{
|
||||
FileDescriptor fileDesc = zt_getFileDescriptor(fd);
|
||||
FileOutputStream fos = new FileOutputStream(fileDesc);
|
||||
FileInputStream fis = new FileInputStream(fileDesc);
|
||||
return new Pair<FileInputStream, FileOutputStream>(fis, fos);
|
||||
}
|
||||
|
||||
// Example Usage:
|
||||
// Get corresponding new I/O streams
|
||||
/*
|
||||
Pair<FileInputStream, FileOutputStream> streamPair;
|
||||
streamPair = SDK.zt_getFileStreams(sock);
|
||||
FileInputStream fis = streamPair.first;
|
||||
FileOutputStream fos = streamPair.second;
|
||||
*/
|
||||
|
||||
/*
|
||||
// Wrapper for TX
|
||||
public static void zt_write(FileOutputStream fos, byte[] buf, int len)
|
||||
{
|
||||
try {
|
||||
fos.write(buf, 0, len);
|
||||
}
|
||||
catch (java.io.IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper for RX
|
||||
public static void zt_read(FileInputStream fis, byte[] buf, int len)
|
||||
{
|
||||
try {
|
||||
fis.read(buf, 0, len);
|
||||
}
|
||||
catch (java.io.IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,16 +1,65 @@
|
||||
package ZeroTier;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class ZTAddress
|
||||
{
|
||||
public String addr;
|
||||
static public byte[] toIPByteArray(long addr){
|
||||
return new byte[]{(byte)addr,(byte)(addr>>>8),(byte)(addr>>>16),(byte)(addr>>>24)};
|
||||
}
|
||||
|
||||
int pack(byte[] bytes) {
|
||||
int val = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
val <<= 8;
|
||||
val |= bytes[i] & 0xff;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int port;
|
||||
public int Port() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public long _rawAddr;
|
||||
public String Address()
|
||||
{
|
||||
try {
|
||||
return InetAddress.getByAddress(toIPByteArray(_rawAddr)).getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
//should never happen
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Address() + ":" + Port();
|
||||
}
|
||||
|
||||
public ZTAddress()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ZTAddress(String _addr, int _port)
|
||||
{
|
||||
port = _port;
|
||||
_rawAddr = pack(_addr.getBytes());
|
||||
}
|
||||
|
||||
public void ZTAddress(InetSocketAddress ins)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public InetSocketAddress ToInetSocketAddress() throws IllegalArgumentException {
|
||||
InetSocketAddress sock_addr = null;
|
||||
try {
|
||||
sock_addr = new InetSocketAddress(addr, port);
|
||||
sock_addr = new InetSocketAddress(Address(), port);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,18 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import java.net.InetSocketAddress;
|
||||
import android.util.*;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
// For SOCKS5 Proxy example
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import ZeroTier.SDK;
|
||||
import ZeroTier.ZTAddress;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@@ -15,39 +24,32 @@ public class MainActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
String nwid = "8056c2e21c000001";
|
||||
// Set up service
|
||||
final SDK zt = new SDK();
|
||||
final String homeDir = getApplicationContext().getFilesDir() + "/zerotier";
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
// Calls to JNI code
|
||||
zt.zt_start_service(homeDir);
|
||||
zt.start_service(homeDir);
|
||||
}
|
||||
}).start();
|
||||
while(!zt.zt_running()) { }
|
||||
zt.zt_join_network("XXXXXXXXXXXXXXXX");
|
||||
|
||||
// Create ZeroTier socket
|
||||
int sock = zt.zt_socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||
while(!zt.running()) { }
|
||||
|
||||
// client/server mode toggle
|
||||
int mode = 1, err = -1;
|
||||
int mode = 4, err = -1;
|
||||
|
||||
// Establish outgoing connection
|
||||
if(mode==0)
|
||||
{
|
||||
while(err < 0) {
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch(java.lang.InterruptedException e) { }
|
||||
err = zt.zt_connect(sock, "10.9.9.100", 7004);
|
||||
Log.d("TEST", "err = " + err + "\n");
|
||||
}
|
||||
err = zt.connect(sock, "10.9.9.100", 7004, nwid);
|
||||
Log.d("TEST", "err = " + err + "\n");
|
||||
|
||||
// TX
|
||||
zt.zt_write(sock, "Welcome to the machine".getBytes(), 16);
|
||||
zt.write(sock, "Welcome to the machine".getBytes(), 16);
|
||||
|
||||
// Test section
|
||||
for(int i=0; i<1000; i++)
|
||||
@@ -58,52 +60,151 @@ public class MainActivity extends AppCompatActivity {
|
||||
catch(java.lang.InterruptedException e) { }
|
||||
|
||||
String msg = "Welcome to the machine!";
|
||||
int written = zt.zt_write(sock, msg.getBytes(), msg.length());
|
||||
int written = zt.write(sock, msg.getBytes(), msg.length());
|
||||
Log.d("TEST", "TX[" + i + "] = " + written);
|
||||
|
||||
// RX
|
||||
byte[] buffer = new byte[1024];
|
||||
zt.zt_read(sock, buffer, buffer.length);
|
||||
zt.read(sock, buffer, buffer.length);
|
||||
String bufStr = new String(buffer);
|
||||
Log.d("TEST", "RX[" + i + "] = " + bufStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Listen to incoming connections
|
||||
if(mode==1)
|
||||
{
|
||||
ArrayList<String> addresses = new ArrayList<String>();
|
||||
while(err < 0) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch(java.lang.InterruptedException e) { }
|
||||
addresses = zt.zt_get_addresses("XXXXXXXXXXXXXXXX");
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||
|
||||
if(addresses.size() > 0) {
|
||||
for(int i=0; i<addresses.size(); i++) {
|
||||
Log.d("TEST", "Address = " + addresses.get(i));
|
||||
}
|
||||
}
|
||||
err = zt.zt_bind(sock, "0.0.0.0", 8080);
|
||||
Log.d("TEST", "bind_err = " + err + "\n");
|
||||
}
|
||||
err = zt.bind(sock, "0.0.0.0", 8080, nwid);
|
||||
Log.d("TEST", "bind_err = " + err + "\n");
|
||||
|
||||
err = zt.zt_listen(sock,1);
|
||||
err = zt.listen(sock,1);
|
||||
Log.d("TEST", "listen_err = " + err);
|
||||
|
||||
err = zt.zt_accept(sock,null); // Pass a ZTAddress to get remote host's address (if you want)
|
||||
err = zt.accept(sock,null); // Pass a ZTAddress to get remote host's address (if you want)
|
||||
Log.d("TEST", "accept_err = " + err);
|
||||
}
|
||||
|
||||
if(mode==2)
|
||||
{
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||
|
||||
// Set up example proxy connection to SDK proxy server
|
||||
/*
|
||||
Log.d("ZTSDK", "Setting up connection to SDK proxy server");
|
||||
Socket s = new Socket();
|
||||
SocketAddress proxyAddr = new InetSocketAddress("0.0.0.0", 1337);
|
||||
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr);
|
||||
*/
|
||||
Log.d("TEST", "RX / TX stress test\n");
|
||||
err = zt.connect(sock, "10.9.9.100", 8080, nwid);
|
||||
Log.d("TEST", "err = " + err + "\n");
|
||||
|
||||
// TX
|
||||
zt.write(sock, "Welcome to the machine".getBytes(), 16);
|
||||
|
||||
// Test section
|
||||
for(int i=0; i<1000; i++)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(0);
|
||||
}
|
||||
catch(java.lang.InterruptedException e) { }
|
||||
|
||||
String msg = "Welcome to the machine!";
|
||||
int written = zt.write(sock, msg.getBytes(), msg.length());
|
||||
Log.d("TEST", "TX[" + i + "] = " + written);
|
||||
|
||||
// RX
|
||||
byte[] buffer = new byte[32];
|
||||
Arrays.fill(buffer, (byte)0);
|
||||
zt.read(sock, buffer, buffer.length);
|
||||
String bufStr = new String(buffer);
|
||||
Log.d("TEST", "RX[" + i + "] = " + bufStr);
|
||||
}
|
||||
}
|
||||
|
||||
// SOCKS5 Proxy test
|
||||
if(mode==3)
|
||||
{
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||
|
||||
int proxyPort = zt.get_proxy_port(nwid);
|
||||
Log.d("ZTSDK", "Setting up connection to SDK proxy server");
|
||||
SocketAddress proxyAddr = new InetSocketAddress("127.0.0.1", proxyPort);
|
||||
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr);
|
||||
Log.d("TEST", "toString() = " + proxy.toString());
|
||||
final Socket s = new Socket(proxy);
|
||||
final SocketAddress remoteAddr = new InetSocketAddress("10.9.9.100", 8080);
|
||||
|
||||
// Wait for address to be assigned
|
||||
ArrayList<String> addresses = new ArrayList<String>();
|
||||
addresses = zt.get_addresses(nwid);
|
||||
for(int i=0; i<addresses.size(); i++) {
|
||||
Log.d("TEST", "Address = " + addresses.get(i));
|
||||
}
|
||||
while(addresses.size() > 0 && addresses.get(0).equals("-1.-1.-1.-1/-1")) {
|
||||
try {
|
||||
Log.d("TEST", "waiting for address");
|
||||
Thread.sleep(100);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
addresses = zt.get_addresses(nwid);
|
||||
}
|
||||
|
||||
// Attempt connection
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
s.connect(remoteAddr, 1000);
|
||||
}
|
||||
catch(java.io.IOException e) {
|
||||
Log.d("TEST", "Unable to establish connection to SOCKS5 Proxy server\n");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// UDP test
|
||||
if(mode==4)
|
||||
{
|
||||
// Remote server address (will be populated by recvfrom()
|
||||
ZTAddress remoteServer = new ZTAddress();
|
||||
ZTAddress bindAddr = new ZTAddress("0.0.0.0", 8080);
|
||||
|
||||
Log.d("TEST", "\n\nStarting UDP Test\n\n");
|
||||
nwid = "8056c2e21c000001";
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_DGRAM, 0);
|
||||
|
||||
Log.d("TEST", "binding...");
|
||||
err = zt.bind(sock, bindAddr, nwid);
|
||||
if (err < 0)
|
||||
Log.d("TEST", "bind_err = " + err + "\n");
|
||||
|
||||
err = zt.listen(sock, 0);
|
||||
if(err < 0)
|
||||
Log.d("TEST", "listen_err = " + err);
|
||||
|
||||
while(err >= 0) {
|
||||
// RX
|
||||
byte[] buffer = new byte[32];
|
||||
String addr_string = "-1.-1.-1.-1";
|
||||
int port_no = -1;
|
||||
|
||||
err = zt.recvfrom(sock, buffer, 32, 0, remoteServer);
|
||||
String bufStr = new String(buffer).substring(0, err);
|
||||
Log.d("TEST", "read (" + err + ") bytes from " + remoteServer.Address() + " : " + remoteServer.Port() + ", msg = " + bufStr);
|
||||
|
||||
// TX
|
||||
|
||||
if(err > 0) {
|
||||
String msg = "Welcome response from android";
|
||||
err = zt.sendto(sock, msg.getBytes(), msg.length(), 0, remoteServer);
|
||||
if (err < 0)
|
||||
Log.d("TEST", "sendto_err = " + err);
|
||||
}
|
||||
|
||||
}
|
||||
Log.d("TEST", "leaving network");
|
||||
zt.leave_network(nwid);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user