From 104cbb6126e55ff8f700629b42b723660899f654 Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Fri, 3 Feb 2023 19:18:34 +0100 Subject: [PATCH] Stub for libFenrir Signed-off-by: Luca Fulchir --- .editorconfig | 12 +++++++ Cargo.toml | 38 ++++++++++++++++++++- flake.nix | 8 ++++- rustfmt.toml | 8 +++++ src/config/mod.rs | 23 +++++++++++++ src/lib.rs | 85 ++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 163 insertions(+), 11 deletions(-) create mode 100644 .editorconfig create mode 100644 rustfmt.toml create mode 100644 src/config/mod.rs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d1f040a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/Cargo.toml b/Cargo.toml index 712badf..855e70d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,44 @@ [package] -name = "libFenrir" + +name = "fenrir" version = "0.1.0" edition = "2021" +# Fenrir won't be ready for a while, +# we might as well use async fn in trait, which is nightly +# remember to update this +rust-version = "1.67.0" +homepage = "https://git.runesauth.com/RunesAuth/libFenrir" +repository = "https://git.runesauth.com/RunesAuth/libFenrir" +license = "Apache-2.0" +keywords = [ "Fenrir", "libFenrir", "authentication" ] +categories = [ "authentication", "cryptography", "network-programming" ] + +# keep this until the PoC works +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] + +crate_type = [ "lib", "cdylib", "staticlib" ] + [dependencies] + +thiserror = { version = "^1.0" } +tokio = { version = "^1", features = ["full"] } +# PERF: todo linux-only, behind "iouring" feature +#tokio-uring = { version = "^0.4" } +tracing = { version = "^0.1" } + +[profile.dev] + +opt-level = 0 +debug = true +debug-assertions = true +overflow-checks = true +lto = false +panic = 'unwind' +incremental = true +codegen-units = 256 +rpath = false + diff --git a/flake.nix b/flake.nix index 4fba8c7..2277581 100644 --- a/flake.nix +++ b/flake.nix @@ -26,10 +26,16 @@ pkg-config exa fd - (rust-bin.stable.latest.default.override { + #(rust-bin.stable.latest.default.override { + # go with nightly to have async fn in traits + (rust-bin.nightly."2023-02-01".default.override { #extensions = [ "rust-src" ]; #targets = [ "arm-unknown-linux-gnueabihf" ]; }) + clippy + lld + cargo-watch + rustfmt ]; shellHook = '' # use zsh or other custom shell diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..8008a3e --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,8 @@ +edition = "2021" +unstable_features = true +format_strings = true +max_width = 80 +# next ones do not work on stable yet +wrap_comments = true +comment_width = 80 + diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..3e008ef --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,23 @@ +//! +//! Configuration to initialize the Fenrir networking library + +use ::std::{net::SocketAddr, num::NonZeroUsize, option::Option, vec::Vec}; + +/// Main config for libFenrir +#[derive(Clone, Debug)] +pub struct Config { + /// number of threads that libFenrir will use + pub threads: Option, + /// List of ipv4 or ipv6 UDP inet socket to listen on + /// If empty, libFenrir will listen on a random UDP port on `0.0.0.0` + pub listen: Vec, +} + +impl Default for Config { + fn default() -> Self { + Config { + threads: None, + listen: Vec::new(), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 7d12d9a..37d8e00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,81 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +#![deny( + missing_docs, + missing_debug_implementations, + missing_copy_implementations, + trivial_casts, + trivial_numeric_casts, + unsafe_code, + unstable_features, + unused_import_braces, + unused_qualifications +)] + +//! +//! libFenrir is the official rust library implementing the Fenrir protocol + +use ::std::{ + io::Result, + net::{IpAddr, Ipv4Addr, SocketAddr}, +}; +use ::tokio::{net::UdpSocket, runtime}; +use ::tracing::error; + +mod config; +pub use config::Config; + +/// Instance of a fenrir endpoint +#[allow(missing_copy_implementations, missing_debug_implementations)] +pub struct Fenrir { + /// library Configuration + cfg: Config, + /// internal runtime + rt: ::tokio::runtime::Runtime, } -#[cfg(test)] -mod tests { - use super::*; +/// Initialize a new Fenrir endpoint +pub fn init(config: &Config) -> Result { + // PERF: linux iouring + // PERF: multithread pinning with hwloc2 for topology + let f = Fenrir::new(config.clone())?; + f.add_listener(); + Ok(f) +} - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); +impl Fenrir { + /// Create a new Fenrir endpoint + fn new(config: Config) -> Result { + let mut builder = runtime::Builder::new_multi_thread(); + if let Some(threads) = config.threads { + builder.worker_threads(threads.get()); + } + let rt = match builder.thread_name("libFenrir").build() { + Ok(rt) => rt, + Err(e) => { + ::tracing::error!("Can't initialize: {}", e); + return Err(e); + } + }; + Ok(Fenrir { + cfg: config, + rt: rt, + }) + } + /// Add an UDP listener + fn add_listener(&self) { + if self.cfg.listen.len() == 0 { + self.rt.spawn(listen_udp(SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + 0, // 0 means random port + ))); + } else { + for sock in self.cfg.listen.iter() { + self.rt.spawn(listen_udp(sock.clone())); + } + } } } +/// Add an async udp listener +async fn listen_udp(sock: SocketAddr) -> Result<()> { + UdpSocket::bind(sock).await?; + Ok(()) +}