Test UDP connectivity with firefox.com DNS query

This commit is contained in:
zonyitoo
2020-11-08 02:50:42 +08:00
committed by ty
parent 6ca52c6d60
commit f43ee3e958
2 changed files with 36 additions and 21 deletions

View File

@@ -525,13 +525,35 @@ impl<S: ServerData + 'static> PingBalancer<S> {
}
async fn check_request_udp(stat: &ServerStatistic<S>) -> 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(())
}

View File

@@ -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::<Address>().unwrap());
local_config.forward = Some("8.8.8.8:53".parse::<Address>().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]);
}