#[macro_use]
extern crate log;
mod server_harness;
use std::io::Write;
use std::net::*;
use std::str::FromStr;
use tokio::net::TcpStream as TokioTcpStream;
use tokio::net::UdpSocket as TokioUdpSocket;
use tokio::runtime::Runtime;
use trust_dns_client::client::*;
use trust_dns_client::op::ResponseCode;
use trust_dns_client::rr::*;
use trust_dns_client::tcp::TcpClientStream;
use trust_dns_client::udp::UdpClientStream;
use server_harness::{named_test_harness, query_a};
use trust_dns_proto::iocompat::AsyncIoTokioAsStd;
#[test]
fn test_example_toml_startup() {
named_test_harness("example.toml", |_, tcp_port, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
})
}
#[test]
fn test_ipv4_only_toml_startup() {
named_test_harness("ipv4_only.toml", |_, tcp_port, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
let addr: SocketAddr = SocketAddr::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
assert!(io_loop.block_on(client).is_err());
})
}
#[ignore]
#[test]
fn test_ipv4_and_ipv6_toml_startup() {
named_test_harness("ipv4_and_ipv6.toml", |_, tcp_port, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
let addr: SocketAddr = SocketAddr::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
})
}
#[test]
fn test_nodata_where_name_exists() {
named_test_harness("example.toml", |_, tcp_port, _, _| {
let io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
let msg = io_loop
.block_on(client.query(
Name::from_str("www.example.com.").unwrap(),
DNSClass::IN,
RecordType::SRV,
))
.unwrap();
assert_eq!(msg.response_code(), ResponseCode::NoError);
assert!(msg.answers().is_empty());
})
}
#[test]
fn test_nxdomain_where_no_name_exists() {
named_test_harness("example.toml", |_, tcp_port, _, _| {
let io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
let msg = io_loop
.block_on(client.query(
Name::from_str("nxdomain.example.com.").unwrap(),
DNSClass::IN,
RecordType::SRV,
))
.unwrap();
assert_eq!(msg.response_code(), ResponseCode::NXDomain);
assert!(msg.answers().is_empty());
})
}
#[test]
fn test_server_continues_on_bad_data_udp() {
named_test_harness("example.toml", |udp_port, _, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
udp_port.expect("no udp_port"),
);
let stream = UdpClientStream::<TokioUdpSocket>::new(addr);
let client = AsyncClient::connect(stream);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
let raw_socket = UdpSocket::bind(SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0))
.expect("couldn't bind raw");
raw_socket
.send_to(b"0xDEADBEEF", addr)
.expect("raw send failed");
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
udp_port.expect("no udp_port"),
);
let stream = UdpClientStream::<TokioUdpSocket>::new(addr);
let client = AsyncClient::connect(stream);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
})
}
#[test]
fn test_server_continues_on_bad_data_tcp() {
named_test_harness("example.toml", |_, tcp_port, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
let mut raw_socket = TcpStream::connect(addr).expect("couldn't bind raw");
raw_socket
.write_all(b"0xDEADBEEF")
.expect("raw send failed");
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
query_a(&mut io_loop, &mut client);
})
}
#[test]
#[cfg(feature = "resolver")]
fn test_forward() {
use server_harness::query_message;
named_test_harness("example_forwarder.toml", |_, tcp_port, _, _| {
let mut io_loop = Runtime::new().unwrap();
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
let response = query_message(
&mut io_loop,
&mut client,
Name::from_str("www.example.com").unwrap(),
RecordType::A,
);
assert_eq!(
*response.answers()[0].rdata().as_a().unwrap(),
Ipv4Addr::new(93, 184, 216, 34)
);
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
trust_dns_proto::spawn_bg(&io_loop, bg);
let response = query_message(
&mut io_loop,
&mut client,
Name::from_str("www.example.com").unwrap(),
RecordType::A,
);
assert_eq!(
*response.answers()[0].rdata().as_a().unwrap(),
Ipv4Addr::new(93, 184, 216, 34)
);
})
}