refactor to async tokio with modular architecture

- Replace synchronous std::net::UdpSocket with tokio async runtime
- Spawn concurrent task per incoming DNS query via tokio::spawn
- Extract monolithic main.rs into modules: buffer, header, question,
  record, packet, config, cache, forward, stats
- Share state across tasks via Arc<ServerCtx> with scoped Mutex locks
- Add TOML config loading, TTL-aware cache, structured logging, stats
- Add CLAUDE.md, README, dns_fun.toml config, and design docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Razvan Dimescu
2026-03-10 04:50:16 +02:00
parent 4e61caac45
commit 9c71e9bb3f
16 changed files with 1879 additions and 787 deletions

27
src/forward.rs Normal file
View File

@@ -0,0 +1,27 @@
use std::net::SocketAddr;
use std::time::Duration;
use tokio::net::UdpSocket;
use tokio::time::timeout;
use crate::buffer::BytePacketBuffer;
use crate::packet::DnsPacket;
use crate::Result;
pub async fn forward_query(
query: &DnsPacket,
upstream: SocketAddr,
timeout_duration: Duration,
) -> Result<DnsPacket> {
let socket = UdpSocket::bind("0.0.0.0:0").await?;
let mut send_buffer = BytePacketBuffer::new();
query.write(&mut send_buffer)?;
socket.send_to(send_buffer.filled(), upstream).await?;
let mut recv_buffer = BytePacketBuffer::new();
timeout(timeout_duration, socket.recv_from(&mut recv_buffer.buf)).await??;
DnsPacket::from_buffer(&mut recv_buffer)
}