Android API update
This commit is contained in:
@@ -44,6 +44,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "lwip/debug.h"
|
#include "lwip/debug.h"
|
||||||
|
|
||||||
|
//#define LWIP_DEBUG 1
|
||||||
|
//#define LWIP_DBG_TYPES_ON LWIP_DBG_TRACE
|
||||||
|
|
||||||
#define LWIP_CHKSUM_ALGORITHM 2
|
#define LWIP_CHKSUM_ALGORITHM 2
|
||||||
|
|
||||||
#undef TCP_MSS
|
#undef TCP_MSS
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.zip.ZipError;
|
||||||
|
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
public class SDK {
|
public class SDK {
|
||||||
@@ -49,70 +51,178 @@ public class SDK {
|
|||||||
|
|
||||||
// ZeroTier service controls
|
// ZeroTier service controls
|
||||||
public native void zt_start_service(String homeDir);
|
public native void zt_start_service(String homeDir);
|
||||||
public native void zt_join_network(String nwid);
|
public void start_service(String homeDir) {
|
||||||
public native void zt_leave_network(String nwid);
|
zt_start_service(homeDir);
|
||||||
public native ArrayList<String> zt_get_addresses(String nwid);
|
}
|
||||||
public native boolean zt_running();
|
|
||||||
|
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 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 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 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 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 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 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_getsockopt(int fd, int type, int protocol);
|
||||||
//public static native int zt_setsockopt(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 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;
|
package ZeroTier;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
public class ZTAddress
|
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;
|
||||||
|
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 {
|
public InetSocketAddress ToInetSocketAddress() throws IllegalArgumentException {
|
||||||
InetSocketAddress sock_addr = null;
|
InetSocketAddress sock_addr = null;
|
||||||
try {
|
try {
|
||||||
sock_addr = new InetSocketAddress(addr, port);
|
sock_addr = new InetSocketAddress(Address(), port);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,18 @@ import android.support.v7.app.AppCompatActivity;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
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.SDK;
|
||||||
|
import ZeroTier.ZTAddress;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@@ -15,39 +24,32 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
String nwid = "8056c2e21c000001";
|
||||||
// Set up service
|
// Set up service
|
||||||
final SDK zt = new SDK();
|
final SDK zt = new SDK();
|
||||||
final String homeDir = getApplicationContext().getFilesDir() + "/zerotier";
|
final String homeDir = getApplicationContext().getFilesDir() + "/zerotier";
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
// Calls to JNI code
|
// Calls to JNI code
|
||||||
zt.zt_start_service(homeDir);
|
zt.start_service(homeDir);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
while(!zt.zt_running()) { }
|
while(!zt.running()) { }
|
||||||
zt.zt_join_network("XXXXXXXXXXXXXXXX");
|
|
||||||
|
|
||||||
// Create ZeroTier socket
|
|
||||||
int sock = zt.zt_socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
|
||||||
|
|
||||||
// client/server mode toggle
|
// client/server mode toggle
|
||||||
int mode = 1, err = -1;
|
int mode = 4, err = -1;
|
||||||
|
|
||||||
// Establish outgoing connection
|
// Establish outgoing connection
|
||||||
if(mode==0)
|
if(mode==0)
|
||||||
{
|
{
|
||||||
while(err < 0) {
|
zt.join_network(nwid);
|
||||||
|
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||||
|
|
||||||
try {
|
err = zt.connect(sock, "10.9.9.100", 7004, nwid);
|
||||||
Thread.sleep(1000);
|
Log.d("TEST", "err = " + err + "\n");
|
||||||
}
|
|
||||||
catch(java.lang.InterruptedException e) { }
|
|
||||||
err = zt.zt_connect(sock, "10.9.9.100", 7004);
|
|
||||||
Log.d("TEST", "err = " + err + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TX
|
// TX
|
||||||
zt.zt_write(sock, "Welcome to the machine".getBytes(), 16);
|
zt.write(sock, "Welcome to the machine".getBytes(), 16);
|
||||||
|
|
||||||
// Test section
|
// Test section
|
||||||
for(int i=0; i<1000; i++)
|
for(int i=0; i<1000; i++)
|
||||||
@@ -58,52 +60,151 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
catch(java.lang.InterruptedException e) { }
|
catch(java.lang.InterruptedException e) { }
|
||||||
|
|
||||||
String msg = "Welcome to the machine!";
|
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);
|
Log.d("TEST", "TX[" + i + "] = " + written);
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
zt.zt_read(sock, buffer, buffer.length);
|
zt.read(sock, buffer, buffer.length);
|
||||||
String bufStr = new String(buffer);
|
String bufStr = new String(buffer);
|
||||||
Log.d("TEST", "RX[" + i + "] = " + bufStr);
|
Log.d("TEST", "RX[" + i + "] = " + bufStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen to incoming connections
|
// Listen to incoming connections
|
||||||
if(mode==1)
|
if(mode==1)
|
||||||
{
|
{
|
||||||
ArrayList<String> addresses = new ArrayList<String>();
|
zt.join_network(nwid);
|
||||||
while(err < 0) {
|
int sock = zt.socket(SDK.AF_INET, SDK.SOCK_STREAM, 0);
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
catch(java.lang.InterruptedException e) { }
|
|
||||||
addresses = zt.zt_get_addresses("XXXXXXXXXXXXXXXX");
|
|
||||||
|
|
||||||
if(addresses.size() > 0) {
|
err = zt.bind(sock, "0.0.0.0", 8080, nwid);
|
||||||
for(int i=0; i<addresses.size(); i++) {
|
Log.d("TEST", "bind_err = " + err + "\n");
|
||||||
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.zt_listen(sock,1);
|
err = zt.listen(sock,1);
|
||||||
Log.d("TEST", "listen_err = " + err);
|
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);
|
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("TEST", "RX / TX stress test\n");
|
||||||
/*
|
err = zt.connect(sock, "10.9.9.100", 8080, nwid);
|
||||||
Log.d("ZTSDK", "Setting up connection to SDK proxy server");
|
Log.d("TEST", "err = " + err + "\n");
|
||||||
Socket s = new Socket();
|
|
||||||
SocketAddress proxyAddr = new InetSocketAddress("0.0.0.0", 1337);
|
// TX
|
||||||
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,8 +120,12 @@ ssize_t zts_recvmsg(RECVMSG_SIG);
|
|||||||
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockopt(JNIEnv *env, jobject thisObj);
|
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockopt(JNIEnv *env, jobject thisObj);
|
||||||
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockname(JNIEnv *env, jobject thisObj);
|
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockname(JNIEnv *env, jobject thisObj);
|
||||||
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1close(JNIEnv *env, jobject thisObj, jint fd);
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1close(JNIEnv *env, jobject thisObj, jint fd);
|
||||||
|
// TCP
|
||||||
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1write(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len);
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1write(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len);
|
||||||
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1read(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len);
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1read(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len);
|
||||||
|
// UDP
|
||||||
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1sendto(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr);
|
||||||
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1recvfrom(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr);
|
||||||
// Takes a given numerical file descriptor and manufactures a java FileDescriptor object for use in javaland
|
// Takes a given numerical file descriptor and manufactures a java FileDescriptor object for use in javaland
|
||||||
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1getFileDescriptor(JNIEnv *env, jobject thisObj, jint fd);
|
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1getFileDescriptor(JNIEnv *env, jobject thisObj, jint fd);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
#define SDK_DEBUG_H
|
#define SDK_DEBUG_H
|
||||||
|
|
||||||
// Set during make (e.g. make SDK_DEBUG=2)
|
// Set during make (e.g. make SDK_DEBUG=2)
|
||||||
#define DEBUG_LEVEL 5
|
#define DEBUG_LEVEL 4
|
||||||
|
|
||||||
#define MSG_TRANSFER 1 // RX/TX specific statements
|
#define MSG_TRANSFER 1 // RX/TX specific statements
|
||||||
#define MSG_ERROR 2 // Errors
|
#define MSG_ERROR 2 // Errors
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG_LEVEL 5 // Set this to adjust what you'd like to see in the debug traces
|
#define DEBUG_LEVEL 4 // Set this to adjust what you'd like to see in the debug traces
|
||||||
|
|
||||||
#define MSG_TRANSFER 1 // RX/TX specific statements
|
#define MSG_TRANSFER 1 // RX/TX specific statements
|
||||||
#define MSG_ERROR 2 // Errors
|
#define MSG_ERROR 2 // Errors
|
||||||
|
|||||||
@@ -382,11 +382,11 @@ Connection *NetconEthernetTap::getConnection(PhySocket *sock)
|
|||||||
|
|
||||||
void NetconEthernetTap::closeConnection(PhySocket *sock)
|
void NetconEthernetTap::closeConnection(PhySocket *sock)
|
||||||
{
|
{
|
||||||
dwr(MSG_DEBUG, "closeConnection(sock=%x):\n", sock);
|
dwr(MSG_DEBUG_EXTRA, "closeConnection(sock=%x):\n", sock);
|
||||||
Mutex::Lock _l(_close_m);
|
Mutex::Lock _l(_close_m);
|
||||||
// Here we assume _tcpconns_m is already locked by caller
|
// Here we assume _tcpconns_m is already locked by caller
|
||||||
if(!sock) {
|
if(!sock) {
|
||||||
dwr(MSG_DEBUG,"closeConnection(): invalid PhySocket\n");
|
dwr(MSG_DEBUG_EXTRA,"closeConnection(): invalid PhySocket\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Connection *conn = getConnection(sock);
|
Connection *conn = getConnection(sock);
|
||||||
@@ -396,14 +396,14 @@ void NetconEthernetTap::closeConnection(PhySocket *sock)
|
|||||||
lwipstack->__udp_remove(conn->UDP_pcb);
|
lwipstack->__udp_remove(conn->UDP_pcb);
|
||||||
}
|
}
|
||||||
if(conn->TCP_pcb && conn->TCP_pcb->state != CLOSED) {
|
if(conn->TCP_pcb && conn->TCP_pcb->state != CLOSED) {
|
||||||
dwr(MSG_DEBUG,"closeConnection(conn=%p,sock=%p): PCB->state = %d\n",
|
dwr(MSG_DEBUG_EXTRA,"closeConnection(conn=%p,sock=%p): PCB->state = %d\n",
|
||||||
(void*)&conn, (void*)&sock, conn->TCP_pcb->state);
|
(void*)&conn, (void*)&sock, conn->TCP_pcb->state);
|
||||||
if(conn->TCP_pcb->state == SYN_SENT /*|| conn->TCP_pcb->state == CLOSE_WAIT*/) {
|
if(conn->TCP_pcb->state == SYN_SENT /*|| conn->TCP_pcb->state == CLOSE_WAIT*/) {
|
||||||
dwr(MSG_DEBUG,"closeConnection(sock=%p): invalid PCB state for this operation. ignoring.\n",
|
dwr(MSG_DEBUG_EXTRA,"closeConnection(sock=%p): invalid PCB state for this operation. ignoring.\n",
|
||||||
(void*)&sock);
|
(void*)&sock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dwr(MSG_DEBUG, "__tcp_close(...)\n");
|
dwr(MSG_DEBUG_EXTRA, "__tcp_close(...)\n");
|
||||||
if(lwipstack->__tcp_close(conn->TCP_pcb) == ERR_OK) {
|
if(lwipstack->__tcp_close(conn->TCP_pcb) == ERR_OK) {
|
||||||
// Unregister callbacks for this PCB
|
// Unregister callbacks for this PCB
|
||||||
lwipstack->__tcp_arg(conn->TCP_pcb, NULL);
|
lwipstack->__tcp_arg(conn->TCP_pcb, NULL);
|
||||||
@@ -413,7 +413,7 @@ void NetconEthernetTap::closeConnection(PhySocket *sock)
|
|||||||
lwipstack->__tcp_poll(conn->TCP_pcb, NULL, 1);
|
lwipstack->__tcp_poll(conn->TCP_pcb, NULL, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dwr(MSG_ERROR,"closeConnection(sock=%p): error while calling tcp_close()\n", (void*)&sock);
|
dwr(MSG_DEBUG_EXTRA,"closeConnection(sock=%p): error while calling tcp_close()\n", (void*)&sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(size_t i=0;i<_Connections.size();++i) {
|
for(size_t i=0;i<_Connections.size();++i) {
|
||||||
@@ -430,7 +430,7 @@ void NetconEthernetTap::closeConnection(PhySocket *sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) {
|
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) {
|
||||||
dwr(MSG_DEBUG, "phyOnUnixClose(sock=%p):\n", (void*)&sock);
|
dwr(MSG_DEBUG_EXTRA, "phyOnUnixClose(sock=%p):\n", (void*)&sock);
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
closeConnection(sock);
|
closeConnection(sock);
|
||||||
}
|
}
|
||||||
@@ -454,12 +454,13 @@ void NetconEthernetTap::processReceivedData(PhySocket *sock,void **uptr,bool lwi
|
|||||||
if(conn->type==SOCK_DGRAM){
|
if(conn->type==SOCK_DGRAM){
|
||||||
conn->unread_udp_packet = false;
|
conn->unread_udp_packet = false;
|
||||||
_phy.setNotifyWritable(conn->sock, false);
|
_phy.setNotifyWritable(conn->sock, false);
|
||||||
|
dwr(MSG_TRANSFER,"UDP RX <--- :: {TX: ------, RX: ------, sock=%x} :: %d bytes\n", conn->sock, n);
|
||||||
}
|
}
|
||||||
//dwr(MSG_DEBUG, "phyOnUnixWritable(): tid = %d\n", pthread_mach_thread_np(pthread_self()));
|
//dwr(MSG_DEBUG, "phyOnUnixWritable(): tid = %d\n", pthread_mach_thread_np(pthread_self()));
|
||||||
if(conn->type==SOCK_STREAM) { // Only acknolwedge receipt of TCP packets
|
if(conn->type==SOCK_STREAM) { // Only acknolwedge receipt of TCP packets
|
||||||
lwipstack->__tcp_recved(conn->TCP_pcb, n);
|
lwipstack->__tcp_recved(conn->TCP_pcb, n);
|
||||||
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_TX_BUF_SZ : (float)DEFAULT_UDP_TX_BUF_SZ;
|
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_TX_BUF_SZ : (float)DEFAULT_UDP_TX_BUF_SZ;
|
||||||
dwr(MSG_TRANSFER," RX <--- :: {TX: %.3f%%, RX: %.3f%%, sock=%x} :: %d bytes\n",
|
dwr(MSG_TRANSFER,"TCP RX <--- :: {TX: %.3f%%, RX: %.3f%%, sock=%x} :: %d bytes\n",
|
||||||
(float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
|
(float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -486,7 +487,7 @@ void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_
|
|||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
|
void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
|
||||||
{
|
{
|
||||||
dwr(MSG_DEBUG, "phyOnUnixData(%p), len = %d\n", (void*)&sock, len);
|
dwr(MSG_DEBUG_EXTRA, "phyOnUnixData(%p), len = %d\n", (void*)&sock, len);
|
||||||
uint64_t CANARY_num;
|
uint64_t CANARY_num;
|
||||||
pid_t pid, tid;
|
pid_t pid, tid;
|
||||||
ssize_t wlen = len;
|
ssize_t wlen = len;
|
||||||
@@ -642,13 +643,13 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NetconEthernetTap::sendReturnValue(PhySocket *sock, int retval, int _errno = 0){
|
int NetconEthernetTap::sendReturnValue(PhySocket *sock, int retval, int _errno = 0){
|
||||||
dwr(MSG_DEBUG," sendReturnValue(sock=%p)\n", (void*)&sock);
|
dwr(MSG_DEBUG_EXTRA," sendReturnValue(sock=%p)\n", (void*)&sock);
|
||||||
return sendReturnValue(_phy.getDescriptor(sock), retval, _errno);
|
return sendReturnValue(_phy.getDescriptor(sock), retval, _errno);
|
||||||
}
|
}
|
||||||
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno = 0)
|
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno = 0)
|
||||||
{
|
{
|
||||||
//#if !defined(USE_SOCKS_PROXY)
|
//#if !defined(USE_SOCKS_PROXY)
|
||||||
dwr(MSG_DEBUG," sendReturnValue(): fd = %d, retval = %d, errno = %d\n", fd, retval, _errno);
|
dwr(MSG_DEBUG_EXTRA," sendReturnValue(): fd = %d, retval = %d, errno = %d\n", fd, retval, _errno);
|
||||||
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
|
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
|
||||||
char retmsg[sz];
|
char retmsg[sz];
|
||||||
memset(&retmsg, 0, sizeof(retmsg));
|
memset(&retmsg, 0, sizeof(retmsg));
|
||||||
@@ -717,7 +718,8 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newPCB, err_t err)
|
|||||||
tap->lwipstack->__tcp_sent(newPCB, nc_sent);
|
tap->lwipstack->__tcp_sent(newPCB, nc_sent);
|
||||||
tap->lwipstack->__tcp_poll(newPCB, nc_poll, 1);
|
tap->lwipstack->__tcp_poll(newPCB, nc_poll, 1);
|
||||||
if(conn->TCP_pcb->state == LISTEN) {
|
if(conn->TCP_pcb->state == LISTEN) {
|
||||||
dwr(MSG_DEBUG," nc_accept(): can't call tcp_accept() on LISTEN socket (pcb = %x)\n", conn->TCP_pcb);
|
// FIX: This error likely doesn't have user significance and is a candidate for removal
|
||||||
|
// dwr(MSG_DEBUG," nc_accept(): can't call tcp_accept() on LISTEN socket (pcb = %x)\n", conn->TCP_pcb);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
tcp_accepted(conn->TCP_pcb); // Let lwIP know that it can queue additional incoming connections
|
tcp_accepted(conn->TCP_pcb); // Let lwIP know that it can queue additional incoming connections
|
||||||
@@ -739,6 +741,12 @@ void NetconEthernetTap::nc_udp_recved(void * arg, struct udp_pcb * upcb, struct
|
|||||||
if(p) {
|
if(p) {
|
||||||
l->conn->rxsz = 0;
|
l->conn->rxsz = 0;
|
||||||
memset(l->conn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
|
memset(l->conn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
|
||||||
|
// Add address info beginning of data buffer
|
||||||
|
u32_t raw_addr = ip4_addr_get_u32(addr);
|
||||||
|
memcpy(l->conn->rxbuf + (l->conn->rxsz), &raw_addr, sizeof(u32_t)); // addr
|
||||||
|
l->conn->rxsz += sizeof(u32_t);
|
||||||
|
memcpy(l->conn->rxbuf + (l->conn->rxsz), &port, sizeof(u16_t)); // port
|
||||||
|
l->conn->rxsz += sizeof(u16_t);
|
||||||
}
|
}
|
||||||
while(p != NULL) {
|
while(p != NULL) {
|
||||||
if(p->len <= 0)
|
if(p->len <= 0)
|
||||||
@@ -750,7 +758,8 @@ void NetconEthernetTap::nc_udp_recved(void * arg, struct udp_pcb * upcb, struct
|
|||||||
tot += len;
|
tot += len;
|
||||||
}
|
}
|
||||||
if(tot) {
|
if(tot) {
|
||||||
dwr(MSG_DEBUG, " nc_udp_recved(): tot = %d, rxsz = %d\n", tot, l->conn->rxsz);
|
dwr(MSG_DEBUG, " nc_udp_recved(): data_len = %d, rxsz = %d, addr_info_len = %d\n",
|
||||||
|
tot, l->conn->rxsz, sizeof(u32_t) + sizeof(u16_t));
|
||||||
l->conn->unread_udp_packet = true;
|
l->conn->unread_udp_packet = true;
|
||||||
l->tap->phyOnUnixWritable(l->conn->sock, NULL, true);
|
l->tap->phyOnUnixWritable(l->conn->sock, NULL, true);
|
||||||
l->tap->_phy.setNotifyWritable(l->conn->sock, true);
|
l->tap->_phy.setNotifyWritable(l->conn->sock, true);
|
||||||
@@ -1005,8 +1014,11 @@ void NetconEthernetTap::handleListen(PhySocket *sock, PhySocket *rpcSock, void *
|
|||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
Connection *conn = getConnection(sock);
|
Connection *conn = getConnection(sock);
|
||||||
|
|
||||||
if(conn->type==SOCK_DGRAM)
|
if(conn->type==SOCK_DGRAM) {
|
||||||
|
// FIX: Added sendReturnValue() call to fix listen() return bug on Android
|
||||||
|
sendReturnValue(rpcSock, ERR_OK, ERR_OK);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if(!conn) {
|
if(!conn) {
|
||||||
dwr(MSG_ERROR," handleListen(): unable to locate Connection.\n");
|
dwr(MSG_ERROR," handleListen(): unable to locate Connection.\n");
|
||||||
sendReturnValue(rpcSock, -1, EBADF);
|
sendReturnValue(rpcSock, -1, EBADF);
|
||||||
@@ -1201,7 +1213,14 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne
|
|||||||
struct sockaddr_in *rawAddr = (struct sockaddr_in *) &connect_rpc->__addr;
|
struct sockaddr_in *rawAddr = (struct sockaddr_in *) &connect_rpc->__addr;
|
||||||
int port = lwipstack->__lwip_ntohs(rawAddr->sin_port);
|
int port = lwipstack->__lwip_ntohs(rawAddr->sin_port);
|
||||||
ip_addr_t connAddr = convert_ip(rawAddr);
|
ip_addr_t connAddr = convert_ip(rawAddr);
|
||||||
int err = 0;
|
int err = 0, ip = rawAddr->sin_addr.s_addr;
|
||||||
|
|
||||||
|
unsigned char d[4];
|
||||||
|
d[0] = ip & 0xFF;
|
||||||
|
d[1] = (ip >> 8) & 0xFF;
|
||||||
|
d[2] = (ip >> 16) & 0xFF;
|
||||||
|
d[3] = (ip >> 24) & 0xFF;
|
||||||
|
dwr(MSG_DEBUG," handleConnect(): %d.%d.%d.%d: %d\n", d[0],d[1],d[2],d[3], port);
|
||||||
|
|
||||||
if(conn->type == SOCK_DGRAM) {
|
if(conn->type == SOCK_DGRAM) {
|
||||||
// Generates no network traffic
|
// Generates no network traffic
|
||||||
@@ -1218,14 +1237,6 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne
|
|||||||
lwipstack->__tcp_poll(conn->TCP_pcb, nc_poll, APPLICATION_POLL_FREQ);
|
lwipstack->__tcp_poll(conn->TCP_pcb, nc_poll, APPLICATION_POLL_FREQ);
|
||||||
lwipstack->__tcp_arg(conn->TCP_pcb, new Larg(this, conn));
|
lwipstack->__tcp_arg(conn->TCP_pcb, new Larg(this, conn));
|
||||||
|
|
||||||
int ip = rawAddr->sin_addr.s_addr;
|
|
||||||
unsigned char d[4];
|
|
||||||
d[0] = ip & 0xFF;
|
|
||||||
d[1] = (ip >> 8) & 0xFF;
|
|
||||||
d[2] = (ip >> 16) & 0xFF;
|
|
||||||
d[3] = (ip >> 24) & 0xFF;
|
|
||||||
|
|
||||||
dwr(MSG_DEBUG," handleConnect(): %d.%d.%d.%d: %d\n", d[0],d[1],d[2],d[3], port);
|
|
||||||
dwr(MSG_DEBUG," handleConnect(): pcb->state = %x\n", conn->TCP_pcb->state);
|
dwr(MSG_DEBUG," handleConnect(): pcb->state = %x\n", conn->TCP_pcb->state);
|
||||||
if(conn->TCP_pcb->state != CLOSED) {
|
if(conn->TCP_pcb->state != CLOSED) {
|
||||||
dwr(MSG_DEBUG," handleConnect(): PCB != CLOSED, cannot connect using this PCB\n");
|
dwr(MSG_DEBUG," handleConnect(): PCB != CLOSED, cannot connect using this PCB\n");
|
||||||
@@ -1316,13 +1327,13 @@ void NetconEthernetTap::handleWrite(Connection *conn)
|
|||||||
} else if(err != ERR_OK) {
|
} else if(err != ERR_OK) {
|
||||||
dwr(MSG_DEBUG, " handleWrite(): Error sending packet - %d\n", err);
|
dwr(MSG_DEBUG, " handleWrite(): Error sending packet - %d\n", err);
|
||||||
} else {
|
} else {
|
||||||
|
// Success
|
||||||
int buf_remaining = (conn->txsz)-udp_trans_len;
|
int buf_remaining = (conn->txsz)-udp_trans_len;
|
||||||
if(buf_remaining)
|
if(buf_remaining)
|
||||||
memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining);
|
memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining);
|
||||||
conn->txsz -= udp_trans_len;
|
conn->txsz -= udp_trans_len;
|
||||||
int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ;
|
int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ;
|
||||||
dwr(MSG_TRANSFER," TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%x} :: %d bytes\n",
|
dwr(MSG_TRANSFER,"UDP TX ---> :: {TX: ------, RX: ------, sock=%x} :: %d bytes\n", conn->sock, udp_trans_len);
|
||||||
(float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, udp_trans_len);
|
|
||||||
}
|
}
|
||||||
lwipstack->__pbuf_free(pb);
|
lwipstack->__pbuf_free(pb);
|
||||||
return;
|
return;
|
||||||
@@ -1370,7 +1381,7 @@ void NetconEthernetTap::handleWrite(Connection *conn)
|
|||||||
memmove(&conn->txbuf, (conn->txbuf+r), sz);
|
memmove(&conn->txbuf, (conn->txbuf+r), sz);
|
||||||
conn->txsz -= r;
|
conn->txsz -= r;
|
||||||
int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ;
|
int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ;
|
||||||
dwr(MSG_TRANSFER," TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes\n",
|
dwr(MSG_TRANSFER,"TCP TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes\n",
|
||||||
(float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r);
|
(float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,8 @@ namespace ZeroTier {
|
|||||||
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
|
||||||
|
int proxyListenPort;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// LWIP callbacks
|
// LWIP callbacks
|
||||||
// NOTE: these are called from within LWIP, meaning that lwipstack->_lock is ALREADY
|
// NOTE: these are called from within LWIP, meaning that lwipstack->_lock is ALREADY
|
||||||
@@ -454,20 +456,14 @@ namespace ZeroTier {
|
|||||||
*/
|
*/
|
||||||
void closeConnection(PhySocket *sock);
|
void closeConnection(PhySocket *sock);
|
||||||
|
|
||||||
// --- Proxy stubs
|
// --- Proxy
|
||||||
int proxyListenPort;
|
|
||||||
|
|
||||||
//std::map<int,PhySocket> proxySockStates;
|
|
||||||
|
|
||||||
int sockstate;
|
int sockstate;
|
||||||
int proxyListenSocket;
|
int proxyListenSocket;
|
||||||
PhySocket *proxyListenPhySocket;
|
PhySocket *proxyListenPhySocket;
|
||||||
|
|
||||||
void StartProxy(const char *sockpath, const char *homepath, uint64_t nwid);
|
void StartProxy(const char *sockpath, const char *homepath, uint64_t nwid);
|
||||||
|
|
||||||
void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable);
|
void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable);
|
||||||
|
|
||||||
// --- end Proxy stubs
|
// --- end Proxy
|
||||||
|
|
||||||
ip_addr_t convert_ip(struct sockaddr_in * addr)
|
ip_addr_t convert_ip(struct sockaddr_in * addr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace ZeroTier
|
|||||||
void ExtractAddress(int addr_type, unsigned char *buf, struct sockaddr_in * addr)
|
void ExtractAddress(int addr_type, unsigned char *buf, struct sockaddr_in * addr)
|
||||||
{
|
{
|
||||||
// TODO: Generalize extraction logic
|
// TODO: Generalize extraction logic
|
||||||
if(addr_type == 3)
|
if(addr_type == 144)
|
||||||
{
|
{
|
||||||
// Extract address from buffer
|
// Extract address from buffer
|
||||||
int domain_len = buf[IDX_DST_ADDR]; // (L):D
|
int domain_len = buf[IDX_DST_ADDR]; // (L):D
|
||||||
@@ -216,8 +216,10 @@ namespace ZeroTier
|
|||||||
|
|
||||||
// CONNECT request
|
// CONNECT request
|
||||||
if(cmd == 1) {
|
if(cmd == 1) {
|
||||||
|
dwr(MSG_DEBUG, "CONNECT request\n");
|
||||||
// Ipv4
|
// Ipv4
|
||||||
if(addr_type == 1)
|
/*
|
||||||
|
if(addr_type == 144)
|
||||||
{
|
{
|
||||||
//printf("IPv4\n");
|
//printf("IPv4\n");
|
||||||
int raw_addr;
|
int raw_addr;
|
||||||
@@ -235,20 +237,22 @@ namespace ZeroTier
|
|||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
addr.sin_addr.s_addr = IPADDR_ANY;
|
addr.sin_addr.s_addr = IPADDR_ANY;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = Utils::hton(proxyListenPort);
|
addr.sin_port = Utils::hton(8080);
|
||||||
|
|
||||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
dwr(MSG_DEBUG, "fd = %d\n", fd);
|
||||||
|
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
perror("socket");
|
perror("socket");
|
||||||
|
|
||||||
int err = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
|
int err = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
|
||||||
|
dwr(MSG_DEBUG, "connect_err = %d\n", err);
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
perror("connect");
|
perror("connect");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Fully-qualified domain name
|
// Fully-qualified domain name
|
||||||
if(addr_type == 3)
|
if(addr_type == 144)
|
||||||
{
|
{
|
||||||
int domain_len = buf[IDX_DST_ADDR]; // (L):D
|
int domain_len = buf[IDX_DST_ADDR]; // (L):D
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|||||||
@@ -112,8 +112,20 @@ void zts_leave_network(const char * nwid) { zt1Service->leave(nwid); }
|
|||||||
bool zts_is_running() { return zt1Service->isRunning(); }
|
bool zts_is_running() { return zt1Service->isRunning(); }
|
||||||
void zts_terminate() { zt1Service->terminate(); }
|
void zts_terminate() { zt1Service->terminate(); }
|
||||||
|
|
||||||
std::vector<std::string> zt_get_addresses(std::string nwid)
|
// FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations
|
||||||
|
// Now only returns first assigned address per network. Shouldn't normally be a problem
|
||||||
|
void zts_get_addresses(const char * nwid, char *addrstr)
|
||||||
{
|
{
|
||||||
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
|
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
||||||
|
if(tap && tap->_ips.size()){
|
||||||
|
std::string addr = tap->_ips[0].toString();
|
||||||
|
memcpy(addrstr, addr.c_str(), addr.length());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(addrstr, "-1.-1.-1.-1/-1", 14);
|
||||||
|
}
|
||||||
|
/*
|
||||||
uint64_t nwid_int = strtoull(nwid.c_str(), NULL, 16);
|
uint64_t nwid_int = strtoull(nwid.c_str(), NULL, 16);
|
||||||
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
||||||
std::vector<std::string> ip_strings;
|
std::vector<std::string> ip_strings;
|
||||||
@@ -124,6 +136,18 @@ std::vector<std::string> zt_get_addresses(std::string nwid)
|
|||||||
return ip_strings;
|
return ip_strings;
|
||||||
}
|
}
|
||||||
return ip_strings;
|
return ip_strings;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
bool zts_is_relayed() {
|
||||||
|
// TODO
|
||||||
|
// zt1Service->getNode()->peers()
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_proxy_port(const char * nwid) {
|
||||||
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
|
return zt1Service->getTaps()[nwid_int]->proxyListenPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -153,12 +177,23 @@ std::vector<std::string> zt_get_addresses(std::string nwid)
|
|||||||
if(zt1Service)
|
if(zt1Service)
|
||||||
zts_terminate();
|
zts_terminate();
|
||||||
}
|
}
|
||||||
|
// FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations
|
||||||
|
// Now only returns first assigned address per network. Shouldn't normally be a problem
|
||||||
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1get_1addresses(JNIEnv *env, jobject thisObj, jstring nwid) {
|
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1get_1addresses(JNIEnv *env, jobject thisObj, jstring nwid) {
|
||||||
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
|
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
|
||||||
std::vector<std::string> address_strings = zt_get_addresses(nwid_str);
|
char address_string[32];
|
||||||
|
memset(address_string, 0, 32);
|
||||||
|
zts_get_addresses(nwid_str, address_string);
|
||||||
|
jclass clazz = (*env).FindClass("java/util/ArrayList");
|
||||||
|
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
|
||||||
|
jstring _str = (*env).NewStringUTF(address_string);
|
||||||
|
env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str);
|
||||||
|
return addresses;
|
||||||
|
/*
|
||||||
|
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
|
||||||
|
std::vector<std::string> address_strings = zts_get_addresses(nwid_str);
|
||||||
jclass clazz = (*env).FindClass("java/util/ArrayList");
|
jclass clazz = (*env).FindClass("java/util/ArrayList");
|
||||||
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
|
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
|
||||||
|
|
||||||
if(address_strings.size()) {
|
if(address_strings.size()) {
|
||||||
for (int n=0;n<address_strings.size();n++) {
|
for (int n=0;n<address_strings.size();n++) {
|
||||||
jstring _str = (*env).NewStringUTF(address_strings[n].c_str());
|
jstring _str = (*env).NewStringUTF(address_strings[n].c_str());
|
||||||
@@ -170,7 +205,15 @@ std::vector<std::string> zt_get_addresses(std::string nwid)
|
|||||||
env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str);
|
env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str);
|
||||||
}
|
}
|
||||||
return addresses;
|
return addresses;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1is_1relayed() {
|
||||||
|
return zts_is_relayed();
|
||||||
|
}
|
||||||
|
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1get_1proxy_1port(JNIEnv *env, jobject thisObj, jstring nwid) {
|
||||||
|
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
|
||||||
|
return zts_get_proxy_port(nwid_str);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ extern "C" {
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
//#include <vector>
|
||||||
|
|
||||||
#ifndef ONE_SERVICE_SETUP_HPP
|
#ifndef ONE_SERVICE_SETUP_HPP
|
||||||
#define ONE_SERVICE_SETUP_HPP
|
#define ONE_SERVICE_SETUP_HPP
|
||||||
@@ -50,6 +50,8 @@ extern "C" {
|
|||||||
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1leave_1network(JNIEnv *env, jobject thisObj, jstring nwid);
|
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1leave_1network(JNIEnv *env, jobject thisObj, jstring nwid);
|
||||||
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj);
|
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj);
|
||||||
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1get_1addresses(JNIEnv *env, jobject thisObj, jstring nwid);
|
JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1get_1addresses(JNIEnv *env, jobject thisObj, jstring nwid);
|
||||||
|
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1is_1relayed();
|
||||||
|
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1get_1proxy_1port(JNIEnv *env, jobject thisObj, jstring nwid);
|
||||||
#else
|
#else
|
||||||
void init_service(int key, const char * path);
|
void init_service(int key, const char * path);
|
||||||
void init_service_and_rpc(int key, const char * path, const char * nwid);
|
void init_service_and_rpc(int key, const char * path, const char * nwid);
|
||||||
@@ -67,7 +69,10 @@ void zts_join_network(const char * nwid);
|
|||||||
void zts_leave_network(const char * nwid);
|
void zts_leave_network(const char * nwid);
|
||||||
bool zts_is_running();
|
bool zts_is_running();
|
||||||
void zts_terminate();
|
void zts_terminate();
|
||||||
std::vector<std::string> zt_get_addresses(std::string nwid);
|
void zts_get_addresses(const char * nwid, char * addrstr);
|
||||||
|
//std::vector<std::string> zts_get_addresses(std::string nwid);
|
||||||
|
bool zts_is_relayed();
|
||||||
|
int zts_get_proxy_port(const char * nwid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#define SENDMSG_SIG int socket, const struct msghdr *message, int flags
|
#define SENDMSG_SIG int socket, const struct msghdr *message, int flags
|
||||||
#define SENDTO_SIG int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addr_len
|
#define SENDTO_SIG int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addr_len
|
||||||
#define RECV_SIG int socket, void *buffer, size_t length, int flags
|
#define RECV_SIG int socket, void *buffer, size_t length, int flags
|
||||||
#define RECVFROM_SIG int socket, void * buffer, size_t length, int flags, struct sockaddr * __restrict address, socklen_t * __restrict address_len
|
#define RECVFROM_SIG int socket, void * buffer, size_t length, int flags, struct sockaddr_in * __restrict address, socklen_t * __restrict address_len
|
||||||
#define RECVMSG_SIG int socket, struct msghdr *message,int flags
|
#define RECVMSG_SIG int socket, struct msghdr *message,int flags
|
||||||
|
|
||||||
#define SEND_SIG int socket, const void *buffer, size_t length, int flags
|
#define SEND_SIG int socket, const void *buffer, size_t length, int flags
|
||||||
|
|||||||
@@ -127,14 +127,41 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
// int sockfd, const void *buf, size_t len, int flags,
|
// int sockfd, const void *buf, size_t len, int flags,
|
||||||
// const struct sockaddr *addr, socklen_t addr_len
|
// const struct sockaddr *addr, socklen_t addr_len
|
||||||
|
|
||||||
#if !defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
// TODO: Check result of each JNI call
|
||||||
|
// UDP TX
|
||||||
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1sendto(
|
||||||
|
JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
jclass cls = (*env)->GetObjectClass(env, ztaddr);
|
||||||
|
jfieldID f = (*env)->GetFieldID(env, cls, "port", "I");
|
||||||
|
addr.sin_port = htons((*env)->GetIntField(env, ztaddr, f));
|
||||||
|
f = (*env)->GetFieldID(env, cls, "_rawAddr", "J");
|
||||||
|
addr.sin_addr.s_addr = (*env)->GetLongField(env, ztaddr, f);
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
LOGV("zt_sendto(): fd = %d\naddr = %s\nport=%d", fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||||
|
|
||||||
|
// TODO: Optimize this
|
||||||
|
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
|
char * bufp = (char *)malloc(sizeof(char)*len);
|
||||||
|
memcpy(bufp, body, len);
|
||||||
|
(*env)->ReleaseByteArrayElements(env, buf, body, 0);
|
||||||
|
|
||||||
|
// "connect" and send buffer contents
|
||||||
|
int sent_bytes = zts_sendto(fd, body, len, flags, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
return sent_bytes;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#if !defined(__ANDROID__)
|
||||||
#ifdef DYNAMIC_LIB
|
#ifdef DYNAMIC_LIB
|
||||||
ssize_t zt_sendto(SENDTO_SIG) // Exposed as API
|
ssize_t zt_sendto(SENDTO_SIG) // Exposed as API
|
||||||
#else
|
#else
|
||||||
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
|
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
dwr(MSG_DEBUG, "zt_sendto()\n");
|
LOGV("zt_sendto()\n");
|
||||||
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
||||||
errno = EMSGSIZE; // Msg is too large
|
errno = EMSGSIZE; // Msg is too large
|
||||||
return -1;
|
return -1;
|
||||||
@@ -162,14 +189,14 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
// TODO: More efficient solution
|
// TODO: More efficient solution
|
||||||
// This connect call is used to get the address info to the stack for sending the packet
|
// This connect call is used to get the address info to the stack for sending the packet
|
||||||
int err;
|
int err;
|
||||||
if((err = connect(sockfd, addr, addr_len)) < 0) {
|
if((err = zts_connect(sockfd, addr, addr_len)) < 0) {
|
||||||
dwr(MSG_DEBUG, "sendto(): unknown problem passing address info to stack\n");
|
LOGV("sendto(): unknown problem passing address info to stack\n");
|
||||||
errno = EISCONN; // double-check this is correct
|
errno = EISCONN; // double-check this is correct
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return send(sockfd, buf, len, flags);
|
return write(sockfd, buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// ----------------------------------- sendmsg() --------------------------------
|
// ----------------------------------- sendmsg() --------------------------------
|
||||||
@@ -216,7 +243,28 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
// int socket, void *restrict buffer, size_t length, int flags, struct sockaddr
|
// int socket, void *restrict buffer, size_t length, int flags, struct sockaddr
|
||||||
// *restrict address, socklen_t *restrict address_len
|
// *restrict address, socklen_t *restrict address_len
|
||||||
|
|
||||||
#if !defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
// UDP RX
|
||||||
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1recvfrom(
|
||||||
|
JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
dwr(MSG_DEBUG, "zt_recvfrom(): fd = %d\n", fd);
|
||||||
|
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
|
int recvd_bytes = zts_recvfrom(fd, body, len, flags, &addr, sizeof(addr));
|
||||||
|
(*env)->ReleaseByteArrayElements(env, buf, body, 0);
|
||||||
|
// Update fields of Java ZTAddress object
|
||||||
|
jfieldID fid;
|
||||||
|
jclass cls = (*env)->GetObjectClass(env, ztaddr);
|
||||||
|
fid = (*env)->GetFieldID(env, cls, "port", "I");
|
||||||
|
(*env)->SetIntField(env, ztaddr, fid, addr.sin_port);
|
||||||
|
fid = (*env)->GetFieldID(env, cls,"_rawAddr", "J");
|
||||||
|
(*env)->SetLongField(env, ztaddr, fid,addr.sin_addr.s_addr);
|
||||||
|
return recvd_bytes;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#if !defined(__ANDROID__)
|
||||||
#ifdef DYNAMIC_LIB
|
#ifdef DYNAMIC_LIB
|
||||||
ssize_t zt_recvfrom(RECVFROM_SIG)
|
ssize_t zt_recvfrom(RECVFROM_SIG)
|
||||||
#else
|
#else
|
||||||
@@ -233,14 +281,24 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
realgetsockopt(socket, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &type_len);
|
realgetsockopt(socket, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &type_len);
|
||||||
*/
|
*/
|
||||||
//if(sock_type == SOCK_DGRAM && address != NULL && address_len != NULL) {
|
//if(sock_type == SOCK_DGRAM && address != NULL && address_len != NULL) {
|
||||||
zts_getsockname(socket, address, address_len);
|
//zts_getsockname(socket, address, address_len);
|
||||||
//}
|
//}
|
||||||
|
// TODO: Explore more efficient means of adjusting buffer
|
||||||
|
unsigned short port;
|
||||||
|
unsigned int addr;
|
||||||
err = read(socket, buffer, length);
|
err = read(socket, buffer, length);
|
||||||
|
int addr_info_len = sizeof(addr) + sizeof(port);
|
||||||
|
memcpy(&addr, buffer, sizeof(addr));
|
||||||
|
memcpy(&port, buffer + sizeof(addr), sizeof(port));
|
||||||
|
memmove(buffer, (buffer + addr_info_len), err - addr_info_len);
|
||||||
|
address->sin_addr.s_addr = addr;
|
||||||
|
address->sin_port = port;
|
||||||
|
// zts_getsockname(socket, address, address_len);
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
perror("read:\n");
|
perror("read:\n");
|
||||||
return err;
|
return err < 0 ? err : err - addr_info_len; // Adjust reported buffer size to exclude address info
|
||||||
}
|
}
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// ----------------------------------- recvmsg() --------------------------------
|
// ----------------------------------- recvmsg() --------------------------------
|
||||||
@@ -311,7 +369,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
// TX
|
// TCP TX
|
||||||
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1write(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1write(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
|
||||||
{
|
{
|
||||||
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
@@ -319,7 +377,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
(*env)->ReleaseByteArrayElements(env, buf, body, 0);
|
(*env)->ReleaseByteArrayElements(env, buf, body, 0);
|
||||||
return written_bytes;
|
return written_bytes;
|
||||||
}
|
}
|
||||||
// RX
|
// TCP RX
|
||||||
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1read(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
|
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1read(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
|
||||||
{
|
{
|
||||||
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
@@ -657,20 +715,36 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
struct getsockname_st rpc_st;
|
struct getsockname_st rpc_st;
|
||||||
rpc_st.sockfd = sockfd;
|
rpc_st.sockfd = sockfd;
|
||||||
memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
|
memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
|
||||||
|
LOGV("A\n");
|
||||||
int rpcfd = rpc_send_command(api_netpath, RPC_GETSOCKNAME, sockfd, &rpc_st, sizeof(struct getsockname_st));
|
int rpcfd = rpc_send_command(api_netpath, RPC_GETSOCKNAME, sockfd, &rpc_st, sizeof(struct getsockname_st));
|
||||||
|
LOGV("b\n");
|
||||||
|
|
||||||
/* read address info from service */
|
/* read address info from service */
|
||||||
char addrbuf[sizeof(struct sockaddr_storage)];
|
char addrbuf[sizeof(struct sockaddr_storage)];
|
||||||
|
LOGV("c\n");
|
||||||
|
|
||||||
memset(&addrbuf, 0, sizeof(struct sockaddr_storage));
|
memset(&addrbuf, 0, sizeof(struct sockaddr_storage));
|
||||||
|
LOGV("d\n");
|
||||||
|
|
||||||
|
|
||||||
if(rpcfd > -1)
|
if(rpcfd > -1)
|
||||||
if(read(rpcfd, &addrbuf, sizeof(struct sockaddr_storage)) > 0)
|
if(read(rpcfd, &addrbuf, sizeof(struct sockaddr_storage)) > 0)
|
||||||
close(rpcfd);
|
close(rpcfd);
|
||||||
|
LOGV("e\n");
|
||||||
|
|
||||||
|
|
||||||
struct sockaddr_storage sock_storage;
|
struct sockaddr_storage sock_storage;
|
||||||
memcpy(&sock_storage, addrbuf, sizeof(struct sockaddr_storage));
|
memcpy(&sock_storage, addrbuf, sizeof(struct sockaddr_storage));
|
||||||
|
LOGV("Afn");
|
||||||
|
|
||||||
*addrlen = sizeof(struct sockaddr_in);
|
*addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
memcpy(addr, &sock_storage, (*addrlen > sizeof(sock_storage)) ? sizeof(sock_storage) : *addrlen);
|
memcpy(addr, &sock_storage, (*addrlen > sizeof(sock_storage)) ? sizeof(sock_storage) : *addrlen);
|
||||||
|
LOGV("g\n");
|
||||||
|
|
||||||
addr->sa_family = AF_INET;
|
addr->sa_family = AF_INET;
|
||||||
|
LOGV("h-\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user