use std::net::{IpAddr, Ipv4Addr, SocketAddrV4}; use hickory_resolver::config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts}; use hickory_resolver::error::ResolveErrorKind; use hickory_resolver::proto::op::ResponseCode; use hickory_resolver::AsyncResolver; use tokio::net::UdpSocket; use dns_mock_server::Server; type Result = std::result::Result>; #[tokio::test] async fn can_query_dns_records_from_the_server() -> Result<()> { let expected_addr = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); let mut server = Server::default(); server.add_records("www.example.com.", vec![expected_addr])?; let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0); let socket = UdpSocket::bind(&addr).await?; let local_addr = socket.local_addr()?; tokio::spawn(async move { server.start(socket).await.unwrap(); }); let mut config = ResolverConfig::new(); let nameserver_config = NameServerConfig::new(local_addr, Protocol::Udp); config.add_name_server(nameserver_config); let resolver = AsyncResolver::tokio(config, ResolverOpts::default()); let result = resolver.lookup_ip("www.example.com.").await?; let addrs: Vec<_> = result.into_iter().collect(); assert_eq!(addrs.len(), 1); assert_eq!(addrs[0], expected_addr); Ok(()) } #[tokio::test] async fn unknown_names_return_errors() -> Result<()> { let server = Server::default(); let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0); let socket = UdpSocket::bind(&addr).await?; let local_addr = socket.local_addr()?; tokio::spawn(async move { server.start(socket).await.unwrap(); }); let mut config = ResolverConfig::new(); let nameserver_config = NameServerConfig::new(local_addr, Protocol::Udp); config.add_name_server(nameserver_config); let resolver = AsyncResolver::tokio(config, ResolverOpts::default()); let Err(err) = resolver.lookup_ip("www.example.com.").await else { return Err("got successful response back".into()); }; let ResolveErrorKind::NoRecordsFound { response_code, .. } = err.kind() else { return Err("got unexpected error kind back".into()); }; assert_eq!(*response_code, ResponseCode::ServFail); Ok(()) }