//! Verifies the client dialer's handover: when an earlier transport in the order is unreachable, //! `dial` moves on to the next and connects. use std::net::SocketAddr; use std::time::Duration; use aura_pki::AuraCa; use aura_proto::{ClientConfig, PacketConnection, ServerConfig}; use aura_transport::{dial, DialConfig, Endpoints, TcpOpts, TransportMode, UdpOpts, UdpServer}; 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 ca_pem = ca.ca_cert_pem(); ( ServerConfig { ca_cert_pem: ca_pem.clone(), server_cert_pem: server.cert_pem, server_key_pem: server.key_pem, }, ClientConfig { ca_cert_pem: ca_pem, client_cert_pem: client.cert_pem, client_key_pem: client.key_pem, server_name: "localhost".to_string(), }, ) } #[tokio::test] 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_addr = udp_server.local_addr().expect("udp addr"); let srv = tokio::spawn(async move { let conn = udp_server.accept().await.expect("server accept"); let p = conn.recv_packet().await.expect("server recv"); conn.send_packet(&p).await.expect("server echo"); }); // Port 1 on loopback has nothing listening → TCP connect is refused fast. let dead_tcp: SocketAddr = "127.0.0.1:1".parse().unwrap(); let cfg = DialConfig { endpoints: Endpoints { udp: Some(udp_addr), tcp: Some(dead_tcp), quic: None, }, sni: "cdn.example.com".to_string(), // Deliberately try the (dead) TCP first to force the handover to UDP. order: vec![TransportMode::Tcp, TransportMode::Udp], udp: UdpOpts::default(), tcp: TcpOpts::default(), attempt_timeout: Duration::from_secs(3), }; let (conn, mode) = dial(ccfg, cfg).await.expect("dial should fall back to UDP"); assert_eq!( mode, TransportMode::Udp, "must hand over to UDP after TCP is refused" ); conn.send_packet(b"hello-fallback").await.expect("send"); let echoed = conn.recv_packet().await.expect("recv"); assert_eq!(echoed, b"hello-fallback"); srv.await.expect("server task"); }