udp.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. /// # Examples
  8. ///
  9. /// ```no_run
  10. /// use dns_transport::{Transport, UdpTransport};
  11. /// use dns::{Request, Flags, Query, Labels, QClass, qtype, record::NS};
  12. ///
  13. /// let query = Query {
  14. /// qname: Labels::encode("dns.lookup.dog").unwrap(),
  15. /// qclass: QClass::IN,
  16. /// qtype: qtype!(NS),
  17. /// };
  18. ///
  19. /// let request = Request {
  20. /// transaction_id: 0xABCD,
  21. /// flags: Flags::query(),
  22. /// query: query,
  23. /// additional: None,
  24. /// };
  25. ///
  26. /// let transport = UdpTransport::new("8.8.8.8");
  27. /// transport.send(&request);
  28. /// ```
  29. pub struct UdpTransport {
  30. addr: String,
  31. }
  32. impl UdpTransport {
  33. /// Creates a new UDP transport that connects to the given host.
  34. pub fn new(sa: impl Into<String>) -> Self {
  35. let addr = sa.into();
  36. Self { addr }
  37. }
  38. }
  39. impl Transport for UdpTransport {
  40. fn send(&self, request: &Request) -> Result<Response, Error> {
  41. info!("Opening UDP socket");
  42. // TODO: This will need to be changed for IPv6 support.
  43. let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0))?;
  44. if self.addr.contains(':') {
  45. socket.connect(&*self.addr)?;
  46. }
  47. else {
  48. socket.connect((&*self.addr, 53))?;
  49. }
  50. debug!("Opened");
  51. let bytes_to_send = request.to_bytes().expect("failed to serialise request");
  52. info!("Sending {} bytes of data to {} over UDP", bytes_to_send.len(), self.addr);
  53. let written_len = socket.send(&bytes_to_send)?;
  54. debug!("Wrote {} bytes", written_len);
  55. info!("Waiting to receive...");
  56. let mut buf = vec![0; 4096];
  57. let received_len = socket.recv(&mut buf)?;
  58. info!("Received {} bytes of data", received_len);
  59. let response = Response::from_bytes(&buf[.. received_len])?;
  60. Ok(response)
  61. }
  62. }