Commit 35e56afa authored by ankitgusai's avatar ankitgusai
Browse files

Proxy close method draft 1

parent 64969bc3
......@@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.example">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
......
......@@ -4,6 +4,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
......@@ -19,18 +20,26 @@ import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyClass.initLogging();
Thread t = new Thread(() -> MyClass.runProxy(getCacheDir().getAbsolutePath()));
MyClass myClass = new MyClass();
myClass.initLogging();
Thread t = new Thread(() -> myClass.runProxy(getCacheDir().getAbsolutePath()));
t.start();
final TextView text = (TextView) this.findViewById(R.id.textField);
Handler handler = new Handler(Looper.getMainLooper());
Thread t2 = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String hostname = "localhost";
int port = 9150;
Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(hostname, port));
......@@ -67,6 +76,8 @@ public class MainActivity extends AppCompatActivity {
e.printStackTrace();
}
});
t2.start();
t2.start();
findViewById(R.id.button).setOnClickListener(v -> myClass.closeProxy(myClass.exitPointer));
}
}
\ No newline at end of file
package net.example;
class MyClass {
static native String runProxy(final String storage);
static native String myMethod(final String target, final String storage);
static native void initLogging();
long exitPointer = 0;
native String runProxy(final String storage);
native void closeProxy(long exitPointer);
native String myMethod(final String target, final String storage);
native void initLogging();
static {
System.loadLibrary("arti_mobile");
}
......
......@@ -16,4 +16,15 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textField"
app:layout_constraintVertical_bias="0.100000024" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -8,23 +8,42 @@ use crate::run_arti_proxy;
// use std::sync::Once;
// use tracing_subscriber::fmt::Subscriber;
// use tracing_subscriber::prelude::*;
use jni::objects::{JClass, JString};
use android_logger::Config;
use jni::objects::{JClass, JObject, JString};
use jni::sys::jstring;
use jni::JNIEnv;
use log::Level;
use android_logger::Config;
pub const HOLDER_FIELD_NAME: &str = "exitPointer";
use futures::channel::oneshot;
use futures::channel::oneshot::Receiver;
use futures::channel::oneshot::Sender;
use std::ops::Deref;
#[no_mangle]
pub extern "C" fn Java_net_example_MyClass_runProxy(
env: JNIEnv,
_: JClass,
object: JObject,
cache_dir: JString,
) -> jstring {
debug!("starting proxy...");
let (sender, receiver) = oneshot::channel::<>();
//save sender reference in JAVA, so in exit call we can retrive it and trigger receiver
let _ = match env.set_rust_field(object, HOLDER_FIELD_NAME, sender) {
Ok(()) => {
println!("set_rust_field success");
}
Err(error) => {
println!("Error set_rust_field");
}
};
let result = match run_arti_proxy(
&env.get_string(cache_dir)
.expect("cache_dir is invalid")
.to_string_lossy(),
receiver,
) {
Ok(_res) => ("Proxy stopped. Good bye.".to_string()),
Err(e) => format!("Error: {}", e),
......@@ -38,21 +57,55 @@ pub extern "C" fn Java_net_example_MyClass_runProxy(
}
#[no_mangle]
pub extern "C" fn Java_net_example_MyClass_initLogging(
_env: JNIEnv,
_: JClass) {
pub extern "C" fn Java_net_example_MyClass_initLogging(_env: JNIEnv, _: JObject) {
android_logger::init_once(
Config::default()
.with_min_level(Level::Trace)
.with_tag("arti-core"));
.with_min_level(Level::Trace)
.with_tag("arti-core"),
);
// Set panic hook
std::panic::set_hook(Box::new(|msg| {
log::error!("arti-core: {:?}", msg);
}));
debug!("logger initialized");
}
#[no_mangle]
pub extern "C" fn Java_net_example_MyClass_closeProxy(
env: JNIEnv,
object: JObject,
cache_dir: JString,
) {
debug!("closing proxy...");
//Retriving sender to trigger close
match env.take_rust_field::<JObject, &str, Sender<i32>>(object, HOLDER_FIELD_NAME) {
Ok(sender) => {
debug!("is cancelled {}", sender.is_canceled());
match sender.send(()) {
Ok(()) => {
debug!("send OK");
}
Err(error) => {
debug!("send FAILED");
debug!("{:?}", error);
}
}
},
Err(error) => debug!("take_rust_field error {:?}", error),
}
//let sender: std::sync::MutexGuard<i32> = get_holder(&env, &class);
//sender.deref().send()
}
/// Create a static method myMethod on class net.example.MyClass
#[no_mangle]
pub extern "C" fn Java_net_example_MyClass_myMethod(
env: JNIEnv,
_: JClass,
_: JObject,
target: JString,
cache_dir: JString,
) -> jstring {
......
#[macro_use] extern crate log;
#[macro_use]
extern crate log;
use anyhow::Ok;
use anyhow::{Context, Result};
use futures::{AsyncReadExt, AsyncWriteExt};
use arti_client::{config::TorClientConfigBuilder, TorClient, BootstrapBehavior::OnDemand};
use arti::{socks};
use tor_rtcompat::BlockOn;
use arti::socks;
use arti_client::{config::TorClientConfigBuilder, BootstrapBehavior::OnDemand, TorClient};
use futures::channel::oneshot::Receiver;
use futures::channel::oneshot::Sender;
use futures::FutureExt;
use tracing::{info};
use tor_rtcompat::BlockOn;
use tracing::info;
/// Shorthand for a boxed and pinned Future.
type PinnedFuture<T> = std::pin::Pin<Box<dyn futures::Future<Output = T>>>;
//fn create_exit_channel
fn run_arti(to: &str, cache: &str) -> Result<String> {
let runtime = tor_rtcompat::PreferredRuntime::create()?;
let rt_copy = runtime.clone();
......@@ -25,7 +30,8 @@ fn run_arti(to: &str, cache: &str) -> Result<String> {
rt_copy.block_on(async {
let client = TorClient::with_runtime(runtime)
.config(config)
.create_bootstrapped().await?;
.create_bootstrapped()
.await?;
let mut stream = client.connect((to, 80)).await?;
stream.write_all(b"GET / HTTP/1.1\r\nHost: ").await?;
......@@ -42,20 +48,22 @@ fn run_arti(to: &str, cache: &str) -> Result<String> {
})
}
fn run_arti_proxy(cache: &str) -> Result<(), anyhow::Error> {
fn run_arti_proxy(cache: &str, exit: Receiver<()>) -> Result<(), anyhow::Error> {
let runtime = tor_rtcompat::PreferredRuntime::create()?;
let config = TorClientConfigBuilder::from_directories(
format!("{}/arti-data", cache),
format!("{}/arti-cache", cache),
).build()?;
)
.build()?;
// Using OnDemand arranges that, while we are bootstrapping, incoming connections wait
// for bootstrap to complete, rather than getting errors.
let rt_copy = runtime.clone();
debug!("run_arti_proxy");
rt_copy.block_on(async {
let client_builder = TorClient::with_runtime(runtime.clone())
.config(config)
.bootstrap_behavior(OnDemand);
.config(config)
.bootstrap_behavior(OnDemand);
let client = client_builder.create_unbootstrapped()?;
......@@ -69,7 +77,6 @@ fn run_arti_proxy(cache: &str) -> Result<(), anyhow::Error> {
let proxy = futures::future::select_all(proxy).map(|(finished, _index, _others)| finished);
futures::select!(
r = proxy.fuse()
=> r.0.context(format!("{} proxy failure", r.1)),
r = async {
......@@ -78,6 +85,7 @@ fn run_arti_proxy(cache: &str) -> Result<(), anyhow::Error> {
futures::future::pending::<Result<()>>().await
}.fuse()
=> r.context("bootstrap"),
r = exit.fuse()=> Ok(()),
)
})
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment