auto.rs 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. use log::*;
  2. use dns::{Request, Response};
  3. use super::{Transport, Error, UdpTransport, TcpTransport};
  4. /// The **automatic transport**, which sends DNS wire data using the UDP
  5. /// transport, then tries using the TCP transport if the first one fails
  6. /// because the response wouldn’t fit in a single UDP packet.
  7. ///
  8. /// This is the default behaviour for many DNS clients.
  9. pub struct AutoTransport {
  10. addr: String,
  11. }
  12. impl AutoTransport {
  13. /// Creates a new automatic transport that connects to the given host.
  14. pub fn new(sa: impl Into<String>) -> Self {
  15. let addr = sa.into();
  16. Self { addr }
  17. }
  18. }
  19. impl Transport for AutoTransport {
  20. fn send(&self, request: &Request) -> Result<Response, Error> {
  21. let udp_transport = UdpTransport::new(&self.addr);
  22. let udp_response = udp_transport.send(&request)?;
  23. if ! udp_response.flags.truncated {
  24. return Ok(udp_response);
  25. }
  26. debug!("Truncated flag set, so switching to TCP");
  27. let tcp_transport = TcpTransport::new(&self.addr);
  28. let tcp_response = tcp_transport.send(&request)?;
  29. Ok(tcp_response)
  30. }
  31. }