不再需要jni
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
[package]
|
||||
name = "vnt-jni"
|
||||
version = "1.2.10"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
vnt = {path="../vnt"}
|
||||
parking_lot = "0.12.1"
|
||||
|
||||
jni = { version = "0.21.1", default-features = false }
|
||||
log = "0.4.20"
|
||||
spki = { version = "0.7.2", features = ["fingerprint", "alloc","base64","pem"]}
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.13"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib", "cdylib"]
|
||||
@@ -1 +0,0 @@
|
||||
## 提供给安卓端使用
|
||||
@@ -1,77 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
import top.wherewego.vnt.jni.param.*;
|
||||
|
||||
/**
|
||||
* 回调
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public interface CallBack {
|
||||
/**
|
||||
* 连接成功的回调
|
||||
*/
|
||||
void success();
|
||||
|
||||
/**
|
||||
* 创建虚拟网卡成功的回调方法
|
||||
* 仅在 windows/linux/macos上使用
|
||||
*
|
||||
* @param info 网卡信息
|
||||
*/
|
||||
void createTun(DeviceInfo info);
|
||||
|
||||
/**
|
||||
* 连接服务端
|
||||
*
|
||||
* @param info 将要连接的服务端信息
|
||||
*/
|
||||
void connect(ConnectInfo info);
|
||||
|
||||
/**
|
||||
* 和服务端握手
|
||||
*
|
||||
* @param info 握手信息
|
||||
* @return 是否确认握手
|
||||
*/
|
||||
boolean handshake(HandshakeInfo info);
|
||||
|
||||
/**
|
||||
* 注册成功回调
|
||||
*
|
||||
* @param info 注册信息
|
||||
* @return 是否确认注册信息
|
||||
*/
|
||||
boolean register(RegisterInfo info);
|
||||
|
||||
/**
|
||||
* 创建网卡回调
|
||||
* 仅在android上使用
|
||||
*
|
||||
* @param info 创建配置
|
||||
* @return 网卡fd
|
||||
*/
|
||||
|
||||
int generateTun(DeviceConfig info);
|
||||
|
||||
/**
|
||||
* 对端用户列表
|
||||
*
|
||||
* @param infoArray
|
||||
*/
|
||||
void peerClientList(PeerClientInfo[] infoArray);
|
||||
|
||||
|
||||
/**
|
||||
* 异常回调
|
||||
*
|
||||
* @param info 错误信息
|
||||
*/
|
||||
void error(ErrorInfo info);
|
||||
|
||||
/**
|
||||
* 服务停止
|
||||
*/
|
||||
void stop();
|
||||
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 启动配置
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class Config implements Serializable {
|
||||
/**
|
||||
* 是否是tap模式,仅支持windows
|
||||
*/
|
||||
private boolean tap;
|
||||
/**
|
||||
* 组网标识
|
||||
*/
|
||||
private String token;
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 客户端间加密的密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 客户端间加密模式 aes_gcm/aes_cbc/aes_ecb/sm4_cbc
|
||||
*/
|
||||
private String cipherModel;
|
||||
/**
|
||||
* 打洞模式 ipv4/ipv6/all
|
||||
*/
|
||||
private String punchModel;
|
||||
/**
|
||||
* mtu 默认自动计算
|
||||
*/
|
||||
private Integer mtu;
|
||||
/**
|
||||
* 是否开启服务端加密
|
||||
*/
|
||||
private boolean serverEncrypt;
|
||||
/**
|
||||
* 设备id,请使用唯一值
|
||||
*/
|
||||
private String deviceId;
|
||||
/**
|
||||
* 服务端地址
|
||||
*/
|
||||
private String server;
|
||||
/**
|
||||
* dns地址
|
||||
*/
|
||||
private String[] dns;
|
||||
/**
|
||||
* 端口映射
|
||||
*/
|
||||
private String[] portMapping;
|
||||
/**
|
||||
* stun服务地址
|
||||
*/
|
||||
private String[] stunServer;
|
||||
/**
|
||||
* 和服务端使用tcp通信,默认使用udp
|
||||
*/
|
||||
private boolean tcp;
|
||||
/**
|
||||
* 指定组网IP
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 开启加密指纹校验
|
||||
*/
|
||||
private boolean finger;
|
||||
/**
|
||||
* 延迟优先,默认p2p优先
|
||||
*/
|
||||
private boolean firstLatency;
|
||||
/**
|
||||
* 点对网入口 格式 192.168.0.0/26,10.26.0.2
|
||||
*/
|
||||
private String[] inIps;
|
||||
/**
|
||||
* 点对网出口 格式 192.168.0.0/26
|
||||
*/
|
||||
private String[] outIps;
|
||||
/**
|
||||
* 端口组,udp会监听一组端口,tcp监听ports[0]端口
|
||||
*/
|
||||
private int[] ports;
|
||||
/**
|
||||
* 虚拟网卡名称 仅在linux、windows、macos上支持
|
||||
*/
|
||||
private String deviceName;
|
||||
/**
|
||||
* enum: relay/p2p/all
|
||||
*/
|
||||
private String useChannel;
|
||||
/**
|
||||
* 模拟丢包率,取0~1之间的数,为null表示不丢包,1表示全部丢包
|
||||
*/
|
||||
private Double packetLossRate;
|
||||
/**
|
||||
* 模拟延迟 单位毫秒(ms)
|
||||
*/
|
||||
private Integer packetDelay;
|
||||
|
||||
public Config() {
|
||||
}
|
||||
|
||||
public boolean isTap() {
|
||||
return tap;
|
||||
}
|
||||
|
||||
public void setTap(boolean tap) {
|
||||
this.tap = tap;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getCipherModel() {
|
||||
return cipherModel;
|
||||
}
|
||||
|
||||
public void setCipherModel(String cipherModel) {
|
||||
this.cipherModel = cipherModel;
|
||||
}
|
||||
|
||||
public String getPunchModel() {
|
||||
return punchModel;
|
||||
}
|
||||
|
||||
public void setPunchModel(String punchModel) {
|
||||
this.punchModel = punchModel;
|
||||
}
|
||||
|
||||
public Integer getMtu() {
|
||||
return mtu;
|
||||
}
|
||||
|
||||
public void setMtu(Integer mtu) {
|
||||
this.mtu = mtu;
|
||||
}
|
||||
|
||||
public boolean isServerEncrypt() {
|
||||
return serverEncrypt;
|
||||
}
|
||||
|
||||
public void setServerEncrypt(boolean serverEncrypt) {
|
||||
this.serverEncrypt = serverEncrypt;
|
||||
}
|
||||
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public void setServer(String server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public String[] getDns() {
|
||||
return dns;
|
||||
}
|
||||
|
||||
public void setDns(String[] dns) {
|
||||
this.dns = dns;
|
||||
}
|
||||
public String[] getPortMapping() {
|
||||
return portMapping;
|
||||
}
|
||||
|
||||
public void setPortMapping(String[] portMapping) {
|
||||
this.portMapping = portMapping;
|
||||
}
|
||||
|
||||
public String[] getStunServer() {
|
||||
return stunServer;
|
||||
}
|
||||
|
||||
public void setStunServer(String[] stunServer) {
|
||||
this.stunServer = stunServer;
|
||||
}
|
||||
|
||||
public boolean isTcp() {
|
||||
return tcp;
|
||||
}
|
||||
|
||||
public void setTcp(boolean tcp) {
|
||||
this.tcp = tcp;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public boolean isFinger() {
|
||||
return finger;
|
||||
}
|
||||
|
||||
public void setFinger(boolean finger) {
|
||||
this.finger = finger;
|
||||
}
|
||||
|
||||
public boolean isFirstLatency() {
|
||||
return firstLatency;
|
||||
}
|
||||
|
||||
public void setFirstLatency(boolean firstLatency) {
|
||||
this.firstLatency = firstLatency;
|
||||
}
|
||||
|
||||
public String[] getInIps() {
|
||||
return inIps;
|
||||
}
|
||||
|
||||
public void setInIps(String[] inIps) {
|
||||
this.inIps = inIps;
|
||||
}
|
||||
|
||||
public String[] getOutIps() {
|
||||
return outIps;
|
||||
}
|
||||
|
||||
public void setOutIps(String[] outIps) {
|
||||
this.outIps = outIps;
|
||||
}
|
||||
|
||||
public int[] getPorts() {
|
||||
return ports;
|
||||
}
|
||||
|
||||
public void setPorts(int[] ports) {
|
||||
this.ports = ports;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public String getUseChannel() {
|
||||
return useChannel;
|
||||
}
|
||||
|
||||
public void setUseChannel(String useChannel) {
|
||||
this.useChannel = useChannel;
|
||||
}
|
||||
|
||||
public Double getPacketLossRate() {
|
||||
return packetLossRate;
|
||||
}
|
||||
|
||||
public void setPacketLossRate(Double packetLossRate) {
|
||||
this.packetLossRate = packetLossRate;
|
||||
}
|
||||
|
||||
public Integer getPacketDelay() {
|
||||
return packetDelay;
|
||||
}
|
||||
|
||||
public void setPacketDelay(Integer packetDelay) {
|
||||
this.packetDelay = packetDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Config{" +
|
||||
"tap=" + tap +
|
||||
", token='" + token + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", cipherModel='" + cipherModel + '\'' +
|
||||
", punchModel='" + punchModel + '\'' +
|
||||
", mtu=" + mtu +
|
||||
", serverEncrypt=" + serverEncrypt +
|
||||
", deviceId='" + deviceId + '\'' +
|
||||
", server='" + server + '\'' +
|
||||
", dns=" + Arrays.toString(dns) +
|
||||
", portMapping=" + Arrays.toString(portMapping) +
|
||||
", stunServer=" + Arrays.toString(stunServer) +
|
||||
", tcp=" + tcp +
|
||||
", ip='" + ip + '\'' +
|
||||
", finger=" + finger +
|
||||
", firstLatency=" + firstLatency +
|
||||
", inIps=" + Arrays.toString(inIps) +
|
||||
", outIps=" + Arrays.toString(outIps) +
|
||||
", ports=" + Arrays.toString(ports) +
|
||||
", deviceName='" + deviceName + '\'' +
|
||||
", useChannel='" + useChannel + '\'' +
|
||||
", packetLossRate=" + packetLossRate +
|
||||
", packetDelay=" + packetDelay +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
/**
|
||||
* ip转换
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class IpUtils {
|
||||
/**
|
||||
* 将整数的ip地址转成字符串,例如 0 转成 "0.0.0.0"
|
||||
*
|
||||
* @param ipAddress
|
||||
* @return
|
||||
*/
|
||||
public static String intToIpAddress(int ipAddress) {
|
||||
|
||||
return ((ipAddress & 0xFF000000) >>> 24) + "." +
|
||||
((ipAddress & 0x00FF0000) >>> 16) + "." +
|
||||
((ipAddress & 0x0000FF00) >>> 8) + "." +
|
||||
(ipAddress & 0x000000FF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回掩码的长度
|
||||
*
|
||||
* @param subnetMask
|
||||
* @return
|
||||
*/
|
||||
public static int subnetMaskToPrefixLength(int subnetMask) {
|
||||
int prefixLength = 0;
|
||||
int bit = 1 << 31;
|
||||
|
||||
while (subnetMask != 0) {
|
||||
if ((subnetMask & bit) != bit) {
|
||||
break;
|
||||
}
|
||||
prefixLength++;
|
||||
subnetMask <<= 1;
|
||||
}
|
||||
|
||||
return prefixLength;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
/**
|
||||
* 对端设备信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class PeerRouteInfo {
|
||||
private final int virtualIp;
|
||||
private final String name;
|
||||
private final String status;
|
||||
private final Route route;
|
||||
|
||||
public PeerRouteInfo(int virtualIp, String name, String status, Route route) {
|
||||
this.virtualIp = virtualIp;
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
public int getVirtualIp() {
|
||||
return virtualIp;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Route getRoute() {
|
||||
return route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PeerDeviceInfo{" +
|
||||
"virtualIp=" + IpUtils.intToIpAddress(virtualIp) +
|
||||
", name='" + name + '\'' +
|
||||
", status='" + status + '\'' +
|
||||
", route=" + route +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
/**
|
||||
* 路由信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class Route {
|
||||
/**
|
||||
* 是否使用tcp
|
||||
*/
|
||||
private final boolean tcp;
|
||||
private final String address;
|
||||
private final byte metric;
|
||||
private final int rt;
|
||||
|
||||
|
||||
public Route(boolean tcp, String address, byte metric, int rt) {
|
||||
this.tcp = tcp;
|
||||
this.address = address;
|
||||
this.metric = metric;
|
||||
this.rt = rt;
|
||||
}
|
||||
|
||||
public boolean isTcp() {
|
||||
return tcp;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public byte getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
public int getRt() {
|
||||
return rt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Route{" +
|
||||
"tcp=" + tcp +
|
||||
", address='" + address + '\'' +
|
||||
", metric=" + metric +
|
||||
", rt=" + rt +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package top.wherewego.vnt.jni;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* vnt的Java映射
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class Vnt implements Closeable {
|
||||
private final long raw;
|
||||
|
||||
public Vnt(Config config, CallBack callBack) throws Exception {
|
||||
this.raw = new0(config, callBack);
|
||||
if (this.raw == 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
stop0(raw);
|
||||
}
|
||||
|
||||
public void await() {
|
||||
wait0(raw);
|
||||
}
|
||||
|
||||
public boolean awaitTimeout(long ms) {
|
||||
return waitTimeout0(raw, ms);
|
||||
}
|
||||
|
||||
public PeerRouteInfo[] list() {
|
||||
return list0(raw);
|
||||
}
|
||||
|
||||
private native long new0(Config config, CallBack callBack) throws Exception;
|
||||
|
||||
private native void stop0(long raw);
|
||||
|
||||
private native void wait0(long raw);
|
||||
|
||||
private native boolean waitTimeout0(long raw, long ms);
|
||||
|
||||
private native void drop0(long raw);
|
||||
|
||||
private native PeerRouteInfo[] list0(long raw);
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
drop0(raw);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
/**
|
||||
* 连接信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class ConnectInfo {
|
||||
private final long count;
|
||||
private final String address;
|
||||
|
||||
public ConnectInfo(long count, String address) {
|
||||
this.count = count;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectInfo{" +
|
||||
"count=" + count +
|
||||
", address='" + address + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
import top.wherewego.vnt.jni.IpUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 创建网卡所需信息,仅在android上使用
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class DeviceConfig {
|
||||
/**
|
||||
* 虚拟IP
|
||||
*/
|
||||
public final int virtualIp;
|
||||
/**
|
||||
* 掩码
|
||||
*/
|
||||
public final int virtualNetmask;
|
||||
/**
|
||||
* 网关
|
||||
*/
|
||||
public final int virtualGateway;
|
||||
/**
|
||||
* 虚拟网段
|
||||
*/
|
||||
public final int virtualNetwork;
|
||||
/**
|
||||
* 额外路由,来自点对网的路由配置
|
||||
*/
|
||||
public final String[] externalRoute;
|
||||
|
||||
public DeviceConfig(int virtualIp, int virtualNetmask, int virtualGateway, int virtualNetwork, String[] externalRoute) {
|
||||
this.virtualIp = virtualIp;
|
||||
this.virtualNetmask = virtualNetmask;
|
||||
this.virtualGateway = virtualGateway;
|
||||
this.virtualNetwork = virtualNetwork;
|
||||
this.externalRoute = externalRoute;
|
||||
}
|
||||
|
||||
public int getVirtualIp() {
|
||||
return virtualIp;
|
||||
}
|
||||
|
||||
public int getVirtualNetmask() {
|
||||
return virtualNetmask;
|
||||
}
|
||||
|
||||
public int getVirtualGateway() {
|
||||
return virtualGateway;
|
||||
}
|
||||
|
||||
public int getVirtualNetwork() {
|
||||
return virtualNetwork;
|
||||
}
|
||||
|
||||
public String[] getExternalRoute() {
|
||||
return externalRoute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeviceConfig{" +
|
||||
"virtualIp=" + IpUtils.intToIpAddress(virtualIp) +
|
||||
", virtualNetmask=" + IpUtils.intToIpAddress(virtualNetmask) +
|
||||
", virtualGateway=" + IpUtils.intToIpAddress(virtualGateway) +
|
||||
", virtualNetwork=" + IpUtils.intToIpAddress(virtualNetwork) +
|
||||
", externalRoute=" + Arrays.toString(externalRoute) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
/**
|
||||
* 网卡信息 仅在 windows/linux/macos上使用
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class DeviceInfo {
|
||||
/**
|
||||
* 虚拟网卡名称
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* 虚拟网卡版本
|
||||
*/
|
||||
private final String version;
|
||||
|
||||
public DeviceInfo(String name, String version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeviceInfo{" +
|
||||
"name='" + name + '\'' +
|
||||
", version='" + version + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
/**
|
||||
* 异常回调信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class ErrorInfo {
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
public final ErrorCodeEnum code;
|
||||
/**
|
||||
* 错误信息,可能为空
|
||||
*/
|
||||
public final String msg;
|
||||
|
||||
public ErrorInfo(int code, String msg) {
|
||||
switch (code) {
|
||||
case 1:
|
||||
this.code = ErrorCodeEnum.TokenError;
|
||||
break;
|
||||
case 2:
|
||||
this.code = ErrorCodeEnum.Disconnect;
|
||||
break;
|
||||
case 3:
|
||||
this.code = ErrorCodeEnum.AddressExhausted;
|
||||
break;
|
||||
case 4:
|
||||
this.code = ErrorCodeEnum.IpAlreadyExists;
|
||||
break;
|
||||
case 5:
|
||||
this.code = ErrorCodeEnum.InvalidIp;
|
||||
break;
|
||||
default:
|
||||
this.code = ErrorCodeEnum.Unknown;
|
||||
}
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public ErrorCodeEnum getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public enum ErrorCodeEnum {
|
||||
TokenError,
|
||||
Disconnect,
|
||||
AddressExhausted,
|
||||
IpAlreadyExists,
|
||||
InvalidIp,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ErrorInfo{" +
|
||||
"code=" + code +
|
||||
", msg='" + msg + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
/**
|
||||
* 握手回调信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class HandshakeInfo {
|
||||
/**
|
||||
* 公钥 pem格式 CRLF分隔,不加密时为空
|
||||
*/
|
||||
private final String publicKey;
|
||||
/**
|
||||
* 公钥签名,不加密时为空
|
||||
*/
|
||||
private final String finger;
|
||||
/**
|
||||
* 服务端版本
|
||||
*/
|
||||
private final String version;
|
||||
|
||||
public HandshakeInfo() {
|
||||
this.publicKey = "publicKey";
|
||||
this.finger = "finger";
|
||||
this.version = "version";
|
||||
}
|
||||
|
||||
public HandshakeInfo(String publicKey, String finger, String version) {
|
||||
this.publicKey = publicKey;
|
||||
this.finger = finger;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public String getFinger() {
|
||||
return finger;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HandshakeInfo{" +
|
||||
"publicKey='" + publicKey + '\'' +
|
||||
", finger='" + finger + '\'' +
|
||||
", version='" + version + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
import top.wherewego.vnt.jni.IpUtils;
|
||||
|
||||
/**
|
||||
* 创建网卡所需信息,仅在android上使用
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class PeerClientInfo {
|
||||
/**
|
||||
* 虚拟IP
|
||||
*/
|
||||
public final int virtualIp;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
public final String name;
|
||||
/**
|
||||
* 是否在线
|
||||
*/
|
||||
public final boolean online;
|
||||
/**
|
||||
* 是否开启客户端加密,不同加密状态的不能通信
|
||||
*/
|
||||
public final boolean clientSecret;
|
||||
|
||||
public PeerClientInfo(int virtualIp, String name, boolean online, boolean clientSecret) {
|
||||
this.virtualIp = virtualIp;
|
||||
this.name = name;
|
||||
this.online = online;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public int getVirtualIp() {
|
||||
return virtualIp;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
public boolean isClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PeerDeviceInfo{" +
|
||||
"virtualIp=" + IpUtils.intToIpAddress(virtualIp) +
|
||||
", name='" + name + '\'' +
|
||||
", online=" + online +
|
||||
", clientSecret=" + clientSecret +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package top.wherewego.vnt.jni.param;
|
||||
|
||||
import top.wherewego.vnt.jni.IpUtils;
|
||||
|
||||
/**
|
||||
* 注册回调信息
|
||||
*
|
||||
* @author https://github.com/lbl8603/vnt
|
||||
*/
|
||||
public class RegisterInfo {
|
||||
/**
|
||||
* 虚拟IP
|
||||
*/
|
||||
public final int virtualIp;
|
||||
/**
|
||||
* 掩码
|
||||
*/
|
||||
public final int virtualNetmask;
|
||||
/**
|
||||
* 网关
|
||||
*/
|
||||
public final int virtualGateway;
|
||||
|
||||
public RegisterInfo(int virtualIp, int virtualNetmask, int virtualGateway) {
|
||||
this.virtualIp = virtualIp;
|
||||
this.virtualNetmask = virtualNetmask;
|
||||
this.virtualGateway = virtualGateway;
|
||||
}
|
||||
|
||||
public int getVirtualIp() {
|
||||
return virtualIp;
|
||||
}
|
||||
|
||||
public int getVirtualNetmask() {
|
||||
return virtualNetmask;
|
||||
}
|
||||
|
||||
public int getVirtualGateway() {
|
||||
return virtualGateway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RegisterInfo{" +
|
||||
"virtualIp='" + IpUtils.intToIpAddress(virtualIp) + '\'' +
|
||||
", virtualNetmask='" + IpUtils.intToIpAddress(virtualNetmask) + '\'' +
|
||||
", virtualGateway='" + IpUtils.intToIpAddress(virtualGateway) + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
|
||||
use jni::{JNIEnv, JavaVM};
|
||||
use spki::der::pem::LineEnding;
|
||||
use spki::EncodePublicKey;
|
||||
|
||||
use vnt::handle::callback::ConnectInfo;
|
||||
#[cfg(target_os = "android")]
|
||||
use vnt::handle::callback::DeviceConfig;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
use vnt::DeviceInfo;
|
||||
use vnt::{ErrorInfo, HandshakeInfo, PeerClientInfo, RegisterInfo, VntCallback};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CallBack {
|
||||
jvm: Arc<JavaVM>,
|
||||
this: GlobalRef,
|
||||
connect_info_class: GlobalRef,
|
||||
handshake_info_class: GlobalRef,
|
||||
error_info_class: GlobalRef,
|
||||
register_info_class: GlobalRef,
|
||||
#[cfg(target_os = "android")]
|
||||
device_config_class: GlobalRef,
|
||||
peer_client_info_class: GlobalRef,
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
device_info_class: GlobalRef,
|
||||
}
|
||||
|
||||
unsafe impl Send for CallBack {}
|
||||
|
||||
fn find_class_global_ref(env: &mut JNIEnv, class: &str) -> jni::errors::Result<GlobalRef> {
|
||||
let class = env.find_class(class)?;
|
||||
env.new_global_ref(class)
|
||||
}
|
||||
impl CallBack {
|
||||
pub fn new(jvm: JavaVM, this: GlobalRef) -> jni::errors::Result<Self> {
|
||||
let mut env = jvm.attach_current_thread_as_daemon()?;
|
||||
let connect_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ConnectInfo")?;
|
||||
let handshake_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/HandshakeInfo")?;
|
||||
let error_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ErrorInfo")?;
|
||||
let register_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/RegisterInfo")?;
|
||||
#[cfg(target_os = "android")]
|
||||
let device_config_class = crate::callback::find_class_global_ref(
|
||||
&mut env,
|
||||
"top/wherewego/vnt/jni/param/DeviceConfig",
|
||||
)?;
|
||||
let peer_client_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/PeerClientInfo")?;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
let device_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/DeviceInfo")?;
|
||||
Ok(Self {
|
||||
jvm: Arc::new(jvm),
|
||||
this,
|
||||
connect_info_class,
|
||||
handshake_info_class,
|
||||
error_info_class,
|
||||
register_info_class,
|
||||
#[cfg(target_os = "android")]
|
||||
device_config_class,
|
||||
peer_client_info_class,
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
device_info_class,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CallBack {
|
||||
fn success0(&self) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
env.call_method(&self.this, "success", "()V", &[])?;
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
fn create_tun0(&self, info: DeviceInfo) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.device_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(Ljava/lang/String;Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::Object(&env.new_string(info.name)?.into()),
|
||||
JValue::Object(&env.new_string(info.version)?.into()),
|
||||
],
|
||||
)?;
|
||||
env.call_method(
|
||||
&self.this,
|
||||
"createTun",
|
||||
"(Ltop/wherewego/vnt/jni/param/DeviceInfo;)V",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
fn connect0(&self, info: ConnectInfo) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.connect_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(JLjava/lang/String;)V",
|
||||
&[
|
||||
JValue::Long(info.count as _),
|
||||
JValue::Object(&env.new_string(info.address.to_string())?.into()),
|
||||
],
|
||||
)?;
|
||||
env.call_method(
|
||||
&self.this,
|
||||
"connect",
|
||||
"(Ltop/wherewego/vnt/jni/param/ConnectInfo;)V",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
fn handshake0(&self, info: HandshakeInfo) -> jni::errors::Result<bool> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let public_key = if let Some(public_key) = info.public_key {
|
||||
match public_key.to_public_key_pem(LineEnding::CRLF) {
|
||||
Ok(public_key) => env.new_string(public_key)?,
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e);
|
||||
JString::default()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JString::default()
|
||||
};
|
||||
let finger = if let Some(finger) = info.finger {
|
||||
env.new_string(finger)?
|
||||
} else {
|
||||
JString::default()
|
||||
};
|
||||
let class = unsafe { JClass::from_raw(self.handshake_info_class.as_raw()) };
|
||||
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::Object(&public_key),
|
||||
JValue::Object(&finger),
|
||||
JValue::Object(&env.new_string(info.version)?.into()),
|
||||
],
|
||||
)?;
|
||||
let rs = env.call_method(
|
||||
&self.this,
|
||||
"handshake",
|
||||
"(Ltop/wherewego/vnt/jni/param/HandshakeInfo;)Z",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
rs.z()
|
||||
}
|
||||
fn register0(&self, info: RegisterInfo) -> jni::errors::Result<bool> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.register_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(III)V",
|
||||
&[
|
||||
JValue::Int(u32::from(info.virtual_ip) as _),
|
||||
JValue::Int(u32::from(info.virtual_netmask) as _),
|
||||
JValue::Int(u32::from(info.virtual_gateway) as _),
|
||||
],
|
||||
)?;
|
||||
let rs = env.call_method(
|
||||
&self.this,
|
||||
"register",
|
||||
"(Ltop/wherewego/vnt/jni/param/RegisterInfo;)Z",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
rs.z()
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
fn generate_tun0(&self, info: DeviceConfig) -> jni::errors::Result<u32> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.device_config_class.as_raw()) };
|
||||
|
||||
let object_array = env.new_object_array(
|
||||
info.external_route.len() as _,
|
||||
"java/lang/String",
|
||||
JObject::null(),
|
||||
)?;
|
||||
for (index, (network, mask)) in info.external_route.into_iter().enumerate() {
|
||||
let param =
|
||||
env.new_string(format!("{}/{}", network, u32::from(mask).leading_ones()))?;
|
||||
env.set_object_array_element(&object_array, index as _, ¶m)?;
|
||||
}
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(IIII[Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::Int(u32::from(info.virtual_ip) as _),
|
||||
JValue::Int(u32::from(info.virtual_netmask) as _),
|
||||
JValue::Int(u32::from(info.virtual_gateway) as _),
|
||||
JValue::Int(u32::from(info.virtual_network) as _),
|
||||
JValue::Object(&object_array),
|
||||
],
|
||||
)?;
|
||||
let rs = env.call_method(
|
||||
&self.this,
|
||||
"generateTun",
|
||||
"(Ltop/wherewego/vnt/jni/param/DeviceConfig;)I",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
rs.i().map(|v| v as _)
|
||||
}
|
||||
fn peer_client_list0(&self, info_vec: Vec<PeerClientInfo>) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.peer_client_info_class.as_raw()) };
|
||||
let object_array = env.new_object_array(info_vec.len() as _, &class, JObject::null())?;
|
||||
for (index, info) in info_vec.into_iter().enumerate() {
|
||||
let param = env.new_object(
|
||||
&class,
|
||||
"(ILjava/lang/String;ZZ)V",
|
||||
&[
|
||||
JValue::Int(u32::from(info.virtual_ip) as _),
|
||||
JValue::Object(&env.new_string(info.name)?.into()),
|
||||
JValue::Bool(info.status.is_online() as _),
|
||||
JValue::Bool(info.client_secret as _),
|
||||
],
|
||||
)?;
|
||||
env.set_object_array_element(&object_array, index as _, ¶m)?;
|
||||
}
|
||||
|
||||
env.call_method(
|
||||
&self.this,
|
||||
"peerClientList",
|
||||
"([Ltop/wherewego/vnt/jni/param/PeerClientInfo;)V",
|
||||
&[JValue::Object(&object_array)],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn error0(&self, info: ErrorInfo) -> jni::errors::Result<()> {
|
||||
let code: u8 = info.code.into();
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.error_info_class.as_raw()) };
|
||||
let msg = if let Some(msg) = info.msg {
|
||||
env.new_string(msg)?
|
||||
} else {
|
||||
JString::default()
|
||||
};
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(ILjava/lang/String;)V",
|
||||
&[JValue::Int(code as _), JValue::Object(&msg.into())],
|
||||
)?;
|
||||
env.call_method(
|
||||
&self.this,
|
||||
"error",
|
||||
"(Ltop/wherewego/vnt/jni/param/ErrorInfo;)V",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
fn stop0(&self) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
env.call_method(&self.this, "stop", "()V", &[])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl VntCallback for CallBack {
|
||||
fn success(&self) {
|
||||
if let Err(e) = self.success0() {
|
||||
log::warn!("success {:?}", e);
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
fn create_tun(&self, info: DeviceInfo) {
|
||||
if let Err(e) = self.create_tun0(info) {
|
||||
log::warn!("create_tun {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect(&self, info: ConnectInfo) {
|
||||
if let Err(e) = self.connect0(info) {
|
||||
log::warn!("connect {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn handshake(&self, info: HandshakeInfo) -> bool {
|
||||
self.handshake0(info).unwrap_or_else(|e| {
|
||||
log::warn!("handshake {:?}", e);
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
fn register(&self, info: RegisterInfo) -> bool {
|
||||
self.register0(info).unwrap_or_else(|e| {
|
||||
log::warn!("register {:?}", e);
|
||||
false
|
||||
})
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
fn generate_tun(&self, info: DeviceConfig) -> u32 {
|
||||
self.generate_tun0(info).unwrap_or_else(|e| {
|
||||
log::warn!("generate_tun {:?}", e);
|
||||
0
|
||||
})
|
||||
}
|
||||
|
||||
fn peer_client_list(&self, info: Vec<PeerClientInfo>) {
|
||||
if let Err(e) = self.peer_client_list0(info) {
|
||||
log::warn!("peer_client_list {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn error(&self, info: ErrorInfo) {
|
||||
if let Err(e) = self.error0(info) {
|
||||
log::warn!("error {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn stop(&self) {
|
||||
if let Err(e) = self.stop0() {
|
||||
log::warn!("stop {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use jni::errors::Error;
|
||||
use jni::objects::JObject;
|
||||
use jni::JNIEnv;
|
||||
|
||||
use vnt::channel::punch::PunchModel;
|
||||
use vnt::channel::UseChannelType;
|
||||
use vnt::cipher::CipherModel;
|
||||
use vnt::compression::Compressor;
|
||||
use vnt::core::Config;
|
||||
|
||||
use crate::utils::*;
|
||||
|
||||
pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let tap = env.get_field(&config, "tap", "Z")?.z()?;
|
||||
let token = to_string_not_null(env, &config, "token")?;
|
||||
let name = to_string_not_null(env, &config, "name")?;
|
||||
let device_id = to_string_not_null(env, &config, "deviceId")?;
|
||||
let password = to_string(env, &config, "password")?;
|
||||
let server_address_str = to_string_not_null(env, &config, "server")?;
|
||||
let stun_server = to_string_array_not_null(env, &config, "stunServer")?;
|
||||
let dns = to_string_array(env, &config, "dns")?.unwrap_or_else(|| vec![]);
|
||||
let port_mapping = to_string_array(env, &config, "portMapping")?.unwrap_or_else(|| vec![]);
|
||||
let cipher_model = to_string_not_null(env, &config, "cipherModel")?;
|
||||
let punch_model = to_string(env, &config, "punchModel")?;
|
||||
let mtu = to_integer(env, &config, "mtu")?.map(|v| v as u32);
|
||||
let tcp = env.get_field(&config, "tcp", "Z")?.z()?;
|
||||
let server_encrypt = env.get_field(&config, "serverEncrypt", "Z")?.z()?;
|
||||
let use_channel = to_string(env, &config, "useChannel")?;
|
||||
let finger = env.get_field(&config, "finger", "Z")?.z()?;
|
||||
let first_latency = env.get_field(&config, "firstLatency", "Z")?.z()?;
|
||||
let packet_delay = to_integer(env, &config, "packetDelay")?
|
||||
.map(|v| v as u32)
|
||||
.unwrap_or_default();
|
||||
let packet_loss_rate = to_double(env, &config, "packetLossRate")?;
|
||||
|
||||
let in_ips = to_string_array(env, &config, "inIps")?;
|
||||
let out_ips = to_string_array(env, &config, "outIps")?;
|
||||
let ports =
|
||||
to_i32_array(env, &config, "ports")?.map(|v| v.into_iter().map(|v| v as u16).collect());
|
||||
let ip = if let Some(ip) = to_string(env, &config, "ip")? {
|
||||
match ip.parse() {
|
||||
Ok(ip) => Some(ip),
|
||||
Err(e) => {
|
||||
env.throw_new(
|
||||
"java/lang/RuntimeException",
|
||||
format!("ip {} err: {}", ip, e),
|
||||
)
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let in_ips = if let Some(in_ips) = in_ips {
|
||||
match common::args_parse::ips_parse(&in_ips) {
|
||||
Ok(in_ips) => in_ips,
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("in_ips {}", e))
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let out_ips = if let Some(out_ips) = out_ips {
|
||||
match common::args_parse::out_ips_parse(&out_ips) {
|
||||
Ok(out_ips) => out_ips,
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("out_ips {}", e))
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let cipher_model = match CipherModel::from_str(&cipher_model) {
|
||||
Ok(cipher_model) => cipher_model,
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("cipher_model {}", e))
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
};
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let device_name = to_string(env, &config, "deviceName")?;
|
||||
let config = match Config::new(
|
||||
#[cfg(target_os = "windows")]
|
||||
tap,
|
||||
token,
|
||||
device_id,
|
||||
name,
|
||||
server_address_str,
|
||||
dns,
|
||||
stun_server,
|
||||
in_ips,
|
||||
out_ips,
|
||||
password,
|
||||
mtu,
|
||||
tcp,
|
||||
ip,
|
||||
false,
|
||||
server_encrypt,
|
||||
1,
|
||||
cipher_model,
|
||||
finger,
|
||||
PunchModel::from_str(&punch_model.unwrap_or_default()).unwrap_or_default(),
|
||||
ports,
|
||||
first_latency,
|
||||
#[cfg(not(target_os = "android"))]
|
||||
device_name,
|
||||
UseChannelType::from_str(&use_channel.unwrap_or_default()).unwrap_or_default(),
|
||||
packet_loss_rate,
|
||||
packet_delay,
|
||||
port_mapping,
|
||||
Compressor::None,
|
||||
) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
env.throw_new(
|
||||
"java/lang/RuntimeException",
|
||||
format!("vnt start error {:?}", e),
|
||||
)
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
};
|
||||
Ok(config)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
pub mod callback;
|
||||
pub mod config;
|
||||
pub mod utils;
|
||||
pub mod vnt;
|
||||
pub(crate) mod vnt_logger;
|
||||
@@ -1,131 +0,0 @@
|
||||
use jni::errors::Error;
|
||||
use jni::objects::{JIntArray, JObject, JObjectArray, JString};
|
||||
use jni::JNIEnv;
|
||||
|
||||
pub fn to_string_not_null(
|
||||
env: &mut JNIEnv,
|
||||
config: &JObject,
|
||||
name: &'static str,
|
||||
) -> Result<String, Error> {
|
||||
let value = env.get_field(config, name, "Ljava/lang/String;")?.l()?;
|
||||
if value.is_null() {
|
||||
env.throw_new("java/lang/NullPointerException", name)
|
||||
.expect("throw");
|
||||
return Err(Error::NullPtr(name));
|
||||
}
|
||||
let binding = JString::from(value);
|
||||
let value = env.get_string(binding.as_ref())?;
|
||||
match value.to_str() {
|
||||
Ok(value) => Ok(value.to_string()),
|
||||
Err(_) => {
|
||||
env.throw_new("java/lang/RuntimeException", "not utf-8")
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(env: &mut JNIEnv, config: &JObject, name: &str) -> Result<Option<String>, Error> {
|
||||
let value = env.get_field(config, name, "Ljava/lang/String;")?.l()?;
|
||||
if value.is_null() {
|
||||
return Ok(None);
|
||||
}
|
||||
let tmp = JString::from(value);
|
||||
let value = env.get_string(tmp.as_ref())?;
|
||||
match value.to_str() {
|
||||
Ok(value) => Ok(Some(value.to_string())),
|
||||
Err(_) => {
|
||||
env.throw_new("java/lang/RuntimeException", "not utf-8")
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string_array_not_null(
|
||||
env: &mut JNIEnv,
|
||||
config: &JObject,
|
||||
name: &str,
|
||||
) -> Result<Vec<String>, Error> {
|
||||
match to_string_array(env, config, name)? {
|
||||
None => {
|
||||
env.throw_new("java/lang/NullPointerException", name)
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
Some(rs) => Ok(rs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string_array(
|
||||
env: &mut JNIEnv,
|
||||
config: &JObject,
|
||||
name: &str,
|
||||
) -> Result<Option<Vec<String>>, Error> {
|
||||
let value = env.get_field(config, name, "[Ljava/lang/String;")?.l()?;
|
||||
if value.is_null() {
|
||||
return Ok(None);
|
||||
}
|
||||
let arr = JObjectArray::from(value);
|
||||
let len = env.get_array_length(&arr)?;
|
||||
let mut rs = Vec::with_capacity(len as usize);
|
||||
for index in 0..len {
|
||||
let object = env.get_object_array_element(&arr, index)?;
|
||||
if object.is_null() {
|
||||
env.throw_new(
|
||||
"java/lang/NullPointerException",
|
||||
format!("{},index={}", name, index),
|
||||
)
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
match env.get_string(JString::from(object).as_ref())?.to_str() {
|
||||
Ok(value) => {
|
||||
rs.push(value.to_string());
|
||||
}
|
||||
Err(_) => {
|
||||
env.throw_new("java/lang/RuntimeException", "not utf-8")
|
||||
.expect("throw");
|
||||
return Err(Error::JavaException);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Some(rs))
|
||||
}
|
||||
|
||||
pub fn to_i32_array(
|
||||
env: &mut JNIEnv,
|
||||
config: &JObject,
|
||||
name: &str,
|
||||
) -> Result<Option<Vec<i32>>, Error> {
|
||||
let obj = env.get_field(&config, name, "[I")?.l()?;
|
||||
if obj.is_null() {
|
||||
Ok(None)
|
||||
} else {
|
||||
let j_arr = JIntArray::from(obj);
|
||||
let len = env.get_array_length(&j_arr)?;
|
||||
let mut arr = vec![0i32; len as usize];
|
||||
env.get_int_array_region(j_arr, 0, &mut arr)?;
|
||||
Ok(Some(arr))
|
||||
}
|
||||
}
|
||||
pub fn to_integer(env: &mut JNIEnv, config: &JObject, name: &str) -> Result<Option<i32>, Error> {
|
||||
let value = env.get_field(config, name, "Ljava/lang/Integer;")?.l()?;
|
||||
if value.is_null() {
|
||||
return Ok(None);
|
||||
}
|
||||
// 调用 intValue
|
||||
return Ok(Some(
|
||||
env.call_method(value, "intValue", "()I", &[])?.i()? as _
|
||||
));
|
||||
}
|
||||
pub fn to_double(env: &mut JNIEnv, config: &JObject, name: &str) -> Result<Option<f64>, Error> {
|
||||
let value = env.get_field(config, name, "Ljava/lang/Double;")?.l()?;
|
||||
if value.is_null() {
|
||||
return Ok(None);
|
||||
}
|
||||
// 调用 intValue
|
||||
return Ok(Some(
|
||||
env.call_method(value, "doubleValue", "()D", &[])?.d()? as _,
|
||||
));
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
use std::ptr;
|
||||
use std::time::Duration;
|
||||
|
||||
use jni::errors::Error;
|
||||
use jni::objects::{JClass, JObject, JValue};
|
||||
use jni::sys::{jboolean, jint, jlong, jobject, jobjectArray, jsize};
|
||||
use jni::JNIEnv;
|
||||
|
||||
use vnt::channel::Route;
|
||||
use vnt::core::Vnt;
|
||||
use vnt::handle::PeerDeviceInfo;
|
||||
|
||||
use crate::callback::CallBack;
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_new0(
|
||||
mut env: JNIEnv<'static>,
|
||||
_class: JClass,
|
||||
config: JObject,
|
||||
call_back: JObject<'static>,
|
||||
) -> jlong {
|
||||
crate::vnt_logger::init_log();
|
||||
let jvm = if let Ok(jvm) = env.get_java_vm() {
|
||||
jvm
|
||||
} else {
|
||||
return 0;
|
||||
};
|
||||
match crate::config::new_config(&mut env, config) {
|
||||
Ok(config) => {
|
||||
let call_back = if let Ok(call_back) = env.new_global_ref(call_back) {
|
||||
call_back
|
||||
} else {
|
||||
return 0;
|
||||
};
|
||||
let call_back = match CallBack::new(jvm, call_back) {
|
||||
Ok(call_back) => call_back,
|
||||
Err(_) => {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
let vnt_util = match Vnt::new(config, call_back) {
|
||||
Ok(vnt_util) => vnt_util,
|
||||
Err(e) => {
|
||||
env.throw_new(
|
||||
"java/lang/RuntimeException",
|
||||
format!("vnt start error {}", e),
|
||||
)
|
||||
.expect("throw");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
let ptr = Box::into_raw(Box::new(vnt_util));
|
||||
return ptr as jlong;
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_stop0(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
raw_vnt: jlong,
|
||||
) {
|
||||
let vnt = raw_vnt as *mut Vnt;
|
||||
let _ = (&*vnt).stop();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_wait0(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
raw_vnt: jlong,
|
||||
) {
|
||||
let vnt = raw_vnt as *mut Vnt;
|
||||
let _ = (&*vnt).wait();
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_waitTimeout0(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
raw_vnt: jlong,
|
||||
time: jlong,
|
||||
) -> jboolean {
|
||||
let vnt = raw_vnt as *mut Vnt;
|
||||
(&*vnt).wait_timeout(Duration::from_millis(time as _)) as _
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_drop0(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
raw_vnt: jlong,
|
||||
) {
|
||||
let vnt = raw_vnt as *mut Vnt;
|
||||
let _ = Box::from_raw(vnt).stop();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_list0(
|
||||
mut env: JNIEnv,
|
||||
_class: JClass,
|
||||
raw_vnt: jlong,
|
||||
) -> jobjectArray {
|
||||
let vnt = raw_vnt as *mut Vnt;
|
||||
let vnt = &mut *vnt;
|
||||
let list = vnt.device_list();
|
||||
|
||||
let arr = match env.new_object_array(
|
||||
list.len() as jsize,
|
||||
"top/wherewego/vnt/jni/PeerRouteInfo",
|
||||
JObject::null(),
|
||||
) {
|
||||
Ok(arr) => arr,
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("error:{:?}", e))
|
||||
.expect("throw");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
};
|
||||
for (index, peer) in list.into_iter().enumerate() {
|
||||
let route = if let Some(route) = vnt.route(&peer.virtual_ip) {
|
||||
match route_parse(&mut env, route) {
|
||||
Ok(route) => JObject::from_raw(route),
|
||||
Err(_) => JObject::null(),
|
||||
}
|
||||
} else {
|
||||
JObject::null()
|
||||
};
|
||||
match peer_device_info_parse(&mut env, peer, route) {
|
||||
Ok(peer) => {
|
||||
match env.set_object_array_element(&arr, index as jsize, JObject::from_raw(peer)) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("error:{:?}", e))
|
||||
.expect("throw");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
env.throw_new("java/lang/RuntimeException", format!("error:{:?}", e))
|
||||
.expect("throw");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
}
|
||||
}
|
||||
arr.as_raw()
|
||||
}
|
||||
|
||||
fn route_parse(env: &mut JNIEnv, route: Route) -> Result<jobject, Error> {
|
||||
let rs = env.new_object(
|
||||
"top/wherewego/vnt/jni/Route",
|
||||
"(ZLjava/lang/String;BI)V",
|
||||
&[
|
||||
JValue::Bool(route.is_tcp as _),
|
||||
JValue::Object(&env.new_string(route.addr.to_string())?.into()),
|
||||
JValue::Byte(route.metric as _),
|
||||
JValue::Int(route.rt as _),
|
||||
],
|
||||
)?;
|
||||
Ok(rs.as_raw())
|
||||
}
|
||||
|
||||
fn peer_device_info_parse(
|
||||
env: &mut JNIEnv,
|
||||
peer: PeerDeviceInfo,
|
||||
route: JObject,
|
||||
) -> Result<jobject, Error> {
|
||||
let virtual_ip = u32::from(peer.virtual_ip);
|
||||
let name = peer.name.to_string();
|
||||
let status = format!("{:?}", peer.status);
|
||||
let rs = env.new_object(
|
||||
"top/wherewego/vnt/jni/PeerRouteInfo",
|
||||
"(ILjava/lang/String;Ljava/lang/String;Ltop/wherewego/vnt/jni/Route;)V",
|
||||
&[
|
||||
JValue::Int(virtual_ip as jint),
|
||||
JValue::Object(&env.new_string(name)?.into()),
|
||||
JValue::Object(&env.new_string(status)?.into()),
|
||||
JValue::Object(&route),
|
||||
],
|
||||
)?;
|
||||
Ok(rs.as_raw())
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn init_log() {
|
||||
use android_logger::Config;
|
||||
use log::LevelFilter;
|
||||
android_logger::init_once(
|
||||
Config::default()
|
||||
.with_max_level(LevelFilter::Info) // limit log level
|
||||
.with_tag("vnt_jni"), // logs will show under mytag tag
|
||||
);
|
||||
}
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub fn init_log() {}
|
||||
Reference in New Issue
Block a user