[package] name = "tsunagi" version = "0.1.0" edition = "2024" rust-version = "1.91" license = "MIT OR Apache-2.0" description = "Proof-of-concept library for small private mesh networks: persistent agent identity, deterministic network spaces, iroh-based control plane." repository = "https://github.com/tsunagi-net/tsunagi" readme = "README.md" keywords = ["mesh", "p2p", "iroh", "networking"] categories = ["network-programming"] [features] default = ["cli"] # The `tsunagi` command line binary. Library users can opt out. cli = ["dep:clap", "dep:anstream", "dep:anstyle", "dep:tracing-subscriber", "tokio/signal", "tun-device", "dns-publish"] # A real TUN device, so the WireGuard plugin can carry actual IP traffic. # Needs CAP_NET_ADMIN at run time; without it the plugin still runs and its # in-memory device can be used for tests. tun-device = ["dep:tun", "dep:rtnetlink", "dep:caps", "dep:futures-util"] # Telling the operating system where to send its questions. Linux only for # now; the zone and the server work without it. dns-publish = ["dep:zbus"] [[bin]] name = "tsunagi" path = "src/bin/tsunagi.rs" required-features = ["cli"] [dependencies] clap = { version = "4.5", features = ["derive", "env"], optional = true } # Already in the tree through clap. `anstream` strips the escapes when stdout # is not a terminal and turns on virtual terminal processing on Windows, so # colour is never written where it would show up as rubbish. anstream = { version = "1.0", optional = true } anstyle = { version = "1.0", optional = true } tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true } iroh = { version = "1.2", default-features = false, features = ["tls-ring"] } tokio = { version = "1.53", features = ["rt", "rt-multi-thread", "sync", "time", "macros"] } rusqlite = { version = "0.40", features = ["bundled"] } hkdf = "0.13" hmac = "0.13" sha2 = "0.11" subtle = "2.6" zeroize = { version = "1.9", features = ["derive"] } rand = "0.10" serde = { version = "1.0", features = ["derive"] } postcard = { version = "1.1", default-features = false, features = ["use-std"] } # Already in the tree through iroh. A packet codec, not a DNS server: the # zone logic is ours and a full server framework would be a large dependency # for answering A records from memory. simple-dns = "0.12" # The IANA top-level domain list, compiled in: one function, no # dependencies, no network. Used only to warn that a zone name shadows a # real public domain, never to refuse one. tld = "2.40" data-encoding = "2.11" hex = "0.4" thiserror = "2.0" tracing = "0.1" fs4 = { version = "1.1", features = ["sync"] } directories = "6.0" # The real system hostname, without a libc call of our own: this crate is # forbidden `unsafe` and will not make one. gethostname = "1.1" netwatch = "0.19.3" bytes = "1.12.1" boringtun = { version = "0.7.1", default-features = false } tun = { version = "0.8", features = ["async"], optional = true } # Linux-only interface provisioning. `rtnetlink` configures the interface in # process, so no `ip` invocation is ever needed; `caps` keeps CAP_NET_ADMIN # out of the effective set except during the moments it is used. [target.'cfg(target_os = "linux")'.dependencies] rtnetlink = { version = "0.23", optional = true } # Pure Rust D-Bus, no libdbus to link against. `tokio` rather than the # default reactor, because the agent brings its own. zbus = { version = "5.19", default-features = false, features = ["tokio"], optional = true } caps = { version = "0.5", optional = true } futures-util = { version = "0.3", default-features = false, optional = true } [dev-dependencies] tokio = { version = "1.53", features = ["rt", "rt-multi-thread", "sync", "time", "macros", "process"] } tempfile = "3.24" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [lints.rust] missing_docs = "warn" unsafe_code = "forbid" [lints.clippy] unwrap_used = "warn" expect_used = "warn" panic = "warn"