Skip to content

Commit 1a6e825

Browse files
committed
chore(docs): Add help and readme
Signed-off-by: Kasama <robertoaall@gmail.com>
1 parent 3be41e7 commit 1a6e825

3 files changed

Lines changed: 53 additions & 9 deletions

File tree

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Server Knocker
2+
==============
3+
4+
Server knocker is an application that can listen to a port and proxy packets to another application.
5+
6+
The proxy will also wait for a idle timeout. If it doesn't get any new packets in this time, it will kill the child application.
7+
8+
Then, if it receives a new packet, it will spawn the child application again so it can continue proxying packets to it.
9+
10+
Motivation
11+
==========
12+
13+
The goal of server knocker is to save resources when running some expensive application that is not used often. For example, a game server to play with friends every once in a while without wasting resources in the server.
14+
15+
Think a minecraft server that can automatically shut down during the night, and spin up automatically when someone tries to join in.
16+
17+
Usage
18+
=====
19+
20+
Use `server-knocker --help` for detailed up-to-date information.

src/main.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,49 @@ mod proxy;
2020
mod timer;
2121

2222
#[derive(Clone, Debug, Parser)]
23+
/// Server Knocker runs a child application and acts like a proxy to it.
24+
///
25+
/// It expects to run a child application and proxy all packets to the port that this child is listening on.
26+
///
27+
/// After a time without receiving any packets (idle_timeout), the child is terminated.
2328
struct Command {
2429
#[arg(long)]
25-
dest: SocketAddr,
30+
/// Address for the proxy to listen on
31+
listen: SocketAddr,
2632
#[arg(long)]
27-
bind: SocketAddr,
33+
/// Destination address for the proxy
34+
destination: SocketAddr,
2835

36+
#[arg(long, default_value_t = String::from("1h"))]
37+
/// Time between received packets to consider the child applicaiton idle
38+
///
39+
/// Use `h` for hour, `m` for minute, `s` for second or any combination
40+
idle_timeout: String,
2941
#[arg(long, default_value_t = String::from("10s"))]
42+
/// Time to wait between trying to terminate the idle application (SIGTERM) and killing it
43+
/// (SIGKILL)
44+
///
45+
/// Use `h` for hour, `m` for minute, `s` for second or any combination
3046
grace_period: String,
31-
#[arg(long, default_value_t = String::from("10s"))]
32-
idle_timeout: String,
3347

3448
#[arg(long, default_value_t = false)]
49+
/// (experimental) For TCP proxies: if set the proxy will hold off the request until the child is ready if it
50+
/// was down.
51+
///
52+
/// This is experimental because it doesn't work properly with child applications that take a
53+
/// long time to become ready. It will probably need to be paired with a "readiness probe" of sorts in the future.
3554
hold_packets: bool,
3655

3756
#[arg(short = 'u', long, default_value_t = false)]
57+
/// Whether to use UDP instead of the default TCP for the proxy
3858
udp: bool,
3959

4060
#[arg(long)]
61+
/// Command to run as a child. It's expected that it listens on the port set by `dest` and can
62+
/// be terminated
63+
///
64+
/// Make sure that terminating this command also terminates the child application. If using
65+
/// Server Knocker with Docker, for example, make sure to not set `-d`.
4166
command: String,
4267
}
4368

@@ -114,11 +139,11 @@ async fn main() -> anyhow::Result<()> {
114139
info!("Proxy starting...");
115140

116141
if cmd.udp {
117-
UDPProxy::new(cmd.dest, cmd.bind, network_sender)
118-
.start(None)
142+
UDPProxy::new(cmd.destination, cmd.listen, network_sender)
143+
.start()
119144
.await?;
120145
} else {
121-
TCPProxy::new(cmd.dest, cmd.bind, network_sender)
146+
TCPProxy::new(cmd.destination, cmd.listen, network_sender)
122147
.start(if cmd.hold_packets {
123148
Some(can_proxy_resume)
124149
} else {

src/proxy/udp.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use log::{error, info};
77
use tokio::net::UdpSocket;
88
use tokio::sync::mpsc::{channel, Receiver};
99
use tokio::sync::watch::Sender;
10-
use tokio::sync::Notify;
1110

1211
use super::ProxyEvent;
1312

@@ -55,7 +54,7 @@ impl UDPProxy {
5554
Ok(()) as anyhow::Result<()>
5655
}
5756

58-
pub async fn start(&self, can_resume: Option<Arc<Notify>>) -> anyhow::Result<()> {
57+
pub async fn start(&self) -> anyhow::Result<()> {
5958
let local = Arc::new(UdpSocket::bind(self.listen_addr).await?);
6059

6160
let (response_sender, receiver) = channel::<(SocketAddr, Vec<u8>)>(512);

0 commit comments

Comments
 (0)