Re-work of thread model

This commit is contained in:
Joseph Henry
2019-02-06 22:00:39 -08:00
parent 292fcdda2c
commit 2fdcf025e1
138 changed files with 7567 additions and 15053 deletions

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ExampleAndroidApp</name>
<comment>Project ExampleAndroidApp created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,2 @@
connection.project.dir=
eclipse.preferences.version=1

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,2 @@
connection.project.dir=..
eclipse.preferences.version=1

View File

@@ -20,15 +20,25 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
debuggable true
jniDebuggable true
minifyEnabled false
}
}
}
dependencies {
implementation 'com.squareup.picasso:picasso:2.71828'
implementation files('libs/libzt-android-debug.aar')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation("com.squareup.okhttp3:okhttp:3.12.0")
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
}

View File

@@ -0,0 +1,79 @@
package com.example.exampleandroidapp;
import com.zerotier.libzt.ZeroTierSocketFactory;
import com.zerotier.libzt.ZeroTier;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.concurrent.ThreadLocalRandom;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HTTPWorker extends Thread {
@Override
public void run() {
long tid = Thread.currentThread().getId();
// Test: Perform randomly-delayed HTTP GET requests
if (true) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.socketFactory(new ZeroTierSocketFactory());
OkHttpClient client = builder.build();
Request request1 = new Request.Builder()
.url("http://11.7.7.223:80/warandpeace.txt")
.build();
Request request2 = new Request.Builder()
.url("http://11.7.7.223:8082/pumpkin.jpg")
.build();
RequestBody formBody = new FormBody.Builder()
.add("message", "Your message")
.build();
Request request3 = new Request.Builder()
.url("http://11.7.7.223:8082/")
.post(formBody)
.build();
long i = 0;
for (;;) {
try {
System.out.println("PEER STATUS IS = " + ZeroTier.get_peer_status(0x7caea82fc4L));
int randomNum = ThreadLocalRandom.current().nextInt(0, 2 + 1);
i++;
Response response = null;
if (randomNum == 0) {
response = client.newCall(request1).execute();
}
if (randomNum == 1) {
//response = client.newCall(request2).execute();
response = client.newCall(request1).execute();
}
if (randomNum == 2) {
//response = client.newCall(request3).execute();
response = client.newCall(request1).execute();
//System.out.println(tid+"::POST");
//continue;
}
InputStream in = response.body().byteStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println(tid+"::GET: i="+i+", len="+buffer.toByteArray().length);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
//System.exit(0);
}
}
}
}
}

View File

@@ -1,103 +1,442 @@
package com.example.exampleandroidapp;
import java.util.concurrent.ThreadLocalRandom;
import java.io.ByteArrayOutputStream;
import java.net.*;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.FormBody;
import com.zerotier.libzt.ZeroTier;
import com.zerotier.libzt.ZTSocketAddress;
import com.zerotier.libzt.ZTFDSet;
import com.zerotier.libzt.ZeroTierSocket;
import com.zerotier.libzt.ZeroTierSocketFactory;
import com.zerotier.libzt.ZeroTierSSLSocketFactory;
//import com.zerotier.libzt.ZeroTierEventListener;
import com.zerotier.libzt.ZeroTierSocketImplFactory;
import com.example.exampleandroidapp.MyZeroTierEventListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import javax.net.ssl.SSLContext;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Callback;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
import android.widget.ImageView;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
public class MainActivity extends AppCompatActivity {
String requestURL = "http://11.7.7.223:80/";
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("zt-shared");
private static String createDataSize(int msgSize) {
StringBuilder sb = new StringBuilder(msgSize);
for (int i=0; i<msgSize; i++) {
sb.append('a');
}
return sb.toString();
}
/*
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
String HTTP_POST(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.socketFactory(new ZeroTierSocketFactory());
OkHttpClient client = builder.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
void HTTP_GET() throws IOException {
}
String sampleJson(String player1, String player2) {
return "{'winCondition':'HIGH_SCORE',"
+ "'name':'Bowling',"
+ "'round':4,"
+ "'lastSaved':1367702411696,"
+ "'dateStarted':1367702378785,"
+ "'players':["
+ "{'name':'" + player1 + "','history':[10,8,6,7,8],'color':-13388315,'total':39},"
+ "{'name':'" + player2 + "','history':[6,10,5,10,10],'color':-48060,'total':41}"
+ "]}";
}
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ZeroTier zt = new ZeroTier();
new Thread(new Runnable() {
public void run() {
final String path = getApplicationContext().getFilesDir() + "/zerotier";
long nwid = 0xe42a7f55c2b9be61L;
// WD TEST
if (true) {
System.out.println("Starting ZeroTier...");
MyZeroTierEventListener listener = new MyZeroTierEventListener();
ZeroTier.start(getApplicationContext().getFilesDir() + "/zerotier3", listener, 9994);
// Test modes
boolean blocking_start_call = true;
boolean client_mode = true;
boolean tcp = false;
boolean loop = true;
int fd = -1, client_fd = -1, err, r, w, length = 0, flags = 0;
byte[] rxBuffer;
byte[] txBuffer = "welcome to the machine".getBytes();
String remoteAddrStr = "172.28.221.116";
String localAddrStr = "1.2.3.4";
int portNo = 4040;
ZTSocketAddress remoteAddr, localAddr;
ZTSocketAddress sockname = new ZTSocketAddress();
ZTSocketAddress addr = new ZTSocketAddress();
// METHOD 1 (easy)
// Blocking call that waits for all components of the service to start
System.out.println("Starting ZT service...");
if (blocking_start_call) {
zt.startjoin(path, nwid);
}
System.out.println("ZT service ready.");
// Device/Node address info
System.out.println("path=" + zt.get_path());
long nodeId = zt.get_node_id();
System.out.println("nodeId=" + Long.toHexString(nodeId));
int numAddresses = zt.get_num_assigned_addresses(nwid);
System.out.println("this node has (" + numAddresses + ") assigned addresses on network " + Long.toHexString(nwid));
for (int i=0; i<numAddresses; i++) {
zt.get_address_at_index(nwid, i, sockname);
//System.out.println("address[" + i + "] = " + sockname.toString()); // ip:port
System.out.println("address[" + i + "] = " + sockname.toCIDR());
}
zt.get_6plane_addr(nwid, nodeId, sockname);
System.out.println("6PLANE address = " + sockname.toCIDR());
System.out.println("mode:tcp");
if ((fd = zt.socket(zt.AF_INET, zt.SOCK_STREAM, 0)) < 0) {
System.out.println("error creating socket");
return;
}
// CLIENT
int lengthToRead;
if (client_mode) {
remoteAddr = new ZTSocketAddress(remoteAddrStr, portNo);
if ((err = zt.connect(fd, remoteAddr)) < 0) {
System.out.println("error connecting (err=" + err + ")");
return;
}
int n = 20000;
String in = "echo!";
String echo_msg = "";
for (int i = 0; i < n; i += 1) {
echo_msg += in;
}
w = zt.write(fd, echo_msg.getBytes());
//rxBuffer = new byte[100];
//lengthToRead = 100;
System.out.println("w="+w);
//System.out.println("reading bytes...");
//r = zt.read(fd, rxBuffer, lengthToRead);
//System.out.println("r="+r);
//System.out.println("string="+new String(rxBuffer));
while (listener.isOnline == false) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
System.out.println("joining network...");
ZeroTier.join(0x0);
System.out.println("waiting for callback");
while (listener.isNetworkReady == false) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
//
System.exit(0);
}
System.out.println("Starting ZeroTier...");
MyZeroTierEventListener listener = new MyZeroTierEventListener();
ZeroTier.start(getApplicationContext().getFilesDir() + "/zerotier3", listener, 9994);
//System.out.println("ZTSDK nodeId=" + Long.toHexString(ZeroTier.get_node_id()));
while (listener.isOnline == false) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
System.out.println("joining network...");
ZeroTier.join(0x0);
System.out.println("waiting for callback");
while (listener.isNetworkReady == false) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
// Start threads
List<Thread> threads = new ArrayList<>();
for(int i = 0;i < 5;i++){
try {
Thread.sleep(500);
} catch (Exception e) {}
HTTPWorker thread = new HTTPWorker();
thread.start();
threads.add(thread);
}
System.out.println("sleeping...");
try {
Thread.sleep(60000000);
} catch (Exception e) {}
System.exit(0);
// Test: setsockopt() and getsockopt() [non-exhaustive]
/*
if (true) {
try {
ZeroTierSocket zts = new ZeroTierSocket();
zts.connect(new InetSocketAddress("11.7.7.223", 8082));
zts.setSoTimeout(1337);
int to = zts.getSoTimeout();
assert to == 1337;
} catch (Exception e) {
}
}
*/
// Test: Perform randomly-delayed HTTP GET requests
if (false) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.socketFactory(new ZeroTierSocketFactory());
OkHttpClient client = builder.build();
Request request1 = new Request.Builder()
.url("http://11.7.7.223:8082/")
.build();
long i = 0;
for (;;) {
try {
Thread.sleep((long)(Math.random() * 250));
Response response = client.newCall(request1).execute();
i++;
System.out.println("GET: i="+i+", len="+response.toString().length());
//response.close();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
e.printStackTrace();
}
}
}
// Test: Perform randomly-delayed HTTP GET requests
if (true) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.socketFactory(new ZeroTierSocketFactory());
OkHttpClient client = builder.build();
Request request1 = new Request.Builder()
.url("http://11.7.7.223:80/warandpeace.txt")
.header("Transfer-Encoding", "chunked")
//.header("Connection","close")
.build();
Request request2 = new Request.Builder()
.url("http://11.7.7.223:8082/pumpkin.jpg")
.header("Transfer-Encoding", "chunked")
.header("Connection","close")
.build();
String postMessage = "what?";
try {
postMessage = new String(createDataSize(1024).getBytes(), "UTF8");
}
catch (Exception e)
{
System.out.println(e);
}
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
okhttp3.RequestBody body = RequestBody.create(JSON, postMessage);
//RequestBody formBody = new FormBody.Builder()
// .add("message", postMessage)
// .build();
Request request3 = new Request.Builder()
.url("http://11.7.7.223:8082/")
//.retryOnConnectionFailure(true)
.header("Transfer-Encoding", "chunked")
.header("Connection","close")
//.header("Connection","keep-alive")
.post(body)
.build();
long i = 0;
for (;;) {
try {
System.out.println("iteration="+i);
int randomNum = ThreadLocalRandom.current().nextInt(0, 2 + 1);
Thread.sleep(10);
i++;
Response response = null;
if (randomNum == 0) {
System.out.println("(0) GET: war");
response = client.newCall(request1).execute();
}
if (randomNum == 1) {
System.out.println("(1) GET: pumpkin");
response = client.newCall(request2).execute();
}
if (randomNum == 2) {
System.out.println("(2) POST: data");
response = client.newCall(request3).execute();
response.close();
continue;
}
InputStream in = response.body().byteStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println("GET: i="+i+", len="+buffer.toByteArray().length);
response.close();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
}
// Test: Perform randomly-delayed HTTP GET requests
if (true) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.socketFactory(new ZeroTierSocketFactory());
OkHttpClient client = builder.build();
Request request = new Request.Builder()
.url(requestURL+"warandpeace.txt")
.build();
long i = 0;
for (;;) {
try {
//Thread.sleep((long)(Math.random()) );
//System.out.println("iteration="+i);
i++;
Response response = client.newCall(request).execute();
//System.out.println(response.body().string());
InputStream in = response.body().byteStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println("\tCOMPLETE, i="+i+", len="+buffer.toByteArray().length);
/*
//Bitmap bitmap = BitmapFactory.decodeByteArray(buffer.toByteArray(), 0, buffer.toByteArray().length);
//ImageView imageView = (ImageView) findViewById(R.id.imageView);
//imageView.setImageBitmap(bitmap);
*/
/*
BufferedInputStream bufferedInputStream = new BufferedInputStream(in);
Bitmap bitmap=BitmapFactory.decodeStream(bufferedInputStream);
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(bitmap);
*/
//
// Thread.sleep(5000);
//response.close();
} catch (Exception e) {
System.out.println("EXCEPTION:"+e);
//System.exit(0);
e.printStackTrace();
}
}
}
// ...
// Test #2: HttpURLConnection
if (false)
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext context = null;
// Set runtime default socket implementation factory
try {
//Socket.setSocketImplFactory(new ZeroTierSocketImplFactory());
//SSLSocket.setSocketImplFactory(new ZeroTierSocketImplFactory());
context = SSLContext.getInstance("SSL");
//context.init(null, null, null);
context.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
ZeroTierSSLSocketFactory customSocketFactory = new ZeroTierSSLSocketFactory(context.getSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(customSocketFactory);
// Test HTTP client
String GET_URL = "https://10.6.6.152";
String USER_AGENT = "Mozilla/5.0";
try {
URL obj = new URL(GET_URL);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setSSLSocketFactory(customSocketFactory);
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
System.out.println("neat?");
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpsURLConnection.HTTP_OK)
{
// success
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} else {
System.out.println("GET request failed");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
).start();
}
}

View File

@@ -0,0 +1,82 @@
package com.example.exampleandroidapp;
import com.zerotier.libzt.ZeroTier;
import com.zerotier.libzt.ZeroTierEventListener;
public class MyZeroTierEventListener implements ZeroTierEventListener {
public boolean isNetworkReady = false;
public boolean isOnline = false;
public void onZeroTierEvent(long id, int eventCode)
{
if (eventCode == ZeroTier.EVENT_NODE_UP) {
System.out.println("EVENT_NODE_UP: nodeId=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NODE_ONLINE) {
// The core service is running properly and can join networks now
System.out.println("EVENT_NODE_ONLINE: nodeId=" + Long.toHexString(ZeroTier.get_node_id()));
isOnline = true;
}
if (eventCode == ZeroTier.EVENT_NODE_OFFLINE) {
// Network does not seem to be reachable by any available strategy
System.out.println("EVENT_NODE_OFFLINE");
}
if (eventCode == ZeroTier.EVENT_NODE_DOWN) {
// Called when the node is shutting down
System.out.println("EVENT_NODE_DOWN");
}
if (eventCode == ZeroTier.EVENT_NODE_IDENTITY_COLLISION) {
// Another node with this identity already exists
System.out.println("EVENT_NODE_IDENTITY_COLLISION");
}
if (eventCode == ZeroTier.EVENT_NODE_UNRECOVERABLE_ERROR) {
// Try again
System.out.println("EVENT_NODE_UNRECOVERABLE_ERROR");
}
if (eventCode == ZeroTier.EVENT_NODE_NORMAL_TERMINATION) {
// Normal closure
System.out.println("EVENT_NODE_NORMAL_TERMINATION");
}
if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP4) {
// We have at least one assigned address and we've received a network configuration
System.out.println("ZTS_EVENT_NETWORK_READY_IP4: nwid=" + Long.toHexString(id));
isNetworkReady = true;
}
if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP6) {
// We have at least one assigned address and we've received a network configuration
System.out.println("ZTS_EVENT_NETWORK_READY_IP6: nwid=" + Long.toHexString(id));
isNetworkReady = true;
}
if (eventCode == ZeroTier.EVENT_NETWORK_DOWN) {
// Someone called leave(), we have no assigned addresses, or otherwise cannot use this interface
System.out.println("EVENT_NETWORK_DOWN: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NETWORK_REQUESTING_CONFIG) {
// Waiting for network configuration
System.out.println("EVENT_NETWORK_REQUESTING_CONFIG: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NETWORK_OK) {
// Config received and this node is authorized for this network
System.out.println("EVENT_NETWORK_OK: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NETWORK_ACCESS_DENIED) {
// You are not authorized to join this network
System.out.println("EVENT_NETWORK_ACCESS_DENIED: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NETWORK_NOT_FOUND) {
// The virtual network does not exist
System.out.println("EVENT_NETWORK_NOT_FOUND: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_NETWORK_CLIENT_TOO_OLD) {
// The core version is too old
System.out.println("EVENT_NETWORK_CLIENT_TOO_OLD: nwid=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_PEER_P2P) {
System.out.println("EVENT_PEER_P2P: id=" + Long.toHexString(id));
}
if (eventCode == ZeroTier.EVENT_PEER_RELAY) {
System.out.println("EVENT_PEER_RELAY: id=" + Long.toHexString(id));
}
}
}

View File

@@ -15,4 +15,12 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_width="136dp"
android:layout_height="213dp"
app:srcCompat="@android:color/transparent"
tools:layout_editor_absoluteX="25dp"
tools:layout_editor_absoluteY="16dp" />
</android.support.constraint.ConstraintLayout>

View File

@@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleWindowsCSharpApp", "ExampleWindowsCSharpApp\ExampleWindowsCSharpApp.csproj", "{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BC236939-C661-4FEB-8935-4A61C2ECEC19}
EndGlobalSection
EndGlobal

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

View File

@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ExampleWindowsCSharpApp</RootNamespace>
<AssemblyName>ExampleWindowsCSharpApp</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="libzt.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using ZeroTier;
namespace ExampleWindowsCSharpApp
{
class Program
{
static void Main(string[] args)
{
ulong nwid = 0xe4da7455b2b9ee6a;
Console.Write("waiting for libzt to come online...\n");
libzt.zts_startjoin("config_path", nwid);
Console.Write("I am " + libzt.zts_get_node_id().ToString("X") +"\n");
Console.Write("ZT ready\n");
int fd;
int err = 0;
bool clientMode = false;
if ((fd = libzt.zts_socket(2, 1, 0)) < 0)
{
Console.Write("error creating socket\n");
}
// CLIENT
if (clientMode == true)
{
string remoteAddrStr = "172.28.221.116";
Int16 remotePort = 2323;
// Convert managed address object to pointer for unmanaged code
libzt.SockAddrIn addr = new libzt.SockAddrIn();
addr.Family = (byte)libzt.SockAddrFamily.Inet;
addr.Port = IPAddress.HostToNetworkOrder((Int16)remotePort);
addr.Addr = (uint)IPAddress.Parse(remoteAddrStr).Address;
IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn)));
Marshal.StructureToPtr(addr, addrPtr, false);
int addrlen = Marshal.SizeOf(addr);
if ((err = libzt.zts_connect(fd, addrPtr, addrlen)) < 0)
{
Console.Write("error connecting to remote server\n");
}
// Send message
string msgStr = "Hello from C#!";
byte[] msgBuf = Encoding.ASCII.GetBytes(msgStr);
int buflen = System.Text.ASCIIEncoding.ASCII.GetByteCount(msgStr);
if ((err = libzt.zts_write(fd, msgBuf, buflen)) < 0)
{
Console.Write("error writing to remote server\n");
}
libzt.zts_close(fd);
Marshal.FreeHGlobal(addrPtr);
}
else // SERVER
{
string localAddrStr = "0.0.0.0";
Int16 bindPort = 5050;
libzt.SockAddrIn addr = new libzt.SockAddrIn();
addr.Family = (byte)libzt.SockAddrFamily.Inet;
addr.Port = IPAddress.HostToNetworkOrder((Int16)bindPort);
addr.Addr = (uint)IPAddress.Parse(localAddrStr).Address;
IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn)));
Marshal.StructureToPtr(addr, addrPtr, false);
int addrlen = Marshal.SizeOf(addr);
if ((err = libzt.zts_bind(fd, addrPtr, addrlen)) < 0)
{
Console.Write("error binding to local port\n");
}
if ((err = libzt.zts_listen(fd, 1)) < 0)
{
Console.Write("error putting socket in listening state\n");
}
int accfd;
Console.Write("waiting to accept connection...\n");
if ((accfd = libzt.zts_accept(fd, IntPtr.Zero, IntPtr.Zero)) < 0)
{
Console.Write("error accepting incoming connection\n");
}
Console.Write("accepted connection!\n");
// Read message
byte[] msgBuf = new byte[32];
int buflen = 32;
Console.Write("reading from client...\n");
if ((err = libzt.zts_read(accfd, msgBuf, buflen)) < 0)
{
Console.Write("error reading from remote client\n");
}
Console.Write("read " + err + " bytes from client\n");
string msgStr = System.Text.Encoding.UTF8.GetString(msgBuf, 0, msgBuf.Length);
Console.Write("msg from client = " + msgStr + "\n");
libzt.zts_close(fd);
libzt.zts_close(accfd);
Marshal.FreeHGlobal(addrPtr);
}
Console.Write("fd=" + fd);
Console.Write("wrote=" + err);
libzt.zts_stop();
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ExampleWindowsCSharpApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ExampleWindowsCSharpApp")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("74f548e3-64fd-41ff-9416-0ae1fc24e8be")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ZeroTier
{
static class libzt
{
public enum SockAddrFamily
{
Inet = 2,
Inet6 = 10
}
[StructLayout(LayoutKind.Sequential)]
public struct SockAddr
{
public ushort Family;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public byte[] Data;
};
[StructLayout(LayoutKind.Sequential)]
public struct SockAddrIn
{
byte len; // unique to lwIP
public byte Family;
public Int16 Port;
public uint Addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Zero;
}
[StructLayout(LayoutKind.Sequential)]
public struct SockAddrIn6
{
public ushort Family;
public ushort Port;
public uint FlowInfo;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Addr;
public uint ScopeId;
};
/****************************************************************************/
/* ZeroTier Service Controls */
/****************************************************************************/
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_start(string path);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_startjoin(string path, ulong nwid);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_stop();
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_join(ulong nwid);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_leave(ulong nwid);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_get_homepath(string homePath, int len);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int64 zts_get_node_id();
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_running();
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_has_address(ulong nwid);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_get_address(ulong nwid, IntPtr addr, int address_family);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_get_6plane_addr(IntPtr addr, string nwid, string nodeId);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_get_rfc4193_addr(IntPtr addr, string nwid, string nodeId);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern long zts_get_peer_count();
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_get_peer_address(string peer, ulong nodeId);
/****************************************************************************/
/* Socket-like API */
/****************************************************************************/
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_socket(int socket_family, int socket_type, int protocol);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_connect(int fd, IntPtr addr, int addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_bind(int fd, IntPtr addr, int addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_listen(int fd, int backlog);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_accept(int fd, IntPtr addr, IntPtr addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_setsockopt(int fd, int level, int optname, IntPtr optval, int optlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_getsockopt(int fd, int level, int optname, IntPtr optval, IntPtr optlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_getsockname(int fd, IntPtr addr, IntPtr addrlen);
/*
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_getpeername(int fd, System.IntPtr addr, IntPtr addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_gethostname(string name, int len);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_sethostname(string name, int len);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern IntPtr *zts_gethostbyname(string name);
*/
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_close(int fd);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_select(int nfds, IntPtr readfds, IntPtr writefds, IntPtr exceptfds, IntPtr timeout);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_fcntl(int fd, int cmd, int flags);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_ioctl(int fd, ulong request, IntPtr argp);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_send(int fd, byte[] buf, int len, int flags);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_sendto(int fd, byte[] buf, int len, int flags, IntPtr addr, int addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_sendmsg(int fd, byte[] msg, int flags);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_recv(int fd, byte[] buf, int len, int flags);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_recvfrom(int fd, byte[] buf, int len, int flags, IntPtr addr, IntPtr addrlen);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_recvmsg(int fd, byte[] msg, int flags);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_read(int fd, byte[] buf, int len);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_write(int fd, byte[] buf, int len);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_shutdown(int fd, int how);
/*
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_add_dns_nameserver(System.IntPtr addr);
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_del_dns_nameserver(System.IntPtr addr);
*/
}
}

View File

@@ -1,280 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
// Simple Java example for libzt using JNI
import com.zerotier.libzt.ZeroTier;
import com.zerotier.libzt.ZTSocketAddress;
import com.zerotier.libzt.ZTFDSet;
import java.lang.Thread;
public class ExampleApp {
static { System.loadLibrary("zt"); } // load libzt.dylib or libzt.so
static void sleep(int ms)
{
try { Thread.sleep(ms); }
catch (InterruptedException e) { e.printStackTrace(); }
}
public static void main(String[] args)
{
final ZeroTier zt = new ZeroTier();
new Thread(new Runnable()
{
public void run()
{
String path = "/Users/joseph/op/zt/libzt/ztjni"; // Where node's config files are stored
long nwid = 0xa09acf7233e4b071L;
// Test modes
boolean blocking_start_call = true;
boolean client_mode = false;
boolean tcp = false;
boolean loop = true; // RX/TX multiple times
boolean idle = false; // Idle loop after node comes online. For testing reachability
boolean use_select = true;
int fd = -1, client_fd = -1, err, r, w, lengthToRead = 0, flags = 0;
byte[] rxBuffer;
byte[] txBuffer = "welcome to the machine".getBytes();
String remoteAddrStr = "11.7.7.107";
String localAddrStr = "0.0.0.0";
int portNo = 4040;
ZTSocketAddress remoteAddr, localAddr;
ZTSocketAddress sockname = new ZTSocketAddress();
ZTSocketAddress addr = new ZTSocketAddress();
// METHOD 1 (easy)
// Blocking call that waits for all components of the service to start
System.out.println("Starting ZT service...");
if (blocking_start_call) {
zt.startjoin(path, nwid);
}
// METHOD 2
// Optional. Non-blocking call to start service. You'll have to use the below process to determine
// when you are allowed to start making socket calls.
if (!blocking_start_call) {
zt.start(path, true);
while(!zt.ready()) {
try { // Wait for core service to start
Thread.sleep(250);
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
System.out.println("Core started. Networks can be joined after this point");
zt.join(nwid);
// Wait for userspace stack to start, we trigger this by joining a network
while(!zt.stack_running()) {
try {
Thread.sleep(1000);
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
System.out.println("ZT service ready.");
// Device/Node address info
System.out.println("path=" + zt.get_path());
long nodeId = zt.get_node_id();
System.out.println("nodeId=" + Long.toHexString(nodeId));
int numAddresses = zt.get_num_assigned_addresses(nwid);
System.out.println("this node has (" + numAddresses + ") assigned addresses on network " + Long.toHexString(nwid));
for (int i=0; i<numAddresses; i++) {
zt.get_address_at_index(nwid, i, sockname);
//System.out.println("address[" + i + "] = " + sockname.toString()); // ip:port
System.out.println("address[" + i + "] = " + sockname.toCIDR());
}
zt.get_6plane_addr(nwid, nodeId, sockname);
System.out.println("6PLANE address = " + sockname.toCIDR());
// Idle loop test
while(idle) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }
// TCP
if (tcp) {
System.out.println("mode:tcp");
if ((fd = zt.socket(zt.AF_INET, zt.SOCK_STREAM, 0)) < 0) {
System.out.println("error creating socket");
return;
}
// CLIENT
if (client_mode) {
System.out.println("mode:client");
remoteAddr = new ZTSocketAddress(remoteAddrStr, portNo);
if ((err = zt.connect(fd, remoteAddr)) < 0) {
System.out.println("error connecting (err=" + err + ")");
return;
}
String echo_msg = "echo!";
w = zt.write(fd, echo_msg.getBytes());
rxBuffer = new byte[100];
lengthToRead = 100;
System.out.println("reading bytes...");
r = zt.read(fd, rxBuffer);
System.out.println("r="+r);
System.out.println("string="+new String(rxBuffer));
}
// SERVER
if (!client_mode) {
System.out.println("mode:server");
localAddr = new ZTSocketAddress(localAddrStr, portNo);
if ((err = zt.bind(fd, localAddr)) < 0) {
System.out.println("error binding socket to virtual interface");
return;
} if ((err = zt.listen(fd, 1)) < 0) {
System.out.println("error putting socket into listening state");
return;
}
remoteAddr = new ZTSocketAddress(localAddrStr, 0);
client_fd = -1;
if ((client_fd = zt.accept(fd, remoteAddr)) < 0) {
System.out.println("error accepting incoming connection (err=" + client_fd + ")");
return;
}
System.out.println("accepted connection (client_fd=" + client_fd + ")");
rxBuffer = new byte[100];
lengthToRead = 100;
System.out.println("reading bytes...");
r = zt.read(client_fd, rxBuffer);
System.out.println("r="+r);
System.out.println("string="+new String(rxBuffer));
System.out.println("writing bytes...");
String echo_msg = "echo!";
w = zt.write(client_fd, echo_msg.getBytes());
System.out.println("wrote (" + w + ") bytes");
}
}
// UDP
if (!tcp) {
System.out.println("mode:udp");
if ((fd = zt.socket(zt.AF_INET, zt.SOCK_DGRAM, 0)) < 0) {
System.out.println("error creating socket");
return;
}
// CLIENT
if (client_mode) {
System.out.println("mode:client");
localAddr = new ZTSocketAddress(localAddrStr, portNo);
if ((err = zt.bind(fd, localAddr)) < 0) {
System.out.println("error binding socket to virtual interface");
return;
}
remoteAddr = new ZTSocketAddress(remoteAddrStr, portNo);
System.out.println("sending message to: " + remoteAddr.toString());
if (loop) {
while (true) {
sleep(500);
if ((w = zt.sendto(fd, txBuffer, flags, remoteAddr)) < 0) {
System.out.println("error sending bytes");
} else {
System.out.println("sendto()=" + w);
}
}
} else {
if ((w = zt.sendto(fd, txBuffer, flags, remoteAddr)) < 0) {
System.out.println("error sending bytes");
} else {
System.out.println("sendto()=" + w);
}
}
}
// SERVER
if (!client_mode) {
System.out.println("mode:server");
localAddr = new ZTSocketAddress(localAddrStr, portNo);
System.out.println("binding to " + localAddr.toString());
if ((err = zt.bind(fd, localAddr)) < 0) {
System.out.println("error binding socket to virtual interface");
return;
}
rxBuffer = new byte[100];
remoteAddr = new ZTSocketAddress("-1.-1.-1.-1", 0);
// select() loop
ZTFDSet master_set = new ZTFDSet();
master_set.ZERO();
master_set.SET(fd);
int nfds = fd + 1;
if (use_select)
{
while(true)
{
err = zt.select(nfds, master_set, null, null, 0, 100000);
if (err < 0) {
System.out.println("select failed");
} if (err == 0) {
System.out.println("select timed out");
} if (err > 0) {
System.out.println("select detected something to read on");
for (int i = 0; i < nfds; i++)
{
if (master_set.ISSET(i))
{
System.out.println("attempting to read from: " + i);
r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr);
System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer));
}
}
}
}
}
if (!use_select)
{
while(true) {
addr = new ZTSocketAddress();
r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr);
System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer));
}
}
}
}
zt.close(client_fd);
zt.close(fd);
}
}).start();
while(true)
{
try { Thread.sleep(3000); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
}

View File

@@ -1,8 +0,0 @@
## ZeroTier with Java via JNI
***
### ExampleApp
Copy `zt.jar` file into this directory
Extract shared library from JAR file: `jar xf zt.jar libzt.dylib`
Build ExampleApp: `javac -cp ".:zt.jar" ExampleApp.java`

View File

@@ -1,54 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
package com.zerotier.libzt;
public class ZTFDSet
{
byte[] fds_bits = new byte[1024];
public void CLR(int fd)
{
fds_bits[fd] = 0x00;
}
public boolean ISSET(int fd)
{
return fds_bits[fd] == 0x01;
}
public void SET(int fd)
{
fds_bits[fd] = 0x01;
}
public void ZERO()
{
for (int i=0; i<1024; i++) {
fds_bits[i] = 0x00;
}
}
}

View File

@@ -1,92 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
package com.zerotier.libzt;
import com.zerotier.libzt.ZeroTier;
import java.net.InetAddress;
// Designed to transport address information across the JNI boundary
public class ZTSocketAddress
{
public byte[] _ip6 = new byte[16];
public byte[] _ip4 = new byte[4];
public int _family;
public int _port; // Also reused for netmask or prefix
public ZTSocketAddress() {}
public ZTSocketAddress(String ipStr, int port)
{
if(ipStr.contains(":")) {
_family = ZeroTier.AF_INET6;
try {
InetAddress ip = InetAddress.getByName(ipStr);
_ip6 = ip.getAddress();
}
catch (Exception e) { }
}
else if(ipStr.contains(".")) {
_family = ZeroTier.AF_INET;
try {
InetAddress ip = InetAddress.getByName(ipStr);
_ip4 = ip.getAddress();
}
catch (Exception e) { }
}
_port = port;
}
public int getPort() { return _port; }
public int getNetmask() { return _port; }
public int getPrefix() { return _port; }
private String ipString()
{
if (_family == ZeroTier.AF_INET) {
try {
InetAddress inet = InetAddress.getByAddress(_ip4);
return "" + inet.getHostAddress();
} catch (Exception e) {
System.out.println(e);
}
}
if (_family == ZeroTier.AF_INET6) {
try {
InetAddress inet = InetAddress.getByAddress(_ip6);
return "" + inet.getHostAddress();
} catch (Exception e) {
System.out.println(e);
}
}
return "";
}
public String toString() { return ipString() + ":" + _port; }
public String toCIDR() { return ipString() + "/" + _port; }
}

View File

@@ -1,82 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
package com.zerotier.libzt;
import java.net.*;
public class ZeroTier {
public static int AF_INET = 2;
public static int AF_INET6 = 30;
public static int SOCK_STREAM = 1;
public static int SOCK_DGRAM = 2;
public static int O_APPEND = 1024;
public static int O_NONBLOCK = 2048;
public static int O_ASYNC = 8192;
public static int O_DIRECT = 65536;
public static int O_NOATIME = 262144;
public static int F_GETFL = 3;
public static int F_SETFL = 4;
public native void start(String homePath, boolean blocking);
public native void startjoin(String homePath, long nwid);
public native void stop();
public native boolean core_running();
public native boolean stack_running();
public native boolean ready();
public native int join(long nwid);
public native int leave(long nwid);
public native String get_path();
public native long get_node_id();
public native int get_num_assigned_addresses(long nwid);
public native boolean get_address_at_index(long nwid, int index, ZTSocketAddress addr);
public native boolean has_address(long nwid);
public native boolean get_address(long nwid, int address_family, ZTSocketAddress addr);
public native void get_6plane_addr(long nwid, long nodeId, ZTSocketAddress addr);
public native void get_rfc4193_addr(long nwid, long nodeId, ZTSocketAddress addr);
public native int socket(int family, int type, int protocol);
public native int connect(int fd, ZTSocketAddress addr);
public native int bind(int fd, ZTSocketAddress addr);
public native int listen(int fd, int backlog);
public native int accept(int fd, ZTSocketAddress addr);
public native int accept4(int fd, String addr, int port);
public native int close(int fd);
public native int setsockopt(int fd, int level, int optname, int optval, int optlen);
public native int getsockopt(int fd, int level, int optname, int optval, int optlen);
public native int sendto(int fd, byte[] buf, int flags, ZTSocketAddress addr);
public native int send(int fd, byte[] buf, int flags);
public native int recv(int fd, byte[] buf, int flags);
public native int recvfrom(int fd, byte[] buf, int flags, ZTSocketAddress addr);
public native int read(int fd, byte[] buf);
public native int write(int fd, byte[] buf);
public native int shutdown(int fd, int how);
public native boolean getsockname(int fd, ZTSocketAddress addr);
public native int getpeername(int fd, ZTSocketAddress addr);
public native int fcntl(int sock, int cmd, int flag);
public native int select(int nfds, ZTFDSet readfds, ZTFDSet writefds, ZTFDSet exceptfds, int timeout_sec, int timeout_usec);
}

View File

@@ -1,194 +0,0 @@
// This file is built with libzt.a via `make tests`
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#if defined(__APPLE__)
#include <net/ethernet.h>
#endif
#if defined(__linux__)
#include <netinet/ether.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#endif
#include "libzt.h"
unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
int main(int argc , char *argv[])
{
if (argc < 3) {
fprintf(stderr, "usage: layer2 <zt_home_dir> <nwid>\n");
return 1;
}
// initialize library
printf("Starting libzt...\n");
zts_startjoin(argv[1], strtoull(argv[2], NULL, 16));
uint64_t device_id = zts_get_node_id();
fprintf(stderr, "Complete. I am %llx\n", device_id);
// create socket
int fd;
if ((fd = zts_socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
printf("There was a problem creating the raw socket\n");
exit(-1);
}
fprintf(stderr, "Created raw socket (%d)\n", fd);
#if defined(__APPLE__)
fprintf(stderr, "SOCK_RAW not supported on mac builds yet. exiting");
exit(0);
#endif
#if defined(__linux__) // The rest of this file isn't yet supported on non-linux platforms
// get interface index to bind on
struct ifreq if_idx;
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, "libzt0", IFNAMSIZ-1);
if (zts_ioctl(fd, SIOCGIFINDEX, &if_idx) < 0) {
perror("SIOCGIFINDEX");
exit(-1);
}
fprintf(stderr, "if_idx.ifr_ifindex=%d\n", if_idx.ifr_ifindex);
// get MAC address of interface to send on
struct ifreq if_mac;
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, "libzt0", IFNAMSIZ-1);
if (zts_ioctl(fd, SIOCGIFHWADDR, &if_mac) < 0) {
perror("SIOCGIFHWADDR");
exit(-1);
}
const unsigned char* mac=(unsigned char*)if_mac.ifr_hwaddr.sa_data;
fprintf(stderr, "hwaddr=%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
// get IP address of interface to send on
struct ifreq if_ip;
memset(&if_ip, 0, sizeof(struct ifreq));
strncpy(if_ip.ifr_name, "libzt0", IFNAMSIZ-1);
if (zts_ioctl(fd, SIOCGIFADDR, &if_ip) < 0) {
perror("SIOCGIFADDR");
exit(-1);
}
char ipv4_str[INET_ADDRSTRLEN];
struct sockaddr_in *in4 = (struct sockaddr_in *)&if_ip.ifr_addr;
inet_ntop(AF_INET, (const void *)&in4->sin_addr.s_addr, ipv4_str, INET_ADDRSTRLEN);
fprintf(stderr, "addr=%s", ipv4_str);
// construct ethernet header
int tx_len = 0;
char sendbuf[1024];
struct ether_header *eh = (struct ether_header *) sendbuf;
memset(sendbuf, 0, 1024);
// Ethernet header
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
// set destination MAC
int MY_DEST_MAC0 = 0x72;
int MY_DEST_MAC1 = 0x92;
int MY_DEST_MAC2 = 0xd4;
int MY_DEST_MAC3 = 0xfd;
int MY_DEST_MAC4 = 0x43;
int MY_DEST_MAC5 = 0x45;
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
eh->ether_type = htons(ETH_P_IP);
tx_len += sizeof(struct ether_header);
// Construct the IP header
int ttl = 64;
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
iph->ihl = 5;
iph->version = 4;
iph->tos = 16; // Low delay
iph->id = htons(54321);
iph->ttl = ttl; // hops
iph->protocol = 17; // UDP
// Source IP address, can be spoofed
iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
// iph->saddr = inet_addr("192.168.0.112");
// Destination IP address
iph->daddr = inet_addr("10.7.7.1");
tx_len += sizeof(struct iphdr);
// Construct UDP header
struct udphdr *udph = (struct udphdr *) (sendbuf + sizeof(struct iphdr) + sizeof(struct ether_header));
udph->source = htons(3423);
udph->dest = htons(5342);
udph->check = 0; // skip
tx_len += sizeof(struct udphdr);
// Fill in UDP payload
sendbuf[tx_len++] = 0xde;
sendbuf[tx_len++] = 0xad;
sendbuf[tx_len++] = 0xbe;
sendbuf[tx_len++] = 0xef;
// Fill in remaining header info
// Length of UDP payload and header
udph->len = htons(tx_len - sizeof(struct ether_header) - sizeof(struct iphdr));
// Length of IP payload and header
iph->tot_len = htons(tx_len - sizeof(struct ether_header));
// Calculate IP checksum on completed header
iph->check = csum((unsigned short *)(sendbuf+sizeof(struct ether_header)), sizeof(struct iphdr)/2);
// Send packet
// Destination address
struct sockaddr_ll socket_address;
// Index of the network device
socket_address.sll_ifindex = if_idx.ifr_ifindex;
// Address length
socket_address.sll_halen = ETH_ALEN;
// Destination MAC
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
while(1)
{
usleep(10000);
// Send packet
if (zts_sendto(fd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
fprintf(stderr, "Send failed\n");
}
// dismantle all zt virtual taps
zts_stop();
#endif
return 0;
}

View File

@@ -1,36 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
import zerotier.ZeroTier
object ExampleApp extends App {
// load libzt.dylib or libzt.so
System.loadLibrary("zt")
val libzt = new ZeroTier
libzt.startjoin("/Users/joseph/op/zt/libzt/ztjni", 0xa09acf0232a930f7L)
val fd = libzt.socket(2, 1, 0)
println(s"libzt.socket(): $fd")
}

View File

@@ -1,18 +0,0 @@
OSTYPE=$(shell uname -s | tr '[A-Z]' '[a-z]')
BUILD=build/$(OSTYPE)
ifeq ($(OSTYPE),darwin)
SHARED_LIB=libzt.dylib
endif
ifeq ($(OSTYPE),linux)
SHARED_LIB=libzt.so
endif
example_scala_app:
scalac *.scala
copy_dynamic_lib:
cp ../../../$(BUILD)/$(SHARED_LIB) .
clean:
-find . -type f \( -name '*.class' \) -delete

View File

@@ -1,14 +0,0 @@
## ZeroTier with Scala via JNI
***
To get this example project to work, do the following:
- From libzt main directory, build shared library: `make shared_jni_lib`
- Copy the resultant dynamic library (`*.so` or `*.dylib`) from `build/` to this current directory
- Change to this directory and `make example_scala_app`
- Run: `scala -Djava.library.path=$(pwd) -cp "." ExampleApp`
Notes:
Upon execution, it will load the libzt dynamic library via the `loadLibrary` method and begin generating an identity.

View File

@@ -1,76 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
package zerotier;
class ZeroTier {
// socket families
// socket types
// basic service controls
@native def start(path: String, blocking: Boolean): Int
@native def startjoin(path: String, nwid: Long): Int
@native def stop(): Unit
@native def running(): Int
@native def join(nwid: Long): Unit
@native def leave(nwid: Long): Unit
// advanced service controls
//@native def get_path(): Unit
@native def get_node_id(): Long
//@native def get_6plane_addr(): Unit
//@native def get_rfc4193_addr(): Unit
// socket API
@native def socket(socket_family: Int, socket_type: Int, protocol: Int): Int
@native def connect(fd: Int, addr: String, port: Int): Int
@native def bind(fd: Int, addr: String, port: Int): Int
@native def listen(fd: Int, backlog: Int): Int
@native def accept(fd: Int, addr: Object, addrlen: Int): Int
@native def accept4(fd: Int, addr: Object, addrlen: Int, flags: Int): Int
@native def close(fd: Int): Int
@native def setsockopt(fd: Int, level: Int, optname: Int, optval: Object, optlen: Int): Int
@native def getsockopt(fd: Int, level: Int, optname: Int, optval: Object, optlen: Int): Int
@native def read(fd: Int, buf: Object, len: Int): Int
@native def write(fd: Int, buf: Object, len: Int): Int
@native def send(fd: Int, buf: Object, len: Int, flags: Int): Int
@native def sendto(fd: Int, buf: Object, len: Int, addr: Object, addrlen: Int): Int
@native def sendmsg(fd: Int, msg: Object, flags: Int): Int
@native def recv(fd: Int, buf: Object, len: Int, flags: Int): Int
@native def recvfrom(fd: Int, buf: Object, len: Int, addr: Object, addrlen: Int): Int
@native def recvmsg(fd: Int, msg: Object, flags: Int): Int
@native def shutdown(fd: Int, how: Int): Int
//@native def getsockname(): Int
//@native def getpeername(): Int
//@native def gethostname(): Int
//@native def sethostname(): Int
//@native def gethostbyname(): Object
//@native def poll(): Int
//@native def select(): Int
@native def fcntl(fd: Int, cmd: Int, flags: Int): Int
@native def ioctl(fd: Int, request: Long, argp: Object): Int
// stack controls
//@native def add_dns(): Int
//@native def del_dns(): Int
}

View File

@@ -1,374 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
7C6D474121126417004C82ED /* libzt-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CC090842112516900AB1506 /* libzt-static.a */; };
7CC0908021124A1200AB1506 /* wrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0907E21124A1200AB1506 /* wrapper.cpp */; };
7CC0908221124F8900AB1506 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0908121124F8900AB1506 /* Example.swift */; };
7CFEEDAA21123E550071915A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CFEEDA921123E550071915A /* AppDelegate.swift */; };
7CFEEDAC21123E550071915A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CFEEDAB21123E550071915A /* ViewController.swift */; };
7CFEEDAF21123E550071915A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDAD21123E550071915A /* Main.storyboard */; };
7CFEEDB121123E560071915A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDB021123E560071915A /* Assets.xcassets */; };
7CFEEDB421123E560071915A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDB221123E560071915A /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7CC0907D21124A1100AB1506 /* ExampleSwiftApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleSwiftApp-Bridging-Header.h"; sourceTree = "<group>"; };
7CC0907E21124A1200AB1506 /* wrapper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrapper.cpp; sourceTree = "<group>"; };
7CC0907F21124A1200AB1506 /* wrapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wrapper.hpp; sourceTree = "<group>"; };
7CC0908121124F8900AB1506 /* Example.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example.swift; sourceTree = "<group>"; };
7CC090842112516900AB1506 /* libzt-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libzt-static.a"; path = "../../../bin/lib/Debug/libzt-static.a"; sourceTree = "<group>"; };
7CFEEDA621123E550071915A /* ExampleSwiftApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleSwiftApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
7CFEEDA921123E550071915A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7CFEEDAB21123E550071915A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
7CFEEDAE21123E550071915A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
7CFEEDB021123E560071915A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7CFEEDB321123E560071915A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
7CFEEDB521123E560071915A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7CFEEDA321123E550071915A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7C6D474121126417004C82ED /* libzt-static.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7CC090832112516800AB1506 /* Frameworks */ = {
isa = PBXGroup;
children = (
7CC090842112516900AB1506 /* libzt-static.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
7CFEED9D21123E550071915A = {
isa = PBXGroup;
children = (
7CFEEDA821123E550071915A /* ExampleSwiftApp */,
7CFEEDA721123E550071915A /* Products */,
7CC090832112516800AB1506 /* Frameworks */,
);
sourceTree = "<group>";
};
7CFEEDA721123E550071915A /* Products */ = {
isa = PBXGroup;
children = (
7CFEEDA621123E550071915A /* ExampleSwiftApp.app */,
);
name = Products;
sourceTree = "<group>";
};
7CFEEDA821123E550071915A /* ExampleSwiftApp */ = {
isa = PBXGroup;
children = (
7CFEEDA921123E550071915A /* AppDelegate.swift */,
7CFEEDAB21123E550071915A /* ViewController.swift */,
7CFEEDAD21123E550071915A /* Main.storyboard */,
7CFEEDB021123E560071915A /* Assets.xcassets */,
7CFEEDB221123E560071915A /* LaunchScreen.storyboard */,
7CFEEDB521123E560071915A /* Info.plist */,
7CC0907E21124A1200AB1506 /* wrapper.cpp */,
7CC0907F21124A1200AB1506 /* wrapper.hpp */,
7CC0907D21124A1100AB1506 /* ExampleSwiftApp-Bridging-Header.h */,
7CC0908121124F8900AB1506 /* Example.swift */,
);
path = ExampleSwiftApp;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7CFEEDA521123E550071915A /* ExampleSwiftApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7CFEEDB821123E560071915A /* Build configuration list for PBXNativeTarget "ExampleSwiftApp" */;
buildPhases = (
7CFEEDA221123E550071915A /* Sources */,
7CFEEDA321123E550071915A /* Frameworks */,
7CFEEDA421123E550071915A /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = ExampleSwiftApp;
productName = ExampleSwiftApp;
productReference = 7CFEEDA621123E550071915A /* ExampleSwiftApp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7CFEED9E21123E550071915A /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0940;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = ZeroTier;
TargetAttributes = {
7CFEEDA521123E550071915A = {
CreatedOnToolsVersion = 9.4.1;
LastSwiftMigration = 0940;
};
};
};
buildConfigurationList = 7CFEEDA121123E550071915A /* Build configuration list for PBXProject "ExampleSwiftApp" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7CFEED9D21123E550071915A;
productRefGroup = 7CFEEDA721123E550071915A /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7CFEEDA521123E550071915A /* ExampleSwiftApp */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7CFEEDA421123E550071915A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7CFEEDB421123E560071915A /* LaunchScreen.storyboard in Resources */,
7CFEEDB121123E560071915A /* Assets.xcassets in Resources */,
7CFEEDAF21123E550071915A /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7CFEEDA221123E550071915A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7CC0908221124F8900AB1506 /* Example.swift in Sources */,
7CFEEDAC21123E550071915A /* ViewController.swift in Sources */,
7CFEEDAA21123E550071915A /* AppDelegate.swift in Sources */,
7CC0908021124A1200AB1506 /* wrapper.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
7CFEEDAD21123E550071915A /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
7CFEEDAE21123E550071915A /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
7CFEEDB221123E560071915A /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
7CFEEDB321123E560071915A /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
7CFEEDB621123E560071915A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
7CFEEDB721123E560071915A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
7CFEEDB921123E560071915A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 57AG88JR8A;
INFOPLIST_FILE = ExampleSwiftApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[arch=*]" = /Users/joseph/op/zt/libzt_new/bin/lib/Debug;
PRODUCT_BUNDLE_IDENTIFIER = zerotier.ExampleSwiftApp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
7CFEEDBA21123E560071915A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 57AG88JR8A;
INFOPLIST_FILE = ExampleSwiftApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = zerotier.ExampleSwiftApp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7CFEEDA121123E550071915A /* Build configuration list for PBXProject "ExampleSwiftApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7CFEEDB621123E560071915A /* Debug */,
7CFEEDB721123E560071915A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7CFEEDB821123E560071915A /* Build configuration list for PBXNativeTarget "ExampleSwiftApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7CFEEDB921123E560071915A /* Debug */,
7CFEEDBA21123E560071915A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7CFEED9E21123E550071915A /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ExampleSwiftApp.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ExampleSwiftApp.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@@ -1,46 +0,0 @@
//
// AppDelegate.swift
// ExampleSwiftApp
//
// Created by Joseph Henry on 8/1/18.
// Copyright © 2018 ZeroTier. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

View File

@@ -1,98 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@@ -1,73 +0,0 @@
//
// Example.swift
// ExampleSwiftApp
//
// Created by Joseph Henry on 8/1/18.
// Copyright © 2018 ZeroTier. All rights reserved.
//
import Foundation
import UIKit
class MyApplication: UIResponder, UIApplicationDelegate {
static func libzt_example_function()
{
var fd: Int32 = -1;
var err: Int32 = -1;
let clientMode = true;
let remotePort = 4545;
let remoteAddress = "192.168.195.1";
let appDir = String(NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0])
// Start up and create socket
print("starting...");
zts_startjoin(appDir, 0x1c33c1ceb0aa9251);
print("I am ", NSString(format:"%llx", zts_get_node_id()));
fd = zts_socket(2, 1, 0);
if(fd < 0) {
print("error creating socket");
}
print("fd = ", fd);
// Remote address
var in4 = sockaddr_in(sin_len: UInt8(MemoryLayout<sockaddr_in>.size),
sin_family: UInt8(AF_INET),
sin_port: UInt16(remotePort).bigEndian,
sin_addr: in_addr(s_addr: 0),
sin_zero: (0,0,0,0,0,0,0,0))
inet_pton(AF_INET, remoteAddress, &(in4.sin_addr));
// CLIENT
if (clientMode)
{
print("connecting...");
let addrlen = socklen_t(MemoryLayout.size(ofValue: in4))
let a = withUnsafeMutablePointer(to: &in4) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
err = zts_connect(fd, $0, addrlen)
}
}
if(err < 0) {
print("error connecting to remote server");
}
print("connected");
print("sending message to server");
var msg: String = "Hello from Swift!";
err = zts_write(fd, msg, msg.count)
if(err < 0) {
print("error creating socket");
}
print("wrote ", err, " bytes");
zts_close(fd);
}
else // SERVER
{
}
zts_stop();
}
}

View File

@@ -1,71 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#ifndef LIBZT_BRIDGING_HEADER_H
#define LIBZT_BRIDGING_HEADER_H
#include <sys/socket.h>
#include "/Users/joseph/op/zt/libzt_new/include/libzt.h"
// ZT SERVICE CONTROLS
int zts_start(const char *path, int blocking);
int zts_startjoin(const char *path, const uint64_t nwid);
void zts_stop();
int zts_core_running();
int zts_stack_running();
int zts_ready();
int zts_join(uint64_t nwid);
int zts_leave(uint64_t nwid);
uint64_t zts_get_node_id();
// SOCKET API
int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen);
int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
int zts_listen(int fd, int backlog);
int zts_socket(int socket_family, int socket_type, int protocol);
int zts_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen);
int zts_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen);
int zts_close(int fd);
int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen);
int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);
ssize_t zts_send(int fd, const void *buf, size_t len, int flags);
ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen);
ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags);
ssize_t zts_recv(int fd, void *buf, size_t len, int flags);
ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen);
ssize_t zts_recvmsg(int fd, struct msghdr *msg,int flags);
int zts_read(int fd, void *buf, size_t len);
int zts_write(int fd, const void *buf, size_t len);
int zts_shutdown(int fd, int how);
int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
int zts_fcntl(int fd, int cmd, int flags);
int zts_ioctl(int fd, unsigned long request, void *argp);
#endif /* LIBZT_BRIDGING_HEADER_H */

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -1,28 +0,0 @@
//
// ViewController.swift
// ExampleSwiftApp
//
// Created by Joseph Henry on 8/1/18.
// Copyright © 2018 ZeroTier. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
MyApplication.libzt_example_function();
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

View File

@@ -1,20 +0,0 @@
//
// wrapper.cpp
// ExampleSwiftApp
//
// Created by Joseph Henry on 8/1/18.
// Copyright © 2018 ZeroTier. All rights reserved.
//
#include "wrapper.hpp"
#include "/Users/joseph/op/zt/libzt_new/include/libzt.h"
#ifdef __cplusplus
extern "C" {
#endif
// Nothing, implementation is in src/libzt.cpp
#ifdef __cplusplus
}
#endif

View File

@@ -1,14 +0,0 @@
//
// wrapper.hpp
// ExampleSwiftApp
//
// Created by Joseph Henry on 8/1/18.
// Copyright © 2018 ZeroTier. All rights reserved.
//
#ifndef wrapper_hpp
#define wrapper_hpp
#include <stdio.h>
#endif /* wrapper_hpp */

View File

@@ -1,406 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#if defined(__linux__) || defined(__APPLE__)
#include <netdb.h>
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fcntl.h>
#include <vector>
#include <algorithm>
#include <map>
#include "libzt.h"
#include "RingBuffer.h"
#include "ztproxy.hpp"
#if defined(_WIN32)
#include <time.h>
void sleep(unsigned long ms)
{
Sleep(ms);
}
#endif
namespace ZeroTier {
typedef void PhySocket;
ZTProxy::ZTProxy(int proxy_listen_port, std::string nwid, std::string path, std::string internal_addr,
int internal_port, std::string dns_nameserver)
:
_enabled(true),
_run(true),
_proxy_listen_port(proxy_listen_port),
_internal_port(internal_port),
_nwid(nwid),
_internal_addr(internal_addr),
_dns_nameserver(dns_nameserver),
_phy(this,false,true)
{
// Set up TCP listen sockets
// IPv4
struct sockaddr_in in4;
memset(&in4,0,sizeof(in4));
in4.sin_family = AF_INET;
in4.sin_addr.s_addr = Utils::hton((uint32_t)(0x7f000001)); // listen for TCP @127.0.0.1
in4.sin_port = Utils::hton((uint16_t)proxy_listen_port);
_tcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this);
if (!_tcpListenSocket) {
DEBUG_ERROR("Error binding on port %d for IPv4 HTTP listen socket", proxy_listen_port);
}
// IPv6
/*
struct sockaddr_in6 in6;
memset((void *)&in6,0,sizeof(in6));
in6.sin6_family = AF_INET6;
in6.sin6_port = in4.sin_port;
in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1
in6.sin6_port = Utils::hton((uint16_t)proxy_listen_port);
_tcpListenSocket6 = _phy.tcpListen((const struct sockaddr *)&in6,this);
*/
/*
if (!_tcpListenSocket6) {
DEBUG_ERROR("Error binding on port %d for IPv6 HTTP listen socket", proxy_listen_port);
}
*/
_thread = Thread::start(this);
}
ZTProxy::~ZTProxy()
{
_run = false;
_phy.whack();
Thread::join(_thread);
_phy.close(_tcpListenSocket,false);
_phy.close(_tcpListenSocket6,false);
}
void ZTProxy::threadMain()
throw()
{
// Add DNS nameserver
if (_dns_nameserver.length() > 0) {
DEBUG_INFO("setting DNS nameserver (%s)", _dns_nameserver.c_str());
struct sockaddr_in dns_address;
dns_address.sin_addr.s_addr = inet_addr(_dns_nameserver.c_str());
zts_add_dns_nameserver((struct sockaddr*)&dns_address);
}
TcpConnection *conn = NULL;
uint32_t msecs = 1;
struct timeval tv;
tv.tv_sec = msecs / 1000;
tv.tv_usec = (msecs % 1000) * 1000;
int ret = 0;
// Main I/O loop
// Moves data between client application socket and libzt VirtualSocket
while(_run) {
_phy.poll(1);
conn_m.lock();
// build fd_sets to select upon
FD_ZERO(&read_set);
FD_ZERO(&write_set);
nfds = 0;
for (size_t i=0; i<clist.size(); i++) {
FD_SET(clist[i]->zfd, &read_set);
FD_SET(clist[i]->zfd, &write_set);
nfds = clist[i]->zfd > nfds ? clist[i]->zfd : nfds;
}
ret = zts_select(nfds + 1, &read_set, &write_set, NULL, &tv);
if (ret > 0) {
for (int fd_i=0; fd_i<nfds+1; fd_i++) { // I/O needs to be handled on at least one fd
// RX, Handle data incoming from libzt
if (FD_ISSET(fd_i, &read_set)) {
int wr = 0, rd = 0;
conn = zmap[fd_i];
if (conn == NULL) {
DEBUG_ERROR("invalid conn");
exit(0);
}
// read data from libzt and place it on ring buffer
conn->rx_m.lock();
if (conn->RXbuf->count() > 0) {
//DEBUG_INFO("libzt has incoming data on fd=%d, RXing via conn=%p, sock=%p",
// conn->zfd, conn, conn->client_sock);
}
if ((rd = zts_read(conn->zfd, conn->RXbuf->get_buf(),ZT_MAX_MTU)) < 0) {
DEBUG_ERROR("error while reading data from libzt, err=%d", rd);
}
else {
//DEBUG_INFO("LIBZT -> RXBUFFER = %d bytes", rd);
conn->RXbuf->produce(rd);
}
// attempt to write data to client from buffer
if ((wr = _phy.streamSend(conn->client_sock, conn->RXbuf->get_buf(), conn->RXbuf->count())) < 0) {
DEBUG_ERROR("error while writing the data from the RXbuf to the client PhySocket, err=%d", wr);
}
else {
//DEBUG_INFO("RXBUFFER -> CLIENT = %d bytes", wr);
conn->RXbuf->consume(wr);
}
conn->rx_m.unlock();
}
// TX, Handle data outgoing from client to libzt
if (FD_ISSET(fd_i, &write_set)) {
int wr = 0;
conn = zmap[fd_i];
if (conn == NULL) {
DEBUG_ERROR("invalid conn, possibly closed before transmit was possible");
}
// read data from client and place it on ring buffer
conn->tx_m.lock();
if (conn->TXbuf->count() > 0) {
// DEBUG_INFO("client has outgoing data of len=%d on fd=%d, TXing via conn=%p, sock=%p",
// conn->TXbuf->count(), conn->zfd, conn, conn->client_sock);
if ((wr = zts_write(conn->zfd, conn->TXbuf->get_buf(), conn->TXbuf->count())) < 0) {
DEBUG_ERROR("error while sending the data over libzt, err=%d", wr);
}
else {
//DEBUG_INFO("TXBUFFER -> LIBZT = %d bytes", wr);
conn->TXbuf->consume(wr); // data is presumed sent, mark it as such in the ringbuffer
}
}
conn->tx_m.unlock();
}
}
}
conn_m.unlock();
}
}
bool isValidIPAddress(const char *ip)
{
struct sockaddr_in sa;
return inet_pton(AF_INET, ip, &(sa.sin_addr)) == 1;
}
void ZTProxy::phyOnTcpData(PhySocket *sock, void **uptr, void *data, unsigned long len)
{
int wr = 0, zfd = -1, err = 0;
DEBUG_EXTRA("sock=%p, len=%lu", sock, len);
std::string host = _internal_addr;
TcpConnection *conn = cmap[sock];
if (conn == NULL) {
DEBUG_ERROR("invalid conn");
exit(0);
}
if (conn->zfd < 0) { // no connection yet
if (host == "") {
DEBUG_ERROR("invalid hostname or address (empty)");
return;
}
DEBUG_INFO("establishing proxy connection...");
uint16_t dest_port, ipv;
dest_port = _internal_port;
host = _internal_addr;
if (isValidIPAddress(host.c_str()) == false) {
// try to resolve this if it isn't an IP address
struct hostent *h = zts_gethostbyname(host.c_str());
if (h == NULL) {
DEBUG_ERROR("unable to resolve hostname (%s) (errno=%d)", host.c_str(), errno);
return;
}
// TODO
// host = h->h_addr_list[0];
}
// determine address type
ipv = host.find(":") != std::string::npos ? 6 : 4;
// connect to remote host
if (ipv == 4) {
DEBUG_INFO("attempting to proxy [0.0.0.0:%d -> %s:%d]", _proxy_listen_port, host.c_str(), dest_port);
struct sockaddr_in in4;
memset(&in4,0,sizeof(in4));
in4.sin_family = AF_INET;
in4.sin_addr.s_addr = inet_addr(host.c_str());
in4.sin_port = Utils::hton(dest_port);
if ((zfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
DEBUG_ERROR("unable to create socket (errno=%d)", errno);
return;
}
if ((err = zts_connect(zfd, (const struct sockaddr *)&in4, sizeof(in4))) < 0) {
DEBUG_ERROR("unable to connect to remote host (errno=%d)", errno);
return;
}
}
if (ipv == 6) {
//DEBUG_INFO("attempting to proxy [0.0.0.0:%d -> %s:%d]", _proxy_listen_port, host.c_str(), dest_port);
/*
struct sockaddr_in6 in6;
memset(&in6,0,sizeof(in6));
in6.sin6_family = AF_INET;
struct hostent *server;
server = gethostbyname2((char*)host.c_str(),AF_INET6);
memmove((char *) &in6.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
in6.sin6_port = Utils::hton(dest_port);
zfd = zts_socket(AF_INET, SOCK_STREAM, 0);
err = zts_connect(zfd, (const struct sockaddr *)&in6, sizeof(in6));
*/
}
if (zfd < 0 || err < 0) {
// now release TX buffer contents we previously saved, since we can't connect
DEBUG_ERROR("error while connecting to remote host (zfd=%d, err=%d)", zfd, err);
conn->tx_m.lock();
conn->TXbuf->reset();
conn->tx_m.unlock();
return;
}
else {
DEBUG_INFO("successfully connected to remote host");
}
conn_m.lock();
// on success, add connection entry to map, set physock for later
clist.push_back(conn);
conn->zfd = zfd;
conn->client_sock = sock;
cmap[conn->client_sock] = conn;
zmap[zfd] = conn;
conn_m.unlock();
}
// Write data coming from client TCP connection to its TX buffer, later emptied into libzt by threadMain I/O loop
conn->tx_m.lock();
if ((wr = conn->TXbuf->write((const char *)data, len)) < 0) {
DEBUG_ERROR("there was an error while writing data from client to tx buffer, err=%d", wr);
}
else {
// DEBUG_INFO("CLIENT -> TXBUFFER = %d bytes", wr);
}
conn->tx_m.unlock();
}
void ZTProxy::phyOnTcpAccept(PhySocket *sockL, PhySocket *sockN, void **uptrL, void **uptrN,
const struct sockaddr *from)
{
DEBUG_INFO("sockL=%p, sockN=%p", sockL, sockN);
TcpConnection *conn = new TcpConnection();
conn->client_sock = sockN;
cmap[sockN]=conn;
}
void ZTProxy::phyOnTcpClose(PhySocket *sock, void **uptr)
{
DEBUG_INFO("sock=%p", sock);
conn_m.lock();
TcpConnection *conn = cmap[sock];
if (conn) {
conn->client_sock=NULL;
if (conn->zfd >= 0) {
zts_close(conn->zfd);
}
cmap.erase(sock);
for (size_t i=0; i<clist.size(); i++) {
if (conn == clist[i]) {
clist.erase(clist.begin()+i);
break;
}
}
zmap[conn->zfd] = NULL;
delete conn;
conn = NULL;
}
#if defined(_WIN32)
closesocket(_phy.getDescriptor(sock));
#else
close(_phy.getDescriptor(sock));
#endif
conn_m.unlock();
}
void ZTProxy::phyOnDatagram(PhySocket *sock, void **uptr, const struct sockaddr *localAddr,
const struct sockaddr *from, void *data, unsigned long len) {
DEBUG_INFO();
}
void ZTProxy::phyOnTcpWritable(PhySocket *sock, void **uptr) {
DEBUG_INFO();
}
void ZTProxy::phyOnFileDescriptorActivity(PhySocket *sock, void **uptr, bool readable, bool writable) {
DEBUG_INFO("sock=%p", sock);
}
void ZTProxy::phyOnTcpConnect(PhySocket *sock, void **uptr, bool success) {
DEBUG_INFO("sock=%p", sock);
}
void ZTProxy::phyOnUnixClose(PhySocket *sock, void **uptr) {
DEBUG_INFO("sock=%p", sock);
}
void ZTProxy::phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len) {
DEBUG_INFO("sock=%p, len=%lu", sock, len);
}
void ZTProxy::phyOnUnixWritable(PhySocket *sock, void **uptr, bool lwip_invoked) {
DEBUG_INFO("sock=%p", sock);
}
}
int main(int argc, char **argv)
{
if (argc < 6 || argc > 7) {
printf("\nZeroTier TCP Proxy Service\n");
printf("ztproxy [config_file_path] [local_listen_port] [nwid] [zt_host_addr] [zt_resource_port] [optional_dns_nameserver]\n");
exit(0);
}
std::string path = argv[1];
int proxy_listen_port = atoi(argv[2]);
std::string nwidstr = argv[3];
std::string internal_addr = argv[4];
int internal_port = atoi(argv[5]);
std::string dns_nameserver= "";//argv[6];
// Start ZeroTier Node
// Join Network which contains resources we need to proxy
DEBUG_INFO("waiting for libzt to come online");
uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16);
zts_startjoin(path.c_str(), nwid);
ZeroTier::ZTProxy *proxy = new ZeroTier::ZTProxy(proxy_listen_port, nwidstr, path, internal_addr, internal_port, dns_nameserver);
if (proxy) {
printf("\nZTProxy started. Listening on %d\n", proxy_listen_port);
printf("Traffic will be proxied to and from %s:%d on network %s\n", internal_addr.c_str(), internal_port, nwidstr.c_str());
printf("Proxy Node config files and key stored in: %s/\n\n", path.c_str());
while(1) {
sleep(1);
}
}
else {
printf("unable to create proxy\n");
}
return 0;
}

View File

@@ -1,132 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#ifndef ZT_ZTPROXY_HPP
#define ZT_ZTPROXY_HPP
#include "Constants.hpp"
#include "Thread.hpp"
#include "InetAddress.hpp"
#include "Mutex.hpp"
#include "Phy.hpp"
#include "OSUtils.hpp"
#if defined(__linux__) || defined(__APPLE__)
#include <sys/select.h>
#endif
#include <queue>
#include <vector>
#include <stdio.h>
#define BUF_SZ 1024*1024
namespace ZeroTier {
typedef void PhySocket;
class ZTProxy;
class TcpConnection
{
public:
int zfd;
PhySocket *client_sock;
RingBuffer *TXbuf, *RXbuf;
Mutex tx_m, rx_m;
TcpConnection() {
zfd = -1;
TXbuf = new RingBuffer(BUF_SZ);
RXbuf = new RingBuffer(BUF_SZ);
}
~TcpConnection() {
delete TXbuf;
delete RXbuf;
client_sock = NULL;
TXbuf = NULL;
RXbuf = NULL;
}
};
class ZTProxy
{
friend class Phy<ZTProxy *>;
public:
ZTProxy(int proxy_listen_port, std::string nwid, std::string path, std::string internal_addr, int internal_port, std::string _dns_nameserver);
~ZTProxy();
// Send incoming data to intended host
void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len);
void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len);
void phyOnTcpWritable(PhySocket *sock,void **uptr);
void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable);
// Establish outgoing connection to intended host
void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success);
// Accept connection
void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from);
// Handle the closure of a Unix Domain socket
void phyOnUnixClose(PhySocket *sock,void **uptr);
void phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len);
void phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_invoked);
// Handle the closure of a TCP connection
void phyOnTcpClose(PhySocket *sock,void **uptr);
void threadMain()
throw();
TcpConnection *getConnection(PhySocket *sock);
private:
volatile bool _enabled;
volatile bool _run;
Mutex conn_m;
fd_set read_set, write_set;
int nfds;
int _proxy_listen_port;
int _internal_port;
std::string _nwid;
std::string _internal_addr;
std::string _dns_nameserver;
Thread _thread;
Phy<ZTProxy*> _phy;
PhySocket *_tcpListenSocket;
PhySocket *_tcpListenSocket6;
// mapping from ZeroTier VirtualSocket fd to TcpConnection pointer
std::map<int, TcpConnection*> zmap;
// mapping from ZeroTier PhySocket to TcpConnection pointer
std::map<PhySocket*, TcpConnection*> cmap;
std::vector<TcpConnection*> clist;
};
}
#endif