Behind a home router the client is unreachable for incoming peer connections, so browsing/downloading firewalled peers (and the server-brokered connect-back) times out. Add a best-effort port mapper to the binary crate that, when listening is enabled, makes us reachable: - NAT-PMP (RFC 6886) hand-rolled on std::net::UdpSocket, zero deps, with an injectable gateway address so it is fully testable. - UPnP-IGD via the blocking igd-next crate as the primary path. - A background PortMapper that discovers off the main thread (never blocks startup), renews at half the lease, and removes the mapping on drop. Any failure is non-fatal and logged. - Maps the EXACT listen port only (we advertise it verbatim via SetWaitPort, so a different external port would be unreachable) and warns the user to forward manually otherwise. Wired into the TUI, search, and CLI browse (the P2P modes); chat/rooms/ messaging are server-mediated and skip it. e2e-tested against an in-process mock NAT-PMP gateway: the map request bytes, response parsing, result-code/timeout handling, and the full spawn -> map -> drop -> unmap service lifecycle.
27 lines
634 B
TOML
27 lines
634 B
TOML
[package]
|
|
name = "soulseek-rs"
|
|
version.workspace = true
|
|
authors.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
description = "Command-line client for Soulseek protocol"
|
|
keywords = ["soulseek", "p2p", "client", "file-sharing"]
|
|
categories = ["command-line-utilities"]
|
|
|
|
[[bin]]
|
|
name = "soulseek-rs"
|
|
path = "src/main.rs"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[dependencies]
|
|
soulseek-rs-lib = { version = "0.3.0", path = "../soulseek-rs-lib" }
|
|
|
|
clap = { version = "4.6.2", features = ["derive", "color", "wrap_help", "env"] }
|
|
ratatui = "0.30.2"
|
|
color-eyre = "0.6.5"
|
|
dotenv = "0.15.0"
|
|
igd-next = "0.17"
|