udp.rs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. use std::net::{Ipv4Addr, UdpSocket};
  2. use log::*;
  3. use dns::{Request, Response};
  4. use super::{Transport, Error};
  5. /// The **UDP transport**, which sends DNS wire data inside a UDP datagram.
  6. ///
  7. /// # References
  8. ///
  9. /// - [RFC 1035 §4.2.1](https://tools.ietf.org/html/rfc1035) — Domain Names,
  10. /// Implementation and Specification (November 1987)
  11. pub struct UdpTransport {
  12. addr: String,
  13. }
  14. impl UdpTransport {
  15. /// Creates a new UDP transport that connects to the given host.
  16. pub fn new(addr: String) -> Self {
  17. Self { addr }
  18. }
  19. }
  20. impl Transport for UdpTransport {
  21. fn send(&self, request: &Request) -> Result<Response, Error> {
  22. info!("Opening UDP socket");
  23. // TODO: This will need to be changed for IPv6 support.
  24. let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0))?;
  25. if self.addr.contains(':') {
  26. socket.connect(&*self.addr)?;
  27. }
  28. else {
  29. socket.connect((&*self.addr, 53))?;
  30. }
  31. debug!("Opened");
  32. let bytes_to_send = request.to_bytes().expect("failed to serialise request");
  33. info!("Sending {} bytes of data to {} over UDP", bytes_to_send.len(), self.addr);
  34. let written_len = socket.send(&bytes_to_send)?;
  35. debug!("Wrote {} bytes", written_len);
  36. info!("Waiting to receive...");
  37. let mut buf = vec![0; 4096];
  38. let received_len = socket.recv(&mut buf)?;
  39. info!("Received {} bytes of data", received_len);
  40. let response = Response::from_bytes(&buf[.. received_len])?;
  41. Ok(response)
  42. }
  43. }