From f43ee3e9583087e081844fde0811f5ff457fe72f Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Sun, 8 Nov 2020 02:50:42 +0800 Subject: [PATCH] Test UDP connectivity with firefox.com DNS query --- src/relay/loadbalancing/server.rs | 26 ++++++++++++++++++++++++-- tests/tunnel.rs | 31 ++++++++++++------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/relay/loadbalancing/server.rs b/src/relay/loadbalancing/server.rs index 42b6b88f..9fd39861 100644 --- a/src/relay/loadbalancing/server.rs +++ b/src/relay/loadbalancing/server.rs @@ -525,13 +525,35 @@ impl PingBalancer { } async fn check_request_udp(stat: &ServerStatistic) -> io::Result<()> { - static DNS_QUERY: &[u8] = b"\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x05\x62\x61\x69\x64\x75\x03\x63\x6f\x6d\x00\x00\x01\x00\x01"; + // TransactionID: 0x1234 + // Flags: 0x0100 RD + // Questions: 0x0001 + // Answer RRs: 0x0000 + // Authority RRs: 0x0000 + // Additional RRs: 0x0000 + // Queries + // - QNAME: \x07 firefox \x03 com \x00 + // - QTYPE: 0x0001 A + // - QCLASS: 0x0001 IN + static DNS_QUERY: &[u8] = + b"\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07firefox\x03com\x00\x00\x01\x00\x01"; let addr = Address::SocketAddress(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53)); let client = UdpServerClient::new(stat.context(), stat.server_config()).await?; client.send_to(stat.context(), &addr, DNS_QUERY).await?; - let _ = client.recv_from(stat.context()).await?; + + let (_, dns_answer) = client.recv_from(stat.context()).await?; + + // DNS packet must have at least 6 * 2 bytes + if dns_answer.len() < 12 || &dns_answer[0..2] != b"\x12\x34" { + use std::io::{Error, ErrorKind}; + + debug!("unexpected response from 8.8.8.8:53, {:?}", ByteStr::new(&dns_answer)); + + let err = Error::new(ErrorKind::InvalidData, "unexpected response from 8.8.8.8:53"); + return Err(err); + } Ok(()) } diff --git a/tests/tunnel.rs b/tests/tunnel.rs index b897a9f9..fae61752 100644 --- a/tests/tunnel.rs +++ b/tests/tunnel.rs @@ -2,6 +2,7 @@ use std::str; +use byte_string::ByteStr; use tokio::{ self, net::{TcpStream, UdpSocket}, @@ -69,6 +70,9 @@ async fn tcp_tunnel() { #[tokio::test] async fn udp_tunnel() { + // Query firefox.com, TransactionID: 0x1234 + static DNS_QUERY: &[u8] = b"\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07firefox\x03com\x00\x00\x01\x00\x01"; + let _ = env_logger::try_init(); let mut local_config = Config::load_from_str( @@ -85,7 +89,7 @@ async fn udp_tunnel() { ) .unwrap(); - local_config.forward = Some("127.0.0.1:9230".parse::
().unwrap()); + local_config.forward = Some("8.8.8.8:53".parse::
().unwrap()); let server_config = Config::load_from_str( r#"{ @@ -102,30 +106,19 @@ async fn udp_tunnel() { tokio::spawn(run_local(local_config)); tokio::spawn(run_server(server_config)); - // Start a UDP echo server - tokio::spawn(async { - let socket = UdpSocket::bind("127.0.0.1:9230").await.unwrap(); - - let mut buf = vec![0u8; 65536]; - let (n, src) = socket.recv_from(&mut buf).await.unwrap(); - - println!("UDP Echo server received packet, size: {}, src: {}", n, src); - - socket.send_to(&buf[..n], src).await.unwrap(); - }); - time::sleep(Duration::from_secs(1)).await; - let payload = b"HELLO WORLD"; - let socket = UdpSocket::bind("0.0.0.0:0").await.unwrap(); - socket.send_to(payload, "127.0.0.1:9210").await.unwrap(); + socket.send_to(DNS_QUERY, "127.0.0.1:9210").await.unwrap(); let mut buf = vec![0u8; 65536]; let n = socket.recv(&mut buf).await.unwrap(); - let recv_payload = &buf[..n]; - println!("Got reply from server: {}", str::from_utf8(recv_payload).unwrap()); + // DNS response have at least 12 bytes + assert!(n >= 12); - assert_eq!(recv_payload, payload); + let recv_payload = &buf[..n]; + println!("Got reply from server: {:?}", ByteStr::new(&recv_payload)); + + assert_eq!(b"\x12\x34", &recv_payload[0..2]); }