Adding config file locations and yaml support

This commit is contained in:
Fabian Stamm 2022-03-21 11:12:59 +01:00
parent 54992ab5cb
commit bfd0189610
5 changed files with 118 additions and 9 deletions

59
Cargo.lock generated
View File

@ -2,6 +2,12 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -109,6 +115,12 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -118,6 +130,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "indexmap"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.1" version = "1.0.1"
@ -130,6 +152,12 @@ version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.6" version = "0.4.6"
@ -266,11 +294,13 @@ dependencies = [
[[package]] [[package]]
name = "rustocat" name = "rustocat"
version = "0.0.2" version = "0.0.3"
dependencies = [ dependencies = [
"futures", "futures",
"serde", "serde",
"serde_json", "serde_json",
"serde_yaml",
"simple-error",
"tokio", "tokio",
] ]
@ -317,6 +347,18 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_yaml"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0"
dependencies = [
"indexmap",
"ryu",
"serde",
"yaml-rust",
]
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.0" version = "1.4.0"
@ -326,6 +368,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "simple-error"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc47a29ce97772ca5c927f75bac34866b16d64e07f330c3248e2d7226623901b"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.5" version = "0.4.5"
@ -466,3 +514,12 @@ name = "windows_x86_64_msvc"
version = "0.32.0" version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "rustocat" name = "rustocat"
version = "0.0.2" version = "0.0.3"
edition = "2021" edition = "2021"
description = "Socat in rust with many less features and a configuration file" description = "Socat in rust with many less features and a configuration file"
license = "ISC" license = "ISC"
@ -12,7 +12,8 @@ tokio = { version = "1.17.0", features = ["full"] }
futures = "0.3.21" futures = "0.3.21"
serde = { version = "1.0.136", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79" serde_json = "1.0.79"
serde_yaml = "0.8.23"
simple-error = "0.2.3"
[profile.release] [profile.release]
opt-level = 'z' # Optimize for size. opt-level = 'z' # Optimize for size.

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# Rustocat
Rustocat is a simple socat alternative with way less features, but it has a config file.
## Config File
Configs can be either yaml or json and can be located in /etc/rustocat.{yaml|json} or ind the current working directory as config.{yaml|json}.
```yaml
tcp:
- source: 0.0.0.0:2222
target: 127.0.0.1:22
```
Currently only TCP is supported, UDP/Unix Socket support might be added later.

View File

@ -3,6 +3,8 @@ mod shutdown;
mod tcp; mod tcp;
use serde::Deserialize; use serde::Deserialize;
use simple_error::bail;
use std::error::Error;
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use tokio::sync::broadcast; use tokio::sync::broadcast;
@ -19,14 +21,48 @@ struct Config {
// udp: Vec<Target>, // udp: Vec<Target>,
} }
fn load_yaml(path: &Path) -> Result<Config, Box<dyn Error>> {
let file = File::open(path)?;
let config: Config = serde_yaml::from_reader(file).expect("Failed to parse!"); //TODO: Print path
return Ok(config);
}
fn load_json(path: &Path) -> Result<Config, Box<dyn Error>> {
let file = File::open(path)?;
let config: Config = serde_json::from_reader(file).expect("Failed to parse!"); //TODO: Print path
return Ok(config);
}
fn load_config() -> Result<Config, Box<dyn Error>> {
for path in [
"config.yaml",
"config.json",
"/etc/rustocat.yaml",
"/etc/rustocat.json",
]
.iter()
{
// if(p)
let config = if path.ends_with(".yaml") {
load_yaml(Path::new(path))
} else {
load_json(Path::new(path))
};
if config.is_ok() {
return config;
}
}
bail!("No config file found");
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let json_file_path = Path::new("./config.json"); let config = load_config().expect("config not found");
let file = File::open(json_file_path).expect("file not found");
let (notify_shutdown, _) = broadcast::channel(1); let (notify_shutdown, _) = broadcast::channel(1);
let config: Config = serde_json::from_reader(file).expect("json parse error");
for target in config.tcp { for target in config.tcp {
let listener = listener::Listener { let listener = listener::Listener {
shutdown: shutdown::Shutdown::new(notify_shutdown.subscribe()), shutdown: shutdown::Shutdown::new(notify_shutdown.subscribe()),

View File

@ -28,9 +28,9 @@ impl Shutdown {
} }
/// Returns `true` if the shutdown signal has been received. /// Returns `true` if the shutdown signal has been received.
pub(crate) fn is_shutdown(&self) -> bool { // pub(crate) fn is_shutdown(&self) -> bool {
self.shutdown // self.shutdown
} // }
/// Receive the shutdown notice, waiting if necessary. /// Receive the shutdown notice, waiting if necessary.
pub(crate) async fn recv(&mut self) { pub(crate) async fn recv(&mut self) {