[mio] 适配新版vnt,增加jni java端代码

This commit is contained in:
lubeilin
2024-02-29 22:29:39 +08:00
parent ceadadee68
commit 8d7eb5ba1b
18 changed files with 1208 additions and 412 deletions
+185
View File
@@ -0,0 +1,185 @@
use std::sync::Arc;
use jni::objects::{GlobalRef, JString, JValue};
use jni::{JNIEnv, JavaVM};
use spki::der::pem::LineEnding;
use spki::EncodePublicKey;
use vnt::handle::callback::ConnectInfo;
use vnt::{DeviceInfo, ErrorInfo, HandshakeInfo, RegisterInfo, VntCallback};
#[derive(Clone)]
pub struct CallBack {
jvm: Arc<JavaVM>,
this: GlobalRef,
}
unsafe impl Send for CallBack {}
impl CallBack {
pub fn new(jvm: JavaVM, this: GlobalRef) -> Self {
Self {
jvm: Arc::new(jvm),
this,
}
}
}
impl CallBack {
fn create_tun0(&self, info: DeviceInfo) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let param = env.new_object(
"top/wherewego/vnt/jni/param/DeviceInfo",
"(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(&param)],
)?;
Ok(())
}
fn connect0(&self, info: ConnectInfo) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let param = env.new_object(
"top/wherewego/vnt/jni/param/ConnectInfo",
"(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(&param)],
)?;
Ok(())
}
fn handshake0(&self, info: HandshakeInfo) -> jni::errors::Result<bool> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
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 param = env.new_object(
"top/wherewego/vnt/jni/param/HandshakeInfo",
"(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(&param)],
)?;
rs.z()
}
fn register0(&self, info: RegisterInfo) -> jni::errors::Result<bool> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let param = env.new_object(
"top/wherewego/vnt/jni/param/RegisterInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
&[
JValue::Object(&env.new_string(info.virtual_ip.to_string())?.into()),
JValue::Object(&env.new_string(info.virtual_netmask.to_string())?.into()),
JValue::Object(&env.new_string(info.virtual_gateway.to_string())?.into()),
],
)?;
let rs = env.call_method(
&self.this,
"register",
"(Ltop/wherewego/vnt/jni/param/RegisterInfo;)Z",
&[JValue::Object(&param)],
)?;
rs.z()
}
fn error0(&self, info: ErrorInfo) -> jni::errors::Result<()> {
let code: u8 = info.code.into();
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let msg = if let Some(msg) = info.msg {
env.new_string(msg)?
} else {
JString::default()
};
let param = env.new_object(
"top/wherewego/vnt/jni/param/ErrorInfo",
"(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(&param)],
)?;
Ok(())
}
fn stop0(&self) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
env.call_method(&self.this, "error", "()V", &[])?;
Ok(())
}
}
impl VntCallback for CallBack {
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
})
}
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);
}
}
}
+145
View File
@@ -0,0 +1,145 @@
use std::net::ToSocketAddrs;
use std::str::FromStr;
use jni::errors::Error;
use jni::JNIEnv;
use jni::objects::JObject;
use vnt::channel::punch::PunchModel;
use vnt::cipher::CipherModel;
use vnt::core::Config;
use crate::utils::*;
pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
#[cfg(any(target_os = "windows", target_os = "linux"))]
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 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 relay = env.get_field(&config, "relay", "Z")?.z()?;
let finger = env.get_field(&config, "finger", "Z")?.z()?;
let first_latency = env.get_field(&config, "firstLatency", "Z")?.z()?;
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 server_address = match server_address_str.to_socket_addrs() {
Ok(mut rs) => {
if let Some(addr) = rs.next() {
addr
} else {
env.throw_new("java/lang/RuntimeException", "server address err")
.expect("throw");
return Err(Error::JavaException);
}
}
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("server address {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
};
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")?;
#[cfg(target_os = "android")]
let device_fd = env.get_field(&config, "deviceFd", "I")?.i()? as i32;
let config = match Config::new(
#[cfg(any(target_os = "windows", target_os = "linux"))]
tap,
token,
device_id,
name,
server_address,
server_address_str,
stun_server,
in_ips,
out_ips,
password,
mtu,
tcp,
ip,
relay,
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,
#[cfg(target_os = "android")]
device_fd,
) {
Ok(config) => config,
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt start error {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
};
Ok(config)
}
+3 -1
View File
@@ -1,2 +1,4 @@
pub mod callback;
pub mod config;
pub mod vnt;
pub mod vnt_util;
pub mod utils;
+115
View File
@@ -0,0 +1,115 @@
use jni::errors::Error;
use jni::JNIEnv;
use jni::objects::{JIntArray, JObject, JObjectArray, JString};
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 _))
}
+51 -25
View File
@@ -1,45 +1,71 @@
use std::ptr;
use jni::errors::Error;
use jni::objects::{JClass, JObject, JValue};
use jni::sys::{jboolean, jbyte, jint, jlong, jobject, jobjectArray, jsize};
use jni::sys::{jbyte, jint, jlong, jobject, jobjectArray, jsize};
use jni::JNIEnv;
use std::ptr;
use vnt::channel::Route;
use vnt::core::sync::VntSync;
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 {
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 vnt_util = match Vnt::new(config, CallBack::new(jvm, 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 VntSync;
let vnt = raw_vnt as *mut Vnt;
let _ = (&*vnt).stop();
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_waitStop0(
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 VntSync;
let _ = (&mut *vnt).wait_stop();
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_waitStopMs0(
_env: JNIEnv,
_class: JClass,
raw_vnt: jlong,
ms: jlong,
) -> jboolean {
let vnt = raw_vnt as *mut VntSync;
if (&mut *vnt).wait_stop_ms(ms as _) {
jni::sys::JNI_TRUE
} else {
jni::sys::JNI_FALSE
}
let vnt = raw_vnt as *mut Vnt;
let _ = (&*vnt).wait();
}
#[no_mangle]
@@ -48,7 +74,7 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_drop0(
_class: JClass,
raw_vnt: jlong,
) {
let vnt = raw_vnt as *mut VntSync;
let vnt = raw_vnt as *mut Vnt;
let _ = Box::from_raw(vnt).stop();
}
@@ -58,7 +84,7 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_list0(
_class: JClass,
raw_vnt: jlong,
) -> jobjectArray {
let vnt = raw_vnt as *mut VntSync;
let vnt = raw_vnt as *mut Vnt;
let vnt = &mut *vnt;
let list = vnt.device_list();
-386
View File
@@ -1,386 +0,0 @@
use std::net::ToSocketAddrs;
use std::ptr;
use std::str::FromStr;
use jni::errors::Error;
use jni::objects::{JClass, JObject, JString, JValue};
#[cfg(not(target_os = "android"))]
use jni::sys::jboolean;
use jni::sys::{jint, jlong, jobject};
use jni::JNIEnv;
use vnt::channel::punch::PunchModel;
use vnt::cipher::CipherModel;
use vnt::core::sync::VntUtilSync;
use vnt::core::Config;
use vnt::handle::registration_handler::{RegResponse, ReqEnum};
#[cfg(not(target_os = "android"))]
use vnt::tun_tap_device::DriverInfo;
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);
}
}
}
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);
}
}
}
fn new_sync(env: &mut JNIEnv, config: JObject) -> Result<VntUtilSync, Error> {
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_str = to_string_not_null(env, &config, "stunServer")?;
let cipher_model = to_string_not_null(env, &config, "cipherModel")?;
let tcp = env.get_field(&config, "tcp", "Z")?.z()?;
let finger = env.get_field(&config, "finger", "Z")?.z()?;
let first_latency = env.get_field(&config, "firstLatency", "Z")?.z()?;
let in_ips = to_string(env, &config, "inIps")?;
let out_ips = to_string(env, &config, "outIps")?;
let port = env.get_field(&config, "port", "I")?.i()? as u16;
let in_ips = if let Some(in_ips) = in_ips {
let in_ips: Vec<&str> = in_ips.split("\n").collect();
let in_ips = in_ips.iter().map(|v| v.to_string()).collect();
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 {
let out_ips: Vec<&str> = out_ips.split("\n").collect();
let out_ips = out_ips.iter().map(|v| v.to_string()).collect();
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 server_address = match server_address_str.to_socket_addrs() {
Ok(mut rs) => {
if let Some(addr) = rs.next() {
addr
} else {
env.throw_new("java/lang/RuntimeException", "server address err")
.expect("throw");
return Err(Error::JavaException);
}
}
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("server address {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
};
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);
}
};
let mut stun_server = Vec::new();
for addr in stun_server_str.split(",") {
stun_server.push(addr.trim().to_string());
}
let config = match Config::new(
false,
token,
device_id,
name,
server_address,
server_address_str,
stun_server,
in_ips,
out_ips,
password,
false,
None,
tcp,
None,
false,
false,
false,
1,
cipher_model,
finger,
PunchModel::All,
port,
first_latency,
) {
Ok(config) => config,
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt start error {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
};
match VntUtilSync::new(config) {
Ok(vnt_util) => Ok(vnt_util),
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt start error {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_VntUtil_new0(
mut env: JNIEnv,
_class: JClass,
config: JObject,
) -> jlong {
match new_sync(&mut env, config) {
Ok(vnt_util) => {
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_VntUtil_connect0(
mut env: JNIEnv,
_class: JClass,
raw_vnt_util: jlong,
) {
let raw_vnt_util = raw_vnt_util as *mut VntUtilSync;
match (&mut *raw_vnt_util).connect() {
Ok(_) => {}
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt connect error {}", e),
)
.expect("throw");
}
}
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_VntUtil_register0(
mut env: JNIEnv,
_class: JClass,
raw_vnt_util: jlong,
) -> jobject {
let raw_vnt_util = raw_vnt_util as *mut VntUtilSync;
match (&mut *raw_vnt_util).register() {
Ok(response) => match reg_response(&mut env, response) {
Ok(res) => {
return res;
}
Err(e) => {
env.throw(format!("vnt register error {}", e))
.expect("throw");
}
},
Err(e) => match e {
ReqEnum::TokenError => {
env.throw_new(
"top/wherewego/vnt/jni/exception/TokenErrorException",
"TokenError",
)
.expect("throw");
}
ReqEnum::AddressExhausted => {
env.throw_new(
"top/wherewego/vnt/jni/exception/AddressExhaustedException",
"AddressExhausted",
)
.expect("throw");
}
ReqEnum::Timeout => {
env.throw_new(
"top/wherewego/vnt/jni/exception/TimeoutException",
"Timeout",
)
.expect("throw");
}
ReqEnum::ServerError(str) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt register error {}", str),
)
.expect("throw");
}
ReqEnum::Other(str) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt register error {}", str),
)
.expect("throw");
}
ReqEnum::IpAlreadyExists => {
env.throw_new(
"top/wherewego/vnt/jni/exception/IpAlreadyExistsException",
"IpAlreadyExists",
)
.expect("throw");
}
ReqEnum::InvalidIp => {
env.throw_new(
"top/wherewego/vnt/jni/exception/InvalidIpException",
"InvalidIp",
)
.expect("throw");
}
},
}
return ptr::null_mut();
}
#[cfg(target_os = "android")]
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_VntUtil_createIface0(
_env: JNIEnv,
_class: JClass,
raw_vnt_util: jlong,
fd: jint,
) {
let raw_vnt_util = raw_vnt_util as *mut VntUtilSync;
(&mut *raw_vnt_util).create_iface(fd as i32);
}
#[cfg(not(target_os = "android"))]
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_VntUtil_createIface0(
mut env: JNIEnv,
_class: JClass,
raw_vnt_util: jlong,
) -> jobject {
let raw_vnt_util = raw_vnt_util as *mut VntUtilSync;
let rs = (&mut *raw_vnt_util).create_iface();
match rs {
Ok(driver_info) => match driver_info_e(&mut env, driver_info) {
Ok(res) => {
return res;
}
Err(e) => {
env.throw(format!("vnt create iface error {}", e))
.expect("throw");
}
},
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt create iface error {}", e),
)
.expect("throw");
}
}
return ptr::null_mut();
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_VntUtil_build0(
mut env: JNIEnv,
_class: JClass,
raw_vnt_util: jlong,
) -> jlong {
let raw_vnt_util = Box::from_raw(raw_vnt_util as *mut VntUtilSync);
match raw_vnt_util.build() {
Ok(rs) => {
return Box::into_raw(Box::new(rs)) as jlong;
}
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("vnt start error:{:?}", e),
)
.expect("throw");
}
}
return 0;
}
fn reg_response(env: &mut JNIEnv, response: RegResponse) -> Result<jobject, Error> {
let virtual_ip = u32::from(response.virtual_ip);
let virtual_gateway = u32::from(response.virtual_gateway);
let virtual_netmask = u32::from(response.virtual_netmask);
let response = env.new_object(
"top/wherewego/vnt/jni/RegResponse",
"(III)V",
&[
JValue::Int(virtual_ip as jint),
JValue::Int(virtual_gateway as jint),
JValue::Int(virtual_netmask as jint),
],
)?;
Ok(response.into_raw())
}
#[cfg(not(target_os = "android"))]
fn driver_info_e(env: &mut JNIEnv, driver_info: DriverInfo) -> Result<jobject, Error> {
let is_tun = driver_info.device_type.is_tun();
let name = driver_info.name;
let version = driver_info.version;
let mac = driver_info.mac.unwrap_or(String::new());
let response = env.new_object(
"top/wherewego/vnt/jni/DriverInfo",
"(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
&[
JValue::Bool(is_tun as jboolean),
JValue::Object(&env.new_string(name)?.into()),
JValue::Object(&env.new_string(version)?.into()),
JValue::Object(&env.new_string(mac)?.into()),
],
)?;
Ok(response.into_raw())
}