mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
Test UDP connectivity with firefox.com DNS query
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user