use log::*; use dns::{Request, Response}; use super::{Transport, Error, UdpTransport, TcpTransport}; /// The **automatic transport**, which sends DNS wire data using the UDP /// transport, then tries using the TCP transport if the first one fails /// because the response wouldn’t fit in a single UDP packet. /// /// This is the default behaviour for many DNS clients. pub struct AutoTransport { addr: String, } impl AutoTransport { /// Creates a new automatic transport that connects to the given host. pub fn new(sa: impl Into<String>) -> Self { let addr = sa.into(); Self { addr } } } impl Transport for AutoTransport { fn send(&self, request: &Request) -> Result<Response, Error> { let udp_transport = UdpTransport::new(&self.addr); let udp_response = udp_transport.send(&request)?; if ! udp_response.flags.truncated { return Ok(udp_response); } debug!("Truncated flag set, so switching to TCP"); let tcp_transport = TcpTransport::new(&self.addr); let tcp_response = tcp_transport.send(&request)?; Ok(tcp_response) } }