initial commit
This commit is contained in:
commit
7cd56bbc3a
3 changed files with 104 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "uredir"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[[bin]]
|
||||
name = "uredir"
|
||||
path = "uredir.rs"
|
||||
93
uredir.rs
Normal file
93
uredir.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
env,
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
|
||||
str::FromStr,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub struct URedir {
|
||||
true_server: IpAddr,
|
||||
port: u16,
|
||||
|
||||
clients: UdpSocket,
|
||||
table: HashMap<SocketAddr, UdpSocket>,
|
||||
buf: Vec<u8>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args().skip(1);
|
||||
println!("uredir by TudbuT: uredir [true server] [port] [mtu]");
|
||||
let true_server: String = args.next().unwrap();
|
||||
let true_server = IpAddr::from_str(&true_server).unwrap();
|
||||
let port: u16 = args.next().unwrap().parse().unwrap();
|
||||
let mtu: usize = args.next().unwrap().parse().unwrap();
|
||||
|
||||
println!("Start!");
|
||||
URedir::run_server(true_server, port, mtu);
|
||||
}
|
||||
|
||||
impl URedir {
|
||||
pub fn run_server(true_server: IpAddr, port: u16, mtu: usize) -> ! {
|
||||
let clients = UdpSocket::bind(("0.0.0.0", port)).unwrap();
|
||||
clients.set_nonblocking(true).unwrap();
|
||||
|
||||
let mut server = URedir {
|
||||
true_server,
|
||||
port,
|
||||
clients,
|
||||
table: HashMap::new(),
|
||||
buf: vec![0u8; mtu],
|
||||
};
|
||||
|
||||
loop {
|
||||
let did_something = server.read_from_clients() || server.read_from_server();
|
||||
|
||||
if !did_something {
|
||||
thread::sleep(Duration::from_millis(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_from_clients(&mut self) -> bool {
|
||||
if let Ok((packet_length, origin)) = self.clients.recv_from(&mut self.buf) {
|
||||
let connection = match self.table.get(&origin) {
|
||||
Some(it) => it,
|
||||
None => {
|
||||
println!("Got a new connection from {origin}.");
|
||||
self.create_server_connection(origin);
|
||||
println!("Connection setup complete");
|
||||
self.table.get(&origin).unwrap()
|
||||
}
|
||||
};
|
||||
let _ = connection.send(&self.buf[..packet_length]);
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn read_from_server(&mut self) -> bool {
|
||||
for (client_addr, server_conn) in &self.table {
|
||||
if let Ok((packet_length, origin)) = server_conn.recv_from(&mut self.buf) {
|
||||
if origin.ip() != self.true_server {
|
||||
continue;
|
||||
}
|
||||
let _ = self
|
||||
.clients
|
||||
.send_to(&self.buf[..packet_length], client_addr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn create_server_connection(&mut self, origin: SocketAddr) {
|
||||
let it = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0)).unwrap();
|
||||
it.connect((self.true_server, self.port)).unwrap();
|
||||
it.set_nonblocking(true).unwrap();
|
||||
self.table.insert(origin, it);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue