T1.5: Migrate emit/parse sites to v2 wire format
This commit is contained in:
@@ -94,9 +94,10 @@ fn relay_a_handle_offer(reg_a: &mut CallRegistry, offer: &SignalMessage) -> Sign
|
||||
/// reproduced here for the test.
|
||||
fn relay_b_handle_forwarded_offer(reg_b: &mut CallRegistry, forward: &SignalMessage) {
|
||||
let (inner, origin_relay_fp) = match forward {
|
||||
SignalMessage::FederatedSignalForward { inner, origin_relay_fp } => {
|
||||
(inner.as_ref().clone(), origin_relay_fp.clone())
|
||||
}
|
||||
SignalMessage::FederatedSignalForward {
|
||||
inner,
|
||||
origin_relay_fp,
|
||||
} => (inner.as_ref().clone(), origin_relay_fp.clone()),
|
||||
_ => panic!("not a forward"),
|
||||
};
|
||||
// Loop-prevention: drop self-sourced.
|
||||
@@ -114,11 +115,7 @@ fn relay_b_handle_forwarded_offer(reg_b: &mut CallRegistry, forward: &SignalMess
|
||||
};
|
||||
|
||||
// Simulated: target is local to B (Bob is registered here).
|
||||
reg_b.create_call(
|
||||
call_id.clone(),
|
||||
caller_fingerprint,
|
||||
target_fingerprint,
|
||||
);
|
||||
reg_b.create_call(call_id.clone(), caller_fingerprint, target_fingerprint);
|
||||
reg_b.set_caller_reflexive_addr(&call_id, caller_reflexive_addr);
|
||||
reg_b.set_peer_relay_fp(&call_id, Some(origin_relay_fp));
|
||||
}
|
||||
@@ -194,9 +191,10 @@ fn relay_a_handle_forwarded_answer(
|
||||
forward: &SignalMessage,
|
||||
) -> SignalMessage {
|
||||
let (inner, origin_relay_fp) = match forward {
|
||||
SignalMessage::FederatedSignalForward { inner, origin_relay_fp } => {
|
||||
(inner.as_ref().clone(), origin_relay_fp.clone())
|
||||
}
|
||||
SignalMessage::FederatedSignalForward {
|
||||
inner,
|
||||
origin_relay_fp,
|
||||
} => (inner.as_ref().clone(), origin_relay_fp.clone()),
|
||||
_ => panic!("not a forward"),
|
||||
};
|
||||
assert_ne!(origin_relay_fp, RELAY_A_TLS_FP);
|
||||
@@ -270,12 +268,15 @@ fn cross_relay_answer_crosswires_peer_direct_addrs() {
|
||||
|
||||
// Bob answers on Relay B.
|
||||
let answer = bob_answer("c-xrelay-2");
|
||||
let (answer_forward, setup_for_bob) =
|
||||
relay_b_handle_local_answer(&mut reg_b, &answer);
|
||||
let (answer_forward, setup_for_bob) = relay_b_handle_local_answer(&mut reg_b, &answer);
|
||||
|
||||
// Bob's CallSetup carries Alice's addr.
|
||||
match setup_for_bob {
|
||||
SignalMessage::CallSetup { peer_direct_addr, relay_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr,
|
||||
relay_addr,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(peer_direct_addr.as_deref(), Some(ALICE_ADDR));
|
||||
assert_eq!(relay_addr, RELAY_B_ADDR);
|
||||
}
|
||||
@@ -286,7 +287,11 @@ fn cross_relay_answer_crosswires_peer_direct_addrs() {
|
||||
// her CallSetup.
|
||||
let setup_for_alice = relay_a_handle_forwarded_answer(&mut reg_a, &answer_forward);
|
||||
match setup_for_alice {
|
||||
SignalMessage::CallSetup { peer_direct_addr, relay_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr,
|
||||
relay_addr,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(peer_direct_addr.as_deref(), Some(BOB_ADDR));
|
||||
assert_eq!(relay_addr, RELAY_A_ADDR);
|
||||
}
|
||||
@@ -313,9 +318,14 @@ fn cross_relay_loop_prevention_drops_self_sourced_forward() {
|
||||
// The dispatcher in main.rs calls this explicit check before
|
||||
// doing any work. Reproduce it inline.
|
||||
let origin = match &forward {
|
||||
SignalMessage::FederatedSignalForward { origin_relay_fp, .. } => origin_relay_fp.clone(),
|
||||
SignalMessage::FederatedSignalForward {
|
||||
origin_relay_fp, ..
|
||||
} => origin_relay_fp.clone(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Relay B sees origin == its own fp → drop.
|
||||
assert_eq!(origin, RELAY_B_TLS_FP, "loop-prevention triggers on self-fp");
|
||||
assert_eq!(
|
||||
origin, RELAY_B_TLS_FP,
|
||||
"loop-prevention triggers on self-fp"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ use bytes::Bytes;
|
||||
use wzp_proto::{MediaTransport, SignalMessage};
|
||||
use wzp_relay::config::{PeerConfig, TrustedConfig};
|
||||
use wzp_relay::event_log::EventLogger;
|
||||
use wzp_relay::federation::{room_hash, FederationManager};
|
||||
use wzp_relay::federation::{FederationManager, room_hash};
|
||||
use wzp_relay::metrics::RelayMetrics;
|
||||
use wzp_relay::room::RoomManager;
|
||||
use wzp_transport::{client_config, create_endpoint, server_config, QuinnTransport};
|
||||
use wzp_transport::{QuinnTransport, client_config, create_endpoint, server_config};
|
||||
|
||||
// ───────────────────────────── helpers ──────────────────────────────
|
||||
|
||||
@@ -41,8 +41,7 @@ fn create_test_fm_full(
|
||||
) -> Arc<FederationManager> {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
let (sc, _cert) = server_config();
|
||||
let ep = create_endpoint((Ipv4Addr::LOCALHOST, 0).into(), Some(sc))
|
||||
.expect("test endpoint");
|
||||
let ep = create_endpoint((Ipv4Addr::LOCALHOST, 0).into(), Some(sc)).expect("test endpoint");
|
||||
let room_mgr = Arc::new(RoomManager::new());
|
||||
let metrics = Arc::new(RelayMetrics::new());
|
||||
let event_log = EventLogger::Noop;
|
||||
@@ -219,7 +218,10 @@ async fn forward_to_peers_empty_returns_immediately() {
|
||||
fm.forward_to_peers("room", &hash, &data),
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_ok(), "forward_to_peers should return immediately with no peers");
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"forward_to_peers should return immediately with no peers"
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────── 4. forward_to_peers with live QUIC peer links ──────────
|
||||
@@ -339,20 +341,20 @@ async fn broadcast_signal_sends_to_all_peers() {
|
||||
.expect("FM should connect to mock peer within 5s");
|
||||
|
||||
// The FM sends FederationHello as the first signal. Read it.
|
||||
let hello = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
peer_transport.recv_signal(),
|
||||
)
|
||||
.await
|
||||
.expect("hello timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
let hello = tokio::time::timeout(Duration::from_secs(2), peer_transport.recv_signal())
|
||||
.await
|
||||
.expect("hello timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
|
||||
match hello {
|
||||
SignalMessage::FederationHello { tls_fingerprint } => {
|
||||
assert_eq!(tls_fingerprint, "test-relay-fp-abc123");
|
||||
}
|
||||
other => panic!("expected FederationHello, got: {:?}", std::mem::discriminant(&other)),
|
||||
other => panic!(
|
||||
"expected FederationHello, got: {:?}",
|
||||
std::mem::discriminant(&other)
|
||||
),
|
||||
}
|
||||
|
||||
// Now the FM's run_federation_link registered the peer in peer_links
|
||||
@@ -372,20 +374,22 @@ async fn broadcast_signal_sends_to_all_peers() {
|
||||
assert_eq!(count, 1, "should have broadcast to exactly 1 peer");
|
||||
|
||||
// Read the signal on the peer side
|
||||
let received = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
peer_transport.recv_signal(),
|
||||
)
|
||||
.await
|
||||
.expect("broadcast signal timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
let received = tokio::time::timeout(Duration::from_secs(2), peer_transport.recv_signal())
|
||||
.await
|
||||
.expect("broadcast signal timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
|
||||
match received {
|
||||
SignalMessage::FederatedSignalForward { origin_relay_fp, .. } => {
|
||||
SignalMessage::FederatedSignalForward {
|
||||
origin_relay_fp, ..
|
||||
} => {
|
||||
assert_eq!(origin_relay_fp, "other-relay-fp");
|
||||
}
|
||||
other => panic!("expected FederatedSignalForward, got: {:?}", std::mem::discriminant(&other)),
|
||||
other => panic!(
|
||||
"expected FederatedSignalForward, got: {:?}",
|
||||
std::mem::discriminant(&other)
|
||||
),
|
||||
}
|
||||
|
||||
drop(peer_transport);
|
||||
@@ -585,14 +589,11 @@ async fn federation_media_egress_forwards_to_peer() {
|
||||
.expect("FM should connect within 5s");
|
||||
|
||||
// Read the FederationHello
|
||||
let _hello = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
peer_transport.recv_signal(),
|
||||
)
|
||||
.await
|
||||
.expect("hello timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
let _hello = tokio::time::timeout(Duration::from_secs(2), peer_transport.recv_signal())
|
||||
.await
|
||||
.expect("hello timeout")
|
||||
.expect("recv ok")
|
||||
.expect("some message");
|
||||
|
||||
// Wait for link setup
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
|
||||
@@ -11,14 +11,18 @@ use wzp_client::perform_handshake;
|
||||
use wzp_crypto::{KeyExchange, WarzoneKeyExchange};
|
||||
use wzp_proto::{MediaTransport, SignalMessage};
|
||||
use wzp_relay::handshake::accept_handshake;
|
||||
use wzp_transport::{client_config, create_endpoint, server_config, QuinnTransport};
|
||||
use wzp_transport::{QuinnTransport, client_config, create_endpoint, server_config};
|
||||
|
||||
/// Establish a QUIC connection and wrap both sides in `QuinnTransport`.
|
||||
///
|
||||
/// Returns (client_transport, server_transport, _endpoints) where the endpoint
|
||||
/// tuple must be kept alive for the duration of the test to avoid premature
|
||||
/// connection teardown.
|
||||
async fn connected_pair() -> (Arc<QuinnTransport>, Arc<QuinnTransport>, (quinn::Endpoint, quinn::Endpoint)) {
|
||||
async fn connected_pair() -> (
|
||||
Arc<QuinnTransport>,
|
||||
Arc<QuinnTransport>,
|
||||
(quinn::Endpoint, quinn::Endpoint),
|
||||
) {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
|
||||
let (sc, _cert_der) = server_config();
|
||||
@@ -31,7 +35,9 @@ async fn connected_pair() -> (Arc<QuinnTransport>, Arc<QuinnTransport>, (quinn::
|
||||
|
||||
let server_ep_clone = server_ep.clone();
|
||||
let accept_fut = tokio::spawn(async move {
|
||||
let conn = wzp_transport::accept(&server_ep_clone).await.expect("accept");
|
||||
let conn = wzp_transport::accept(&server_ep_clone)
|
||||
.await
|
||||
.expect("accept");
|
||||
Arc::new(QuinnTransport::new(conn))
|
||||
});
|
||||
|
||||
@@ -59,9 +65,8 @@ async fn handshake_succeeds() {
|
||||
|
||||
// Clone Arc so the server transport stays alive in the main task too.
|
||||
let server_t = Arc::clone(&server_transport);
|
||||
let callee_handle = tokio::spawn(async move {
|
||||
accept_handshake(server_t.as_ref(), &callee_seed).await
|
||||
});
|
||||
let callee_handle =
|
||||
tokio::spawn(async move { accept_handshake(server_t.as_ref(), &callee_seed).await });
|
||||
|
||||
let caller_session = perform_handshake(client_transport.as_ref(), &caller_seed, None)
|
||||
.await
|
||||
@@ -120,9 +125,8 @@ async fn handshake_verifies_identity() {
|
||||
);
|
||||
|
||||
let server_t = Arc::clone(&server_transport);
|
||||
let callee_handle = tokio::spawn(async move {
|
||||
accept_handshake(server_t.as_ref(), &callee_seed).await
|
||||
});
|
||||
let callee_handle =
|
||||
tokio::spawn(async move { accept_handshake(server_t.as_ref(), &callee_seed).await });
|
||||
|
||||
let caller_session = perform_handshake(client_transport.as_ref(), &caller_seed, None)
|
||||
.await
|
||||
@@ -179,13 +183,17 @@ async fn auth_then_handshake() {
|
||||
|
||||
let token = match auth_msg {
|
||||
SignalMessage::AuthToken { token } => token,
|
||||
other => panic!("expected AuthToken, got {:?}", std::mem::discriminant(&other)),
|
||||
other => panic!(
|
||||
"expected AuthToken, got {:?}",
|
||||
std::mem::discriminant(&other)
|
||||
),
|
||||
};
|
||||
|
||||
// 2. Run the cryptographic handshake
|
||||
let (session, profile, _caller_fp, _caller_alias) = accept_handshake(server_t.as_ref(), &callee_seed)
|
||||
.await
|
||||
.expect("accept_handshake after auth");
|
||||
let (session, profile, _caller_fp, _caller_alias) =
|
||||
accept_handshake(server_t.as_ref(), &callee_seed)
|
||||
.await
|
||||
.expect("accept_handshake after auth");
|
||||
|
||||
(token, session, profile)
|
||||
});
|
||||
@@ -203,9 +211,7 @@ async fn auth_then_handshake() {
|
||||
.await
|
||||
.expect("perform_handshake after auth");
|
||||
|
||||
let (received_token, callee_session, _profile) = callee_handle
|
||||
.await
|
||||
.expect("join callee task");
|
||||
let (received_token, callee_session, _profile) = callee_handle.await.expect("join callee task");
|
||||
|
||||
// Verify the auth token was received correctly.
|
||||
assert_eq!(received_token, "bearer-test-token-12345");
|
||||
@@ -246,9 +252,8 @@ async fn handshake_rejects_bad_signature() {
|
||||
|
||||
// Spawn callee -- it should reject the tampered CallOffer.
|
||||
let server_t = Arc::clone(&server_transport);
|
||||
let callee_handle = tokio::spawn(async move {
|
||||
accept_handshake(server_t.as_ref(), &callee_seed).await
|
||||
});
|
||||
let callee_handle =
|
||||
tokio::spawn(async move { accept_handshake(server_t.as_ref(), &callee_seed).await });
|
||||
|
||||
// Manually build a CallOffer with a corrupted signature.
|
||||
let mut kx = WarzoneKeyExchange::from_identity_seed(&caller_seed);
|
||||
|
||||
@@ -151,12 +151,13 @@ fn both_peers_advertise_reflex_addrs_cross_wire_in_setup() {
|
||||
);
|
||||
|
||||
let answer = mk_answer("c1", CallAcceptMode::AcceptTrusted, Some(callee_addr));
|
||||
let (setup_caller, setup_callee) =
|
||||
handle_answer_and_build_setups(&mut reg, &answer);
|
||||
let (setup_caller, setup_callee) = handle_answer_and_build_setups(&mut reg, &answer);
|
||||
|
||||
// The CALLER's setup should carry the CALLEE's addr as peer_direct_addr.
|
||||
match setup_caller {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
assert_eq!(
|
||||
peer_direct_addr.as_deref(),
|
||||
Some(callee_addr),
|
||||
@@ -168,7 +169,9 @@ fn both_peers_advertise_reflex_addrs_cross_wire_in_setup() {
|
||||
|
||||
// The CALLEE's setup should carry the CALLER's addr.
|
||||
match setup_callee {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
assert_eq!(
|
||||
peer_direct_addr.as_deref(),
|
||||
Some(caller_addr),
|
||||
@@ -193,12 +196,13 @@ fn privacy_mode_answer_omits_callee_addr_from_setup() {
|
||||
// AcceptGeneric explicitly passes None for callee_reflexive_addr —
|
||||
// the whole point is to hide the callee's IP from the caller.
|
||||
let answer = mk_answer("c2", CallAcceptMode::AcceptGeneric, None);
|
||||
let (setup_caller, setup_callee) =
|
||||
handle_answer_and_build_setups(&mut reg, &answer);
|
||||
let (setup_caller, setup_callee) = handle_answer_and_build_setups(&mut reg, &answer);
|
||||
|
||||
// CALLER should see peer_direct_addr = None (privacy preserved).
|
||||
match setup_caller {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
assert!(
|
||||
peer_direct_addr.is_none(),
|
||||
"privacy mode must not leak callee addr to caller"
|
||||
@@ -210,7 +214,9 @@ fn privacy_mode_answer_omits_callee_addr_from_setup() {
|
||||
// CALLEE still gets the caller's addr — only the callee opted for
|
||||
// privacy, the caller already volunteered its addr in the offer.
|
||||
match setup_callee {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
assert_eq!(
|
||||
peer_direct_addr.as_deref(),
|
||||
Some(caller_addr),
|
||||
@@ -242,11 +248,12 @@ fn pre_phase3_caller_leaves_both_setups_relay_only() {
|
||||
CallAcceptMode::AcceptTrusted,
|
||||
Some("198.51.100.9:4433"),
|
||||
);
|
||||
let (setup_caller, setup_callee) =
|
||||
handle_answer_and_build_setups(&mut reg, &answer);
|
||||
let (setup_caller, setup_callee) = handle_answer_and_build_setups(&mut reg, &answer);
|
||||
|
||||
match setup_caller {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
// Phase 3 relay behavior: we always inject whatever
|
||||
// addrs are in the registry, regardless of who
|
||||
// advertised. The caller here gets the callee's addr
|
||||
@@ -258,7 +265,9 @@ fn pre_phase3_caller_leaves_both_setups_relay_only() {
|
||||
|
||||
// The callee's setup has no caller addr (pre-Phase-3 offer).
|
||||
match setup_callee {
|
||||
SignalMessage::CallSetup { peer_direct_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr, ..
|
||||
} => {
|
||||
assert!(
|
||||
peer_direct_addr.is_none(),
|
||||
"callee should see no caller addr when offer was pre-Phase-3"
|
||||
@@ -278,12 +287,15 @@ fn neither_peer_advertises_both_setups_are_relay_only() {
|
||||
|
||||
handle_offer(&mut reg, &mk_offer("c4", None));
|
||||
let answer = mk_answer("c4", CallAcceptMode::AcceptTrusted, None);
|
||||
let (setup_caller, setup_callee) =
|
||||
handle_answer_and_build_setups(&mut reg, &answer);
|
||||
let (setup_caller, setup_callee) = handle_answer_and_build_setups(&mut reg, &answer);
|
||||
|
||||
for (label, setup) in [("caller", setup_caller), ("callee", setup_callee)] {
|
||||
match setup {
|
||||
SignalMessage::CallSetup { peer_direct_addr, relay_addr, .. } => {
|
||||
SignalMessage::CallSetup {
|
||||
peer_direct_addr,
|
||||
relay_addr,
|
||||
..
|
||||
} => {
|
||||
assert!(
|
||||
peer_direct_addr.is_none(),
|
||||
"{label}'s CallSetup must have no peer_direct_addr"
|
||||
|
||||
@@ -24,9 +24,9 @@ use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use wzp_client::reflect::{detect_nat_type, probe_reflect_addr, NatType};
|
||||
use wzp_client::reflect::{NatType, detect_nat_type, probe_reflect_addr};
|
||||
use wzp_proto::{MediaTransport, SignalMessage};
|
||||
use wzp_transport::{create_endpoint, server_config, QuinnTransport};
|
||||
use wzp_transport::{QuinnTransport, create_endpoint, server_config};
|
||||
|
||||
/// Minimal mock relay that loops accepting connections, handles
|
||||
/// RegisterPresence + Reflect, and responds correctly. Mirrors the
|
||||
@@ -136,10 +136,7 @@ async fn detect_nat_type_two_loopback_relays_probes_work_but_classify_unknown()
|
||||
let (addr_b, _h_b) = spawn_mock_relay().await;
|
||||
|
||||
let detection = detect_nat_type(
|
||||
vec![
|
||||
("RelayA".into(), addr_a),
|
||||
("RelayB".into(), addr_b),
|
||||
],
|
||||
vec![("RelayA".into(), addr_a), ("RelayB".into(), addr_b)],
|
||||
2000,
|
||||
None,
|
||||
)
|
||||
@@ -194,10 +191,7 @@ async fn detect_nat_type_dead_relay_is_unknown() {
|
||||
let dead_addr: SocketAddr = "127.0.0.1:1".parse().unwrap();
|
||||
|
||||
let detection = detect_nat_type(
|
||||
vec![
|
||||
("Alive".into(), alive_addr),
|
||||
("Dead".into(), dead_addr),
|
||||
],
|
||||
vec![("Alive".into(), alive_addr), ("Dead".into(), dead_addr)],
|
||||
600, // tight timeout so the dead probe fails fast
|
||||
None,
|
||||
)
|
||||
@@ -207,8 +201,16 @@ async fn detect_nat_type_dead_relay_is_unknown() {
|
||||
|
||||
// Find the alive and dead probes by name (order of JoinSet
|
||||
// completions is not guaranteed).
|
||||
let alive = detection.probes.iter().find(|p| p.relay_name == "Alive").unwrap();
|
||||
let dead = detection.probes.iter().find(|p| p.relay_name == "Dead").unwrap();
|
||||
let alive = detection
|
||||
.probes
|
||||
.iter()
|
||||
.find(|p| p.relay_name == "Alive")
|
||||
.unwrap();
|
||||
let dead = detection
|
||||
.probes
|
||||
.iter()
|
||||
.find(|p| p.relay_name == "Dead")
|
||||
.unwrap();
|
||||
|
||||
assert!(
|
||||
alive.observed_addr.is_some(),
|
||||
|
||||
@@ -31,7 +31,7 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use wzp_proto::{MediaTransport, SignalMessage};
|
||||
use wzp_transport::{client_config, create_endpoint, server_config, QuinnTransport};
|
||||
use wzp_transport::{QuinnTransport, client_config, create_endpoint, server_config};
|
||||
|
||||
/// Spawn a minimal mock relay that loops over `recv_signal`,
|
||||
/// matches on `Reflect`, and responds with `ReflectResponse` using
|
||||
@@ -94,7 +94,11 @@ async fn spawn_mock_relay_without_reflect(
|
||||
/// distinct-ports test).
|
||||
async fn connected_pair_with_port(
|
||||
_client_port_hint: u16,
|
||||
) -> (Arc<QuinnTransport>, Arc<QuinnTransport>, (quinn::Endpoint, quinn::Endpoint)) {
|
||||
) -> (
|
||||
Arc<QuinnTransport>,
|
||||
Arc<QuinnTransport>,
|
||||
(quinn::Endpoint, quinn::Endpoint),
|
||||
) {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
|
||||
let (sc, _cert_der) = server_config();
|
||||
@@ -109,7 +113,9 @@ async fn connected_pair_with_port(
|
||||
|
||||
let server_ep_clone = server_ep.clone();
|
||||
let accept_fut = tokio::spawn(async move {
|
||||
let conn = wzp_transport::accept(&server_ep_clone).await.expect("accept");
|
||||
let conn = wzp_transport::accept(&server_ep_clone)
|
||||
.await
|
||||
.expect("accept");
|
||||
Arc::new(QuinnTransport::new(conn))
|
||||
});
|
||||
|
||||
@@ -134,10 +140,7 @@ async fn reflect_happy_path() {
|
||||
|
||||
// Grab the client's actual bound port so we can cross-check
|
||||
// against the reflected response.
|
||||
let client_port = client_ep
|
||||
.local_addr()
|
||||
.expect("client local addr")
|
||||
.port();
|
||||
let client_port = client_ep.local_addr().expect("client local addr").port();
|
||||
assert_ne!(client_port, 0, "client must have a real bound port");
|
||||
|
||||
// Start the mock relay's reflect handler.
|
||||
@@ -162,7 +165,10 @@ async fn reflect_happy_path() {
|
||||
|
||||
let observed_addr = match resp {
|
||||
SignalMessage::ReflectResponse { observed_addr } => observed_addr,
|
||||
other => panic!("expected ReflectResponse, got {:?}", std::mem::discriminant(&other)),
|
||||
other => panic!(
|
||||
"expected ReflectResponse, got {:?}",
|
||||
std::mem::discriminant(&other)
|
||||
),
|
||||
};
|
||||
|
||||
let parsed: SocketAddr = observed_addr
|
||||
@@ -210,19 +216,17 @@ async fn reflect_two_clients_distinct_ports() {
|
||||
|
||||
// Client A
|
||||
let client_ep_a = create_endpoint((Ipv4Addr::LOCALHOST, 0).into(), None).expect("ep A");
|
||||
let conn_a =
|
||||
wzp_transport::connect(&client_ep_a, server_listen, "localhost", client_config())
|
||||
.await
|
||||
.expect("connect A");
|
||||
let conn_a = wzp_transport::connect(&client_ep_a, server_listen, "localhost", client_config())
|
||||
.await
|
||||
.expect("connect A");
|
||||
let client_a = Arc::new(QuinnTransport::new(conn_a));
|
||||
let port_a = client_ep_a.local_addr().unwrap().port();
|
||||
|
||||
// Client B
|
||||
let client_ep_b = create_endpoint((Ipv4Addr::LOCALHOST, 0).into(), None).expect("ep B");
|
||||
let conn_b =
|
||||
wzp_transport::connect(&client_ep_b, server_listen, "localhost", client_config())
|
||||
.await
|
||||
.expect("connect B");
|
||||
let conn_b = wzp_transport::connect(&client_ep_b, server_listen, "localhost", client_config())
|
||||
.await
|
||||
.expect("connect B");
|
||||
let client_b = Arc::new(QuinnTransport::new(conn_b));
|
||||
let port_b = client_ep_b.local_addr().unwrap().port();
|
||||
|
||||
@@ -252,7 +256,8 @@ async fn reflect_two_clients_distinct_ports() {
|
||||
}
|
||||
};
|
||||
|
||||
let (addr_a, addr_b) = tokio::join!(reflect_for(client_a.clone()), reflect_for(client_b.clone()));
|
||||
let (addr_a, addr_b) =
|
||||
tokio::join!(reflect_for(client_a.clone()), reflect_for(client_b.clone()));
|
||||
|
||||
let parsed_a: SocketAddr = addr_a.parse().unwrap();
|
||||
let parsed_b: SocketAddr = addr_b.parse().unwrap();
|
||||
@@ -277,12 +282,10 @@ async fn reflect_two_clients_distinct_ports() {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn reflect_old_relay_times_out() {
|
||||
let (client_transport, server_transport, _endpoints) =
|
||||
connected_pair_with_port(0).await;
|
||||
let (client_transport, server_transport, _endpoints) = connected_pair_with_port(0).await;
|
||||
|
||||
// Mock relay that ignores Reflect — simulates a pre-Phase-1 build.
|
||||
let _relay_handle =
|
||||
spawn_mock_relay_without_reflect(Arc::clone(&server_transport)).await;
|
||||
let _relay_handle = spawn_mock_relay_without_reflect(Arc::clone(&server_transport)).await;
|
||||
|
||||
client_transport
|
||||
.send_signal(&SignalMessage::Reflect)
|
||||
|
||||
Reference in New Issue
Block a user