From a2cbd2ad776fdb04afe9d11dba5b1ed1cc8d1970 Mon Sep 17 00:00:00 2001 From: Jett Chen Date: Sat, 26 Aug 2023 20:51:40 +0800 Subject: [PATCH] Add rudimentary web server --- .../PacketTunnelProvider.swift | 4 +- Cargo.lock | 203 ++++++++++++++++-- burrow/Cargo.toml | 7 +- burrow/src/lib.rs | 1 + burrow/src/server.rs | 42 ++++ tun/src/tokio/mod.rs | 13 +- 6 files changed, 235 insertions(+), 35 deletions(-) create mode 100644 burrow/src/server.rs diff --git a/Apple/NetworkExtension/PacketTunnelProvider.swift b/Apple/NetworkExtension/PacketTunnelProvider.swift index 540c585..e885d82 100644 --- a/Apple/NetworkExtension/PacketTunnelProvider.swift +++ b/Apple/NetworkExtension/PacketTunnelProvider.swift @@ -19,8 +19,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { completionHandler(err) } logger.info("fd: \(fild)") - let networkSettings = genNetSec(fild: fild) - logger.info("Network Settings: - ipv4:\(networkSettings.ipv4Settings) -mtu: \(networkSettings.mtu)") + let network_settings = genNetSec(fild: fild) + logger.info("Network Settings: - ipv4:\(network_settings.ipv4Settings) -mtu: \(network_settings.mtu)") completionHandler(nil) } diff --git a/Cargo.lock b/Cargo.lock index 273ec5d..79a7d93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,6 +93,17 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "async-trait" +version = "0.1.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + [[package]] name = "atty" version = "0.2.14" @@ -110,6 +121,68 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "axum-macros", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-macros" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.29", +] + [[package]] name = "base64" version = "0.21.0" @@ -164,7 +237,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.15", + "syn 2.0.29", "which", ] @@ -193,11 +266,14 @@ checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" name = "burrow" version = "0.1.0" dependencies = [ + "axum", "caps", "clap 4.3.2", "env_logger 0.10.0", "log", "nix", + "serde", + "serde_json", "tokio", "tracing", "tracing-oslog", @@ -340,7 +416,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -612,7 +688,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -931,6 +1007,12 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "matchit" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" + [[package]] name = "memchr" version = "2.5.0" @@ -966,7 +1048,7 @@ checksum = "4901771e1d44ddb37964565c654a3223ba41a594d02b8da471cc4464912b5cfa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -1089,7 +1171,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -1176,6 +1258,26 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1201,23 +1303,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058" dependencies = [ "proc-macro2", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1320,6 +1422,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.13" @@ -1366,21 +1474,45 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1519,15 +1651,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tempfile" version = "3.5.0" @@ -1576,7 +1714,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -1644,7 +1782,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -1671,6 +1809,28 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -1684,6 +1844,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1697,7 +1858,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", ] [[package]] @@ -1892,7 +2053,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -1926,7 +2087,7 @@ checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/burrow/Cargo.toml b/burrow/Cargo.toml index c9338cd..7551e18 100644 --- a/burrow/Cargo.toml +++ b/burrow/Cargo.toml @@ -8,16 +8,19 @@ crate-type = ["lib", "staticlib"] [dependencies] tokio = { version = "1.21", features = ["rt", "macros"] } -tun = { version = "0.1", path = "../tun" } +tun = { version = "0.1", path = "../tun" , features = ["tokio"]} clap = { version = "4.3.2", features = ["derive"] } env_logger = "0.10" log = "0.4" tracing = "0.1" tracing-subscriber = "0.3" +serde = { version = "1.0.188", features = ["derive"] } +serde_json = "1.0.105" +axum = {version = "0.6.20", features = ["json", "macros"]} [target.'cfg(target_os = "linux")'.dependencies] caps = "0.5.5" [target.'cfg(target_vendor = "apple")'.dependencies] nix = { version = "0.26.2" } -tracing-oslog = "0.1" \ No newline at end of file +tracing-oslog = "0.1" diff --git a/burrow/src/lib.rs b/burrow/src/lib.rs index 931517d..de0af85 100644 --- a/burrow/src/lib.rs +++ b/burrow/src/lib.rs @@ -1,6 +1,7 @@ pub mod ensureroot; #[cfg(target_vendor = "apple")] mod apple; +mod server; #[cfg(any(target_os = "linux", target_vendor = "apple"))] use std::{ diff --git a/burrow/src/server.rs b/burrow/src/server.rs new file mode 100644 index 0000000..68e7d13 --- /dev/null +++ b/burrow/src/server.rs @@ -0,0 +1,42 @@ +use axum::{body::Bytes, error_handling::HandleErrorLayer, extract::{DefaultBodyLimit, Path, State}, handler::Handler, http::StatusCode, response::IntoResponse, routing::{delete, get}, Router, Json, debug_handler}; +use std::{ + borrow::Cow, + collections::HashMap, + sync::{Arc, RwLock}, + time::Duration, +}; +use std::net::{Ipv4Addr, SocketAddr}; +use axum::handler::HandlerWithoutStateExt; +use serde_json::json; +use tun::TunInterface; // TODO: refactor to tokio TunInterface, which doesn't implement `Send` + +type SharedState = Arc>; + +pub async fn serve(ti: TunInterface){ + let state = Arc::new(RwLock::new( + ti + )); + let app_router = Router::new() + .route("/info", get(network_settings)) + .with_state(state); + let port = std::env::var("BURROW_PORT").unwrap_or("3000".to_string()); + let sock_addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port.parse().unwrap()); + axum::Server::bind(&sock_addr) + .serve(app_router.into_make_service()) + .await + .unwrap(); +} + +#[debug_handler] +async fn network_settings(State(state): State) -> impl IntoResponse{ + let st = state.read().unwrap(); + let name = st.name().unwrap(); + let mtu = st.mtu().unwrap(); + let netmask = st.netmask().unwrap(); + let res = Json(json!({ + "name": name, + "mtu": mtu, + "netmask": netmask, + })); + res +} \ No newline at end of file diff --git a/tun/src/tokio/mod.rs b/tun/src/tokio/mod.rs index 97b587e..7c0c465 100644 --- a/tun/src/tokio/mod.rs +++ b/tun/src/tokio/mod.rs @@ -5,6 +5,9 @@ pub struct TunInterface { inner: AsyncFd, } +unsafe impl Send for TunInterface { +} + impl TunInterface { pub fn new(tun: crate::TunInterface) -> io::Result { Ok(Self { @@ -62,16 +65,6 @@ impl TunInterface { } } - pub async fn set_name(&self, name: &str) -> io::Result<()> { - loop { - let mut guard = self.inner.readable().await?; - match guard.try_io(|inner| inner.get_ref().set_name(name)) { - Ok(result) => return result, - Err(_would_block) => continue, - } - } - } - pub async fn netmask(&self) -> io::Result { loop { let mut guard = self.inner.readable().await?;