45 lines
1.2 KiB
Rust
45 lines
1.2 KiB
Rust
use std::collections::HashMap;
|
|
use std::net::SocketAddr;
|
|
use tokio::io::copy;
|
|
use tokio::net::{TcpListener, TcpStream};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
let filename = std::env::args()
|
|
.next()
|
|
.unwrap_or_else(|| "config.toml".to_string());
|
|
|
|
let contents = std::fs::read_to_string(filename)?;
|
|
|
|
let mut ports: HashMap<u16, SocketAddr> = toml::from_str(&contents)?;
|
|
|
|
let listener = TcpListener::bind("0.0.0.0:8000").await?;
|
|
|
|
loop {
|
|
let (stream, addr) = listener.accept().await?;
|
|
let to_addr = match ports.get(&addr.port()) {
|
|
Some(v) => *v,
|
|
None => continue,
|
|
};
|
|
let to_stream = TcpStream::connect(to_addr).await?; // TODO: remove this placeholder
|
|
|
|
tokio::spawn(async move {
|
|
proxy(stream, to_stream).await?;
|
|
|
|
Ok::<(), anyhow::Error>(())
|
|
});
|
|
}
|
|
}
|
|
|
|
async fn proxy(left: TcpStream, right: TcpStream) -> anyhow::Result<()> {
|
|
let (mut left_read, mut left_write) = left.into_split();
|
|
let (mut right_read, mut right_write) = right.into_split();
|
|
|
|
tokio::select! {
|
|
r = copy(&mut left_read, &mut right_write) => r?,
|
|
r = copy(&mut right_read, &mut left_write) => r?
|
|
};
|
|
|
|
Ok(())
|
|
}
|