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| { },
79 |_size: usize, _peer: std::net::SocketAddr| { },
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}