188 lines
5.8 KiB
Rust
188 lines
5.8 KiB
Rust
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(¶m)],
|
|
)?;
|
|
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(¶m)],
|
|
)?;
|
|
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(¶m)],
|
|
)?;
|
|
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(¶m)],
|
|
)?;
|
|
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(¶m)],
|
|
)?;
|
|
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 success(&self) {
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|