rust_tunnel/
lib.rs

1use rand_core::RngCore;
2pub use {smol, smol::prelude::*};
3
4pub async fn gen_key() -> x25519_dalek::StaticSecret {
5    let mut key: [u8; 32] = [0u8; 32];
6    rand_core::OsRng.fill_bytes(&mut key);
7    let key: x25519_dalek::StaticSecret = x25519_dalek::StaticSecret::from(key);
8    return key;
9}
10
11#[async_recursion::async_recursion]
12pub async fn get_key() -> x25519_dalek::StaticSecret {
13    let home: String = dirs::home_dir()
14        .unwrap()
15        .into_os_string()
16        .into_string()
17        .unwrap();
18    let keyfile: String = home + "/tunnel-private.key";
19
20    let key: x25519_dalek::StaticSecret = match std::fs::read(&keyfile) {
21        Ok(v) => {
22            if v.len() != 32 {
23                std::fs::remove_file(&keyfile).unwrap();
24                return get_key().await;
25            }
26            let mut k: [u8; 32] = [0u8; 32];
27            for i in 0..32 {
28                k[i] = v[i];
29            }
30            x25519_dalek::StaticSecret::from(k)
31        }
32        Err(_) => {
33            let key: x25519_dalek::StaticSecret = gen_key().await;
34            let keyfile_value: [u8; 32] = key.to_bytes();
35            std::fs::write(&keyfile, keyfile_value).unwrap();
36            key
37        }
38    };
39    return key;
40}
41
42pub async fn client(
43    pk: x25519_dalek::PublicKey,
44    client: std::net::SocketAddr,
45    server: std::net::SocketAddr,
46) {
47    let tunnel_stats: std::sync::Arc<sosistab::StatsGatherer> =
48        std::sync::Arc::new(sosistab::StatsGatherer::new_active());
49    let tunnel_client: sosistab::ClientConfig =
50        sosistab::ClientConfig::new(sosistab::Protocol::DirectUdp, server, pk, tunnel_stats);
51
52    let tunnel_conn: sosistab::Session = tunnel_client.connect().await.unwrap();
53    let tunnel_conn: sosistab::Multiplex = tunnel_conn.multiplex();
54
55    let tcp_server: smol::net::TcpListener = smol::net::TcpListener::bind(client).await.unwrap();
56    let mut tcp_in = tcp_server.incoming();
57
58    loop {
59        let tcp_conn: smol::net::TcpStream = tcp_in.next().await.unwrap().unwrap();
60        let tunnel_conn: sosistab::RelConn = tunnel_conn.open_conn(None).await.unwrap();
61
62        smol::spawn(
63            smol::io::copy(tunnel_conn.clone(), tcp_conn.clone())
64                .race(smol::io::copy(tcp_conn, tunnel_conn)),
65        )
66        .detach();
67    }
68}
69
70pub async fn server(
71    sk: x25519_dalek::StaticSecret,
72    server: std::net::SocketAddr,
73    tunnel_to: std::net::SocketAddr,
74) {
75    let tunnel_server: sosistab::Listener = sosistab::Listener::listen_udp(
76        server,
77        sk,
78        |_size: usize, _peer: std::net::SocketAddr| { /* on receive */ },
79        |_size: usize, _peer: std::net::SocketAddr| { /* on send */ },
80    )
81    .await
82    .unwrap();
83
84    loop {
85        let tunnel_conn: sosistab::Session = tunnel_server.accept_session().await.unwrap();
86        let tunnel_conn: sosistab::Multiplex = tunnel_conn.multiplex();
87
88        smol::spawn(async move {
89            loop {
90                let tunnel_conn: sosistab::RelConn = tunnel_conn.accept_conn().await.unwrap();
91                let tcp_conn = smol::net::TcpStream::connect(tunnel_to).await.unwrap();
92
93                smol::spawn(
94                    smol::io::copy(tunnel_conn.clone(), tcp_conn.clone())
95                        .race(smol::io::copy(tcp_conn, tunnel_conn)),
96                )
97                .detach();
98            }
99        })
100        .detach();
101    }
102}
103
104pub async fn async_server(tunnel_server: &str, tunnel_to: &str) -> anyhow::Result<()> {
105    let listen = tunnel_server.parse::<std::net::SocketAddr>()?;
106    let to = tunnel_to.parse::<std::net::SocketAddr>()?;
107    let key = get_key().await;
108    let pubkey_bytes = x25519_dalek::PublicKey::from(&key).to_bytes();
109    let pubkey: String = {
110        let mut pk: String = String::new();
111        for i in 0..32 {
112            let it = pubkey_bytes[i];
113            let it: String = format!("{:02X}", it);
114            pk.extend(it.chars());
115        }
116        pk
117    };
118    println!("You public key is {}", pubkey);
119    server(key, listen, to).await;
120    Ok(())
121}
122
123pub async fn async_client(
124    tunnel_client: &str,
125    tunnel_server: &str,
126    pubkey: &str,
127) -> anyhow::Result<()> {
128    let listen = tunnel_client.parse::<std::net::SocketAddr>()?;
129    let server = tunnel_server.parse::<std::net::SocketAddr>()?;
130    let pk: [u8; 32] = {
131        let mut key: [u8; 32] = [0u8; 32];
132        let mut n: usize = 0;
133        for i in (0..(pubkey.len())).step_by(2) {
134            let it: &str = &pubkey[i..=i + 1];
135            let it: u8 = u8::from_str_radix(it, 16).unwrap();
136            key[n] = it;
137            n += 1;
138        }
139        key
140    };
141    client(x25519_dalek::PublicKey::from(pk), listen, server).await;
142    Ok(())
143}
144
145pub fn run_server(tunnel_server: &str, tunnel_to: &str) {
146    smol::block_on(async {
147        if let Err(e) = async_server(tunnel_server, tunnel_to).await {
148            eprintln!("{:?}", e);
149        }
150    });
151}
152
153pub fn run_client(tunnel_client: &str, tunnel_server: &str, pubkey: &str) {
154    smol::block_on(async {
155        if let Err(e) = async_client(tunnel_client, tunnel_server, pubkey).await {
156            eprintln!("{:?}", e);
157        }
158    });
159}