Merge remote-tracking branch 'am/daemonize' into quiche

This commit is contained in:
Ezra Barrow 2023-08-18 11:33:30 -05:00
commit a8d89b5f29
No known key found for this signature in database
GPG Key ID: 5EF8BA3CE9180419
8 changed files with 118 additions and 28 deletions

10
Cargo.lock generated
View File

@ -152,6 +152,15 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "daemonize"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8bfdaacb3c887a54d41bdf48d3af8873b3f5566469f8ba21b92057509f116e"
dependencies = [
"libc",
]
[[package]]
name = "deranged"
version = "0.3.7"
@ -720,6 +729,7 @@ dependencies = [
"backoff",
"base64",
"color-eyre",
"daemonize",
"quiche",
"quinn",
"rcgen",

View File

@ -11,6 +11,7 @@ backoff = { version = "0.4.0", features = ["tokio"] }
base64 = "0.21.2"
color-eyre = "0.6.2"
quiche = "0.17.2"
daemonize = "0.5.0"
quinn = { version = "0.10.2", features = [] }
rcgen = "0.11.1"
ring = "0.16.20"

View File

@ -1,6 +1,11 @@
[server]
endpoint = "127.0.0.1:9092"
daemonize = true
endpoint = "10.177.1.7:9092"
server_name = "alphamethyl.barr0w.net"
user = "nobody"
group = "daemon"
stdout = "/tmp/sleepyserver"
stderr = "/tmp/sleepyserver.err"
[client]
endpoint = "10.177.1.7:9092"

View File

@ -19,4 +19,3 @@
async fn main() -> anyhow::Result<()> {
sleepytunny::client_main().await
}

View File

@ -19,4 +19,3 @@
async fn main() -> anyhow::Result<()> {
sleepytunny::config::Configuration::generate_config("config.toml")
}

View File

@ -15,8 +15,45 @@
* --------------------
*/
use daemonize::Daemonize;
use tokio_tun::Tun;
use std::fs::File;
use std::sync::Arc;
use sleepytunny::config::Configuration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
sleepytunny::server_main().await
}
let c = Arc::new(Configuration::load_config("config.toml")?);
let tun = Tun::builder()
.name("sleepy")
.tap(false)
.packet_info(true)
.address(c.interface.address)
.netmask(c.interface.netmask)
.up()
.try_build()?;
let tun = tun;
let user = &c.server()?.user()?;
let group = &c.server()?.group()?;
let stdout = File::create(&c.server()?.stdout()?)?;
let stderr = File::create(&c.server()?.stderr()?)?;
let daemonize = Daemonize::new()
.user(user.as_str())
.group(group.as_str())
.stdout(stdout)
.stderr(stderr);
if c.server()?.daemonize {
match daemonize.start() {
Ok(_) => sleepytunny::server_main(c.clone(), tun).await,
Err(e) => {
eprintln!("Error, {}", e);
panic!()
}
}
} else {
sleepytunny::server_main(c.clone(), tun).await
}
}

View File

@ -1,5 +1,5 @@
use anyhow::Context;
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Write;
use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs};
@ -8,20 +8,61 @@ use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Server {
pub daemonize: bool,
pub endpoint: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub server_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stdout: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stderr: Option<String>,
}
impl Server {
pub fn new() -> Self {
Self {
daemonize: true,
endpoint: String::from("127.0.0.1:9092"),
server_name: Some(String::from("alphamethyl.barr0w.net")),
user: Some(String::from("nobody")),
group: Some(String::from("daemon")),
stdout: Some(String::from("/tmp/sleepyserver")),
stderr: Some(String::from("/tmp/sleepyserver.err")),
}
}
pub fn user(&self) -> anyhow::Result<String> {
match &self.user {
Some(u) => Ok(u.clone()),
None => Ok(String::from("nobody")),
}
}
pub fn group(&self) -> anyhow::Result<String> {
match &self.group {
Some(g) => Ok(g.clone()),
None => Ok(String::from("daemon")),
}
}
pub fn stdout(&self) -> anyhow::Result<String> {
match &self.stdout {
Some(s) => Ok(s.clone()),
None => Ok(String::from("/tmp/sleepyserver")),
}
}
pub fn stderr(&self) -> anyhow::Result<String> {
match &self.stderr {
Some(s) => Ok(s.clone()),
None => Ok(String::from("/tmp/sleepyserver.err")),
}
}
/// Returns the socketaddr our endpoint should bind to
pub fn endpoint(&self) -> anyhow::Result<SocketAddr> {
self.endpoint.to_socket_addrs()?.next().context("bad server socketaddr")
self.endpoint
.to_socket_addrs()?
.next()
.context("bad server socketaddr")
}
/// Returns the server name for SNI
pub fn server_name(&self) -> anyhow::Result<Option<&String>> {
@ -48,7 +89,10 @@ impl Client {
}
/// Returns the socketaddr of the server's endpoint
pub fn endpoint(&self) -> anyhow::Result<SocketAddr> {
self.endpoint.to_socket_addrs()?.next().context("bad server socketaddr")
self.endpoint
.to_socket_addrs()?
.next()
.context("bad server socketaddr")
}
/// Returns the server name for SNI
pub fn server_name(&self) -> anyhow::Result<Option<&String>> {
@ -103,10 +147,14 @@ impl Configuration {
}
/// Returns the server config or an appropriate error
pub fn server(&self) -> anyhow::Result<&Server> {
self.server.as_ref().context("this config is not a server config")
self.server
.as_ref()
.context("this config is not a server config")
}
/// Returns the client config or an appropriate error
pub fn client(&self) -> anyhow::Result<&Client> {
self.client.as_ref().context("this config is not a client config")
self.client
.as_ref()
.context("this config is not a client config")
}
}

View File

@ -18,12 +18,12 @@ use anyhow::Context;
use std::{io, sync::Arc, time::Duration};
use tokio::{
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
sync::mpsc::error::{TryRecvError, SendError},
sync::mpsc::error::{SendError, TryRecvError},
time::sleep,
};
use tokio_tun::Tun;
mod encoder;
pub mod encoder;
use encoder::Encoder;
mod quic;
@ -111,7 +111,7 @@ pub async fn client_main() -> anyhow::Result<()> {
}
let vec = Vec::from(stream_buf);
match to_tun.send(vec) {
Ok(()) => {},
Ok(()) => {}
Err(SendError(vec)) => {
conn.close(true, 0x0, b"exiting")?;
return Ok(());
@ -122,8 +122,8 @@ pub async fn client_main() -> anyhow::Result<()> {
match conn.stream_writable(2, 1350) {
Ok(false) => {
return Ok(());
},
Err(quiche::Error::InvalidStreamState(_)) => {},
}
Err(quiche::Error::InvalidStreamState(_)) => {}
Err(e) => return Err(e.into()),
_ => {}
}
@ -193,16 +193,7 @@ pub async fn client_main() -> anyhow::Result<()> {
}
}
pub async fn server_main() -> anyhow::Result<()> {
let c = Arc::new(Configuration::load_config("config2.toml")?);
let tun = Tun::builder()
.name("sleepy2")
.tap(false)
.packet_info(true)
.address(c.interface.address)
.netmask(c.interface.netmask)
.up()
.try_build()?;
pub async fn server_main(c: Arc<Configuration>, mut tun: Tun) -> anyhow::Result<()> {
let mut tun = Encoder::new(tun);
let (mut to_tun, mut from_quic) = tokio::sync::mpsc::unbounded_channel::<Vec<u8>>();
let (mut to_quic, mut from_tun) = tokio::sync::mpsc::channel::<Vec<u8>>(8);
@ -232,7 +223,7 @@ pub async fn server_main() -> anyhow::Result<()> {
}
let vec = Vec::from(stream_buf);
match to_tun.send(vec) {
Ok(()) => {},
Ok(()) => {}
Err(SendError(vec)) => {
client.conn.close(true, 0x0, b"exiting")?;
return Ok(());
@ -243,8 +234,8 @@ pub async fn server_main() -> anyhow::Result<()> {
match client.conn.stream_writable(3, 1350) {
Ok(false) => {
return Ok(());
},
Err(quiche::Error::InvalidStreamState(_)) => {},
}
Err(quiche::Error::InvalidStreamState(_)) => {}
Err(e) => return Err(e.into()),
_ => {}
}