1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- use std::net::{Ipv4Addr, UdpSocket};
- use log::*;
- use dns::{Request, Response};
- use super::{Transport, Error};
- /// The **UDP transport**, which sends DNS wire data inside a UDP datagram.
- ///
- /// # References
- ///
- /// - [RFC 1035 §4.2.1](https://tools.ietf.org/html/rfc1035) — Domain Names,
- /// Implementation and Specification (November 1987)
- pub struct UdpTransport {
- addr: String,
- }
- impl UdpTransport {
- /// Creates a new UDP transport that connects to the given host.
- pub fn new(addr: String) -> Self {
- Self { addr }
- }
- }
- impl Transport for UdpTransport {
- fn send(&self, request: &Request) -> Result<Response, Error> {
- info!("Opening UDP socket");
- // TODO: This will need to be changed for IPv6 support.
- let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0))?;
- if self.addr.contains(':') {
- socket.connect(&*self.addr)?;
- }
- else {
- socket.connect((&*self.addr, 53))?;
- }
- debug!("Opened");
- let bytes_to_send = request.to_bytes().expect("failed to serialise request");
- info!("Sending {} bytes of data to {} over UDP", bytes_to_send.len(), self.addr);
- let written_len = socket.send(&bytes_to_send)?;
- debug!("Wrote {} bytes", written_len);
- info!("Waiting to receive...");
- let mut buf = vec![0; 4096];
- let received_len = socket.recv(&mut buf)?;
- info!("Received {} bytes of data", received_len);
- let response = Response::from_bytes(&buf[.. received_len])?;
- Ok(response)
- }
- }
|