From 693f1095372ecc46d30eea6b864d90b29a7c3c3b Mon Sep 17 00:00:00 2001 From: dandyvica Date: Tue, 14 Jan 2025 20:36:56 +0100 Subject: [PATCH] fixed bug no stats in DoQ --- src/args.rs | 5 ++++- src/main.rs | 23 +++++++++++++++-------- src/protocol.rs | 18 ++++++++---------- src/transport/https.rs | 4 ++++ src/transport/network.rs | 3 +++ src/transport/quic.rs | 36 +++++++++++++++++++++--------------- src/transport/tcp.rs | 4 ++++ src/transport/tls.rs | 4 ++++ src/transport/udp.rs | 4 ++++ 9 files changed, 67 insertions(+), 34 deletions(-) diff --git a/src/args.rs b/src/args.rs index c64bccd..12a22fd 100644 --- a/src/args.rs +++ b/src/args.rs @@ -146,7 +146,10 @@ Project home page: https://github.com/dandyvica/dqy"#, let usage = format!( r#"dqy [TYPES] [DOMAIN] [@RESOLVER] [OPTIONS] -Caveat: all options starting with a dash (-) should be placed after optional [TYPES] [DOMAIN] [@RESOLVER]. +Caveats: + + - all options starting with a dash (-) should be placed after optional [TYPES] [DOMAIN] [@RESOLVER]. + - whenever you enter a domain name, it must ends with the root (.). E.g.: fr. or mx. Supported query types: {} "#, diff --git a/src/main.rs b/src/main.rs index 74d4027..56fc0b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ mod transport; use transport::{ https::HttpsProtocol, network::{Messenger, Protocol}, + quic::QuicProtocol, root_servers::init_root_map, tcp::TcpProtocol, tls::TlsProtocol, @@ -54,15 +55,15 @@ use lua::LuaDisplay; const BUFFER_SIZE: usize = 8192; //─────────────────────────────────────────────────────────────────────────────────── -// get list of messages using transport +// get list of messages using transport: sync mode //─────────────────────────────────────────────────────────────────────────────────── -fn get_messages_using_transport( +fn get_messages_using_sync_transport( info: Option<&mut QueryInfo>, transport: &mut T, options: &CliOptions, ) -> error::Result { // BUFFER_SIZE is the size of the buffer used to received data - let messages = DnsProtocol::process_request(options, transport, BUFFER_SIZE)?; + let messages = DnsProtocol::sync_process_request(options, transport, BUFFER_SIZE)?; // we want run info if let Some(info) = info { @@ -83,19 +84,19 @@ pub fn get_messages(info: Option<&mut QueryInfo>, options: &CliOptions) -> error match options.transport.transport_mode { Protocol::Udp => { let mut transport = UdpProtocol::new(&options.transport)?; - get_messages_using_transport(info, &mut transport, options) + get_messages_using_sync_transport(info, &mut transport, options) } Protocol::Tcp => { let mut transport = TcpProtocol::new(&options.transport)?; - get_messages_using_transport(info, &mut transport, options) + get_messages_using_sync_transport(info, &mut transport, options) } Protocol::DoT => { let mut transport = TlsProtocol::new(&options.transport)?; - get_messages_using_transport(info, &mut transport, options) + get_messages_using_sync_transport(info, &mut transport, options) } Protocol::DoH => { let mut transport = HttpsProtocol::new(&options.transport)?; - get_messages_using_transport(info, &mut transport, options) + get_messages_using_sync_transport(info, &mut transport, options) } Protocol::DoQ => { // quinn crate doesn't provide blocking @@ -105,7 +106,13 @@ pub fn get_messages(info: Option<&mut QueryInfo>, options: &CliOptions) -> error .map_err(Error::Tokio)?; rt.block_on(async { - let messages = DnsProtocol::quic_process_request(options, BUFFER_SIZE).await?; + let mut transport = QuicProtocol::new(&options.transport).await?; + let messages = DnsProtocol::async_process_request(options, &mut transport, BUFFER_SIZE).await?; + + // we want run info + if let Some(info) = info { + info.netinfo = *transport.network_info(); + } Ok(messages) }) } diff --git a/src/protocol.rs b/src/protocol.rs index 8bf65b0..99def6b 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -8,7 +8,6 @@ use crate::dns::{ }; use crate::error::{self}; use crate::transport::network::{Messenger, Protocol}; -use crate::transport::quic::QuicProtocol; use crate::transport::tcp::TcpProtocol; use crate::{args::CliOptions, cli_options::FromOptions}; @@ -93,9 +92,9 @@ impl DnsProtocol { } //─────────────────────────────────────────────────────────────────────────────────── - // this sends and receives queries using a transport + // this sends and receives queries using a sync transport //─────────────────────────────────────────────────────────────────────────────────── - pub(crate) fn process_request( + pub(crate) fn sync_process_request( options: &CliOptions, trp: &mut T, buffer_size: usize, @@ -132,25 +131,24 @@ impl DnsProtocol { } //─────────────────────────────────────────────────────────────────────────────────── - // specific to QUIC + // this sends and receives queries using an async transport //─────────────────────────────────────────────────────────────────────────────────── - pub(crate) async fn quic_process_request( + pub(crate) async fn async_process_request( options: &CliOptions, + trp: &mut T, buffer_size: usize, ) -> crate::error::Result { // we'll have the same number of messages than the number of types to query let mut messages = Vec::with_capacity(options.protocol.qtype.len()); let mut buffer = vec![0u8; buffer_size]; - let mut trp = QuicProtocol::new(&options.transport).await?; - for qtype in options.protocol.qtype.iter() { // for QUIC, we need a specific stream for each query as stated in https://www.rfc-editor.org/rfc/rfc9250.html - trp.connect().await?; + trp.aconnect().await?; // send query, response is depending on TC flag if UDP - let query = Self::asend_query(options, qtype, &mut trp).await?; - let response = Self::areceive_response(&mut trp, &mut buffer, &options.dump.write_response).await?; + let query = Self::asend_query(options, qtype, trp).await?; + let response = Self::areceive_response(trp, &mut buffer, &options.dump.write_response).await?; // struct Message is a convenient way to gather both query and response let msg = Message { query, response }; diff --git a/src/transport/https.rs b/src/transport/https.rs index ae6f79e..b123da0 100644 --- a/src/transport/https.rs +++ b/src/transport/https.rs @@ -100,6 +100,10 @@ impl<'a> Messenger for HttpsProtocol<'a> { Ok(0) } + async fn aconnect(&mut self) -> error::Result<()> { + Ok(()) + } + fn send(&mut self, buffer: &[u8]) -> crate::error::Result { self.netinfo.sent = buffer.len(); diff --git a/src/transport/network.rs b/src/transport/network.rs index e7e5e45..65cc45e 100644 --- a/src/transport/network.rs +++ b/src/transport/network.rs @@ -106,6 +106,9 @@ pub trait Messenger { // async version async fn arecv(&mut self, buffer: &mut [u8]) -> error::Result; + // async connect used by QUIC + async fn aconnect(&mut self) -> error::Result<()>; + // true if transporter uses Tcp. This is required for TCP transport to have 2 bytes // for the message length prepended in the query fn uses_leading_length(&self) -> bool; diff --git a/src/transport/quic.rs b/src/transport/quic.rs index 76bb3e5..482742c 100644 --- a/src/transport/quic.rs +++ b/src/transport/quic.rs @@ -59,29 +59,21 @@ impl QuicProtocol { .map_err(|e| Error::Quic(QuicError::Connection(e)))?; debug!("conn: {:?}", conn); + let addr = conn.remote_address(); + Ok(Self { handle: QuicConn { conn, send: None, recv: None, }, - netinfo: NetworkInfo::default(), + netinfo: NetworkInfo { + sent: 0, + received: 0, + peer: Some(addr), + }, }) } - - pub async fn connect(&mut self) -> Result<()> { - let (send, recv) = self - .handle - .conn - .open_bi() - .await - .map_err(|e| Error::Quic(QuicError::Connection(e)))?; - - self.handle.send = Some(send); - self.handle.recv = Some(recv); - - Ok(()) - } } impl Messenger for QuicProtocol { @@ -130,6 +122,20 @@ impl Messenger for QuicProtocol { Ok(length) } + async fn aconnect(&mut self) -> Result<()> { + let (send, recv) = self + .handle + .conn + .open_bi() + .await + .map_err(|e| Error::Quic(QuicError::Connection(e)))?; + + self.handle.send = Some(send); + self.handle.recv = Some(recv); + + Ok(()) + } + fn uses_leading_length(&self) -> bool { true } diff --git a/src/transport/tcp.rs b/src/transport/tcp.rs index 8056a36..ced46ca 100644 --- a/src/transport/tcp.rs +++ b/src/transport/tcp.rs @@ -44,6 +44,10 @@ impl Messenger for TcpProtocol { Ok(0) } + async fn aconnect(&mut self) -> error::Result<()> { + Ok(()) + } + fn send(&mut self, buffer: &[u8]) -> Result { self.netinfo.sent = self.handle.write(buffer).map_err(crate::error::Error::Buffer)?; self.handle.flush().map_err(crate::error::Error::Buffer)?; diff --git a/src/transport/tls.rs b/src/transport/tls.rs index d9aca42..f60a0d6 100644 --- a/src/transport/tls.rs +++ b/src/transport/tls.rs @@ -83,6 +83,10 @@ impl Messenger for TlsProtocol { Ok(0) } + async fn aconnect(&mut self) -> error::Result<()> { + Ok(()) + } + fn send(&mut self, buffer: &[u8]) -> Result { self.netinfo.sent = self .handle diff --git a/src/transport/udp.rs b/src/transport/udp.rs index 5bc0fd0..e12efbe 100644 --- a/src/transport/udp.rs +++ b/src/transport/udp.rs @@ -66,6 +66,10 @@ impl Messenger for UdpProtocol { Ok(0) } + async fn aconnect(&mut self) -> error::Result<()> { + Ok(()) + } + fn send(&mut self, buffer: &[u8]) -> Result { self.netinfo.sent = self.handle.send(buffer).map_err(|e| Error::Network(e, Network::Send))?; debug!("sent {} bytes", self.netinfo.sent);