feat(net): accept relay hostnames
PLAN.md describes the first client flow as entering a relay domain and room code, but the client and gateway CLIs only accepted socket-address literals. Add a small shared RelayEndpoint parser so bare hosts default to UDP/443 while IP literals and explicit host:port values stay supported. The runtime configs still store resolved SocketAddr values. That keeps the Windows route-pinning path on a concrete relay IP before TAP activation while avoiding duplicated endpoint grammar between client and gateway. The relay listen config reuses the same default port constant so UDP/443 has one source. README examples now use lanparty-relay.local and document the shared endpoint syntax. Test Plan: - cargo fmt --check - cargo test -p lanparty-net - cargo test -p lanparty-client-win \ accepts_relay_domain_with_default_port -- --nocapture - cargo test -p lanparty-gateway \ accepts_iface_alias_for_gateway_interface -- --nocapture - cargo test -p lanparty-net -p lanparty-client-win -p lanparty-gateway - cargo clippy -p lanparty-net -p lanparty-client-win -p lanparty-gateway \ --all-targets -- -D warnings - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - git diff --check Refs: PLAN.md
This commit is contained in:
@@ -8,6 +8,7 @@ anyhow.workspace = true
|
||||
clap.workspace = true
|
||||
lanparty-client-core = { path = "../lanparty-client-core" }
|
||||
lanparty-ctrl = { path = "../lanparty-ctrl" }
|
||||
lanparty-net = { path = "../lanparty-net" }
|
||||
lanparty-obs = { path = "../lanparty-obs" }
|
||||
lanparty-proto = { path = "../lanparty-proto" }
|
||||
tokio.workspace = true
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fs,
|
||||
net::{IpAddr, SocketAddr},
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::{collections::BTreeMap, fs, net::IpAddr, path::PathBuf};
|
||||
#[cfg(windows)]
|
||||
use std::{
|
||||
sync::{Arc, mpsc},
|
||||
@@ -26,6 +21,7 @@ use lanparty_client_route::{
|
||||
#[cfg(windows)]
|
||||
use lanparty_client_tap::TapAdapter;
|
||||
use lanparty_ctrl::{ControlMessage, PeerInfo, Role, RoomCode};
|
||||
use lanparty_net::RelayEndpoint;
|
||||
use lanparty_obs::{ClientDiagnostics, RelayDiagnostics, TapDiagnostics};
|
||||
use lanparty_proto::MacAddr;
|
||||
|
||||
@@ -42,9 +38,9 @@ const CLIENT_DIAGNOSTICS_INTERVAL: Duration = Duration::from_secs(10);
|
||||
about = "Windows TAP client for the LAN party L2 tunnel"
|
||||
)]
|
||||
struct ClientArgs {
|
||||
/// Relay UDP socket address, for example 203.0.113.10:443.
|
||||
#[arg(long)]
|
||||
relay: SocketAddr,
|
||||
/// Relay DNS name or UDP socket address; bare hosts default to UDP/443.
|
||||
#[arg(long, value_name = "HOST[:PORT]")]
|
||||
relay: RelayEndpoint,
|
||||
|
||||
/// TLS server name expected in the relay certificate.
|
||||
#[arg(long, default_value = "lanparty-relay.local")]
|
||||
@@ -89,8 +85,13 @@ impl ClientArgs {
|
||||
None => ClientIdentityStore::new(self.identity_file)?.load_or_create()?,
|
||||
};
|
||||
|
||||
let relay_addr = self
|
||||
.relay
|
||||
.resolve()
|
||||
.with_context(|| format!("failed to resolve relay endpoint {}", self.relay))?;
|
||||
|
||||
ClientSessionConfig::new(
|
||||
self.relay,
|
||||
relay_addr,
|
||||
self.server_name,
|
||||
relay_ca_cert,
|
||||
self.room,
|
||||
@@ -778,6 +779,7 @@ fn open_tap_adapter(_session: &ClientSession) {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use lanparty_ctrl::{DisconnectReason, PeerInfo};
|
||||
use lanparty_net::DEFAULT_RELAY_PORT;
|
||||
use lanparty_obs::{QuicDiagnostics, TunnelStats};
|
||||
|
||||
#[test]
|
||||
@@ -845,6 +847,22 @@ mod tests {
|
||||
assert_eq!(refreshed.ip().unwrap().to_string(), "10.73.42.51");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_relay_domain_with_default_port() {
|
||||
let args = ClientArgs::parse_from([
|
||||
"lanparty-client-win",
|
||||
"--relay",
|
||||
"relay.example.test",
|
||||
"--relay-ca-cert",
|
||||
"relay-cert.der",
|
||||
"--room",
|
||||
"ROOM1",
|
||||
]);
|
||||
|
||||
assert_eq!(args.relay.host(), "relay.example.test");
|
||||
assert_eq!(args.relay.port(), DEFAULT_RELAY_PORT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_relay_lifecycle_events() {
|
||||
let gateway = ControlMessage::PeerJoined(PeerInfo::new(1, Role::Gateway, None).unwrap());
|
||||
|
||||
Reference in New Issue
Block a user