Android API update

This commit is contained in:
Joseph Henry
2016-08-11 23:34:40 -07:00
parent c0a89129fa
commit 30db7ae58c
14 changed files with 565 additions and 165 deletions

View File

@@ -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();
}
}
*/
}

View File

@@ -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();
}

View File

@@ -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);
}
}
}