rayfish 0.1.4

P2P mesh VPN powered by iroh — connect peers by cryptographic identity, not IP address
[package]
name = "rayfish"
version = "0.1.4"
edition = "2024"
rust-version = "1.91"
authors = ["Dario <dario@rayfish.xyz>"]
description = "P2P mesh VPN powered by iroh — connect peers by cryptographic identity, not IP address"
license = "MPL-2.0"
repository = "https://github.com/rayfish/rayfish"
homepage = "https://github.com/rayfish/rayfish"
readme = "README.md"
keywords = ["vpn", "p2p", "mesh", "networking", "iroh"]
categories = ["network-programming", "command-line-utilities"]

# The repo root is both the `rayfish` package (binary `ray`) and the workspace
# root. `ray-proto` is a member crate holding the shared IPC wire protocol.
[workspace]
members = ["ray-proto"]

[[bin]]
name = "ray"
path = "src/main.rs"

[features]
default = []
tor = ["dep:iroh-tor-transport"]
# Export tracing spans to an OpenTelemetry collector over OTLP/HTTP. Activated at
# runtime only when an OTEL endpoint is configured (standard OTEL_* env vars).
otel = [
    "dep:opentelemetry",
    "dep:opentelemetry_sdk",
    "dep:opentelemetry-otlp",
    "dep:tracing-opentelemetry",
]

[dependencies]
ray-proto = { path = "ray-proto", version = "0.1.4" }
anyhow = "1"
blake3 = { version = "1", features = ["serde"] }
bytes = "1"
clap = { version = "4", features = ["derive"] }
ahash = "0.8"
clap_complete = "4"
# Token-bucket rate limiter guarding inbound control streams against floods
# (src/ratelimit.rs). One per control-listener task; no shared state.
ratelimit = "0.10"
dashmap = "6"
dirs = "6.0.0"
futures = "0.3"
iroh = { version = "1", features = ["metrics", "unstable-custom-transports", "unstable-net-report"] }
iroh-tor-transport = { version = "0.1", optional = true }
iroh-metrics = { version = "1", features = ["service", "metrics"] }
iroh-dns = "1"
iroh-blobs = { version = "0.103", default-features = false, features = ["fs-store"] }
iroh-mdns-address-lookup = "0.4"
humansize = "2"
unicode-width = "0.2"
indicatif = "0.18"
crossterm = "0.29"
mime_guess = "2"
rand = "0.10"
rmp-serde = "1"
libc = "0.2"
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7", features = ["codec"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter", "registry"] }
tracing-appender = "0.2"
opentelemetry = { version = "0.32", optional = true }
opentelemetry_sdk = { version = "0.32", features = ["rt-tokio"], optional = true }
opentelemetry-otlp = { version = "0.32", default-features = false, features = [
    "trace",
    "http-proto",
    "reqwest-client",
], optional = true }
tracing-opentelemetry = { version = "0.33", optional = true }
tar = "0.4"
flate2 = "1"
tun = { version = "0.8.13", features = ["async"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yml = "0.0.13"
toml = "1.1"
# Format-agnostic config loading for `ray apply` specs (YAML/TOML/JSON by
# extension). Read-only; `--dry-run`/`--example` output uses serde_yml.
config = { version = "0.15", default-features = false, features = ["yaml", "toml"] }
url = "2"
hex = "0.4.3"
simple-dns = "0.11"
smol_str = { version = "0.3.6", features = ["serde"] }
arc-swap = "1.9.1"
qr2term = "0.3.3"
bs58 = "0.5.1"
chacha20poly1305 = "0.10.1"
argon2 = "0.5.3"
rpassword = "7.5.4"
async-trait = "0.1"
bytesize = "2.4.0"
# `ray update`: query the GitHub releases API and download the new binary.
# `rustls-no-provider` reuses the ring TLS stack already in the tree (iroh's
# `tls-ring`) — no aws-lc-rs C build (which breaks cross-compilation), no OpenSSL
# system dep. We install ring as the process-default CryptoProvider in cmd_update.
reqwest = { version = "0.13", default-features = false, features = [
    "json",
    "stream",
    "rustls-no-provider",
] }
# Direct handle on rustls so we can install the ring crypto provider as the
# process default before reqwest builds its client (reqwest pulls no provider).
rustls = { version = "0.23", default-features = false, features = ["ring"] }
# Atomically replace the running executable during `ray update`.
self-replace = "1"
# SHA-256 verification of the downloaded release asset against its .sha256 file.
sha2 = "0.10"
# Semantic version comparison for `ray update` (only upgrade when newer).
semver = "1"
# Embedded mesh SSH server (`ray firewall ssh on`): pure-Rust async SSH on tokio.
# Use the `ring` crypto backend (already in the tree via iroh) instead of the
# default `aws-lc-rs`, whose C build breaks cross-compilation (`just cross`).
russh = { version = "0.54", default-features = false, features = ["ring", "flate2"] }
# PTY allocation + login-shell spawning for SSH sessions (async/tokio).
pty-process = { version = "0.5", features = ["async"] }
# getpwnam-style passwd lookup to resolve the requested SSH unix user.
uzers = "0.12"
# Build the mesh SSH listener socket with SO_REUSEADDR/SO_REUSEPORT so binding
# a specific mesh IP's port 22 coexists with a host sshd on 0.0.0.0:22.
socket2 = { version = "0.5", features = ["all"] }

[dev-dependencies]
tempfile = "3"
criterion = "0.5"

# Microbenchmarks for the per-packet data path (firewall eval + the zero-copy
# Bytes hand-off). Run with `cargo bench`. `harness = false` lets Criterion own
# `fn main`.
[[bench]]
name = "forward"
harness = false

[target.'cfg(target_os = "linux")'.dependencies]
rtnetlink = "0.21.0"
zbus = { version = "5", default-features = false, features = ["tokio"] }
# Watch /etc/resolv.conf for trampling (NetworkManager/dhclient) in direct mode
# so we re-assert in ~ms instead of polling. `stream` gives a tokio-driven
# EventStream we can select! on alongside the cancellation token.
inotify = { version = "0.11", default-features = false, features = ["stream"] }

[target.'cfg(target_os = "macos")'.dependencies]
system-configuration = "0.7"
core-foundation = "0.9"

[target.'cfg(windows)'.dependencies]
# Enables ANSI escape processing on legacy Windows consoles (no-op on modern terminals).
enable-ansi-support = "0.3"