feat(cli): select transport in config; server MultiServer + client dial handover
- aura-cli config gains [transport] (order + per-transport ports + obfuscate/ masquerade); server binds all enabled transports via MultiServer, client uses dial() with UDP->TCP->QUIC handover. Config examples updated; backward-compatible (defaults to udp,tcp,quic). 21 cli tests incl. a real-UDP-transport loopback. - docs/sing-box.md: integration approach note (process-bridge now; native Go outbound for phones, with crypto-library mapping + KAT requirement). - Normalize rustfmt across the v2 transport files (tcp/dial/udp contract). Whole workspace: 97 tests pass, clippy -D warnings clean, fmt clean. Deploy flow (pki init/issue-server/issue-client) validated with the release binary. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,9 @@ impl FromStr for TransportMode {
|
||||
"udp" => Ok(Self::Udp),
|
||||
"tcp" => Ok(Self::Tcp),
|
||||
"quic" => Ok(Self::Quic),
|
||||
other => Err(format!("unknown transport '{other}' (expected udp|tcp|quic)")),
|
||||
other => Err(format!(
|
||||
"unknown transport '{other}' (expected udp|tcp|quic)"
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +119,8 @@ pub async fn dial(
|
||||
};
|
||||
tracing::info!("dial: trying {mode} at {addr}");
|
||||
let attempt =
|
||||
tokio::time::timeout(cfg.attempt_timeout, dial_one(*mode, addr, &proto_cfg, &cfg)).await;
|
||||
tokio::time::timeout(cfg.attempt_timeout, dial_one(*mode, addr, &proto_cfg, &cfg))
|
||||
.await;
|
||||
match attempt {
|
||||
Ok(Ok(conn)) => {
|
||||
tracing::info!("dial: connected via {mode}");
|
||||
|
||||
@@ -109,7 +109,11 @@ impl PacketConnection for TcpConnection {
|
||||
Frame::Data { payload, .. } => return Ok(payload.to_vec()),
|
||||
Frame::Ping { seq } => {
|
||||
// Separate mutex from the receive lock we hold => no deadlock.
|
||||
self.sender.lock().await.send_frame(Frame::Pong { seq }).await?;
|
||||
self.sender
|
||||
.lock()
|
||||
.await
|
||||
.send_frame(Frame::Pong { seq })
|
||||
.await?;
|
||||
}
|
||||
Frame::Pong { .. } => continue,
|
||||
Frame::Close { code, reason } => {
|
||||
|
||||
@@ -10,8 +10,12 @@ use aura_transport::{dial, DialConfig, Endpoints, TcpOpts, TransportMode, UdpOpt
|
||||
|
||||
fn make_configs() -> (ServerConfig, ClientConfig) {
|
||||
let ca = AuraCa::generate("Aura Test CA").expect("generate CA");
|
||||
let server = ca.issue_server_cert("localhost").expect("issue server cert");
|
||||
let client = ca.issue_client_cert("client-dial").expect("issue client cert");
|
||||
let server = ca
|
||||
.issue_server_cert("localhost")
|
||||
.expect("issue server cert");
|
||||
let client = ca
|
||||
.issue_client_cert("client-dial")
|
||||
.expect("issue client cert");
|
||||
let ca_pem = ca.ca_cert_pem();
|
||||
(
|
||||
ServerConfig {
|
||||
@@ -33,8 +37,8 @@ async fn dial_falls_back_from_dead_tcp_to_udp() {
|
||||
let (scfg, ccfg) = make_configs();
|
||||
|
||||
// A real UDP server (the working fallback target).
|
||||
let udp_server =
|
||||
UdpServer::bind("127.0.0.1:0".parse().unwrap(), scfg, UdpOpts::default()).expect("bind udp");
|
||||
let udp_server = UdpServer::bind("127.0.0.1:0".parse().unwrap(), scfg, UdpOpts::default())
|
||||
.expect("bind udp");
|
||||
let udp_addr = udp_server.local_addr().expect("udp addr");
|
||||
let srv = tokio::spawn(async move {
|
||||
let conn = udp_server.accept().await.expect("server accept");
|
||||
|
||||
@@ -8,8 +8,12 @@ use aura_transport::{TcpClient, TcpOpts, TcpServer};
|
||||
/// Mint a fresh CA + server("localhost") + client("client-tcp") and build the proto configs.
|
||||
fn make_configs() -> (ServerConfig, ClientConfig) {
|
||||
let ca = AuraCa::generate("Aura Test CA").expect("generate CA");
|
||||
let server = ca.issue_server_cert("localhost").expect("issue server cert");
|
||||
let client = ca.issue_client_cert("client-tcp").expect("issue client cert");
|
||||
let server = ca
|
||||
.issue_server_cert("localhost")
|
||||
.expect("issue server cert");
|
||||
let client = ca
|
||||
.issue_client_cert("client-tcp")
|
||||
.expect("issue client cert");
|
||||
let ca_pem = ca.ca_cert_pem();
|
||||
let scfg = ServerConfig {
|
||||
ca_cert_pem: ca_pem.clone(),
|
||||
|
||||
Reference in New Issue
Block a user