idoq : DNS over QUIC Client for Rust
Table of Contents
Features
- RFC 9250 compliant DoQ implementation
- Built-in DoQ server list (AdGuard, ControlD, Alibaba DNS)
- Async/await support with Tokio
- TLS 1.3 with QUIC transport
- Support for A, AAAA, MX, TXT, NS, CNAME, PTR, SRV records
- Zero-copy DNS message parsing
- Connection pooling with lazy initialization
Installation
Add to Cargo.toml:
[]
= "0.1"
Usage
Query DNS records using built-in servers:
use ;
use Query;
async
Query with custom server:
use ;
use Query;
async
API Reference
Structs
HostIp
DoQ server configuration with hostname and IP address.
Implements idns::Query trait for DNS queries.
Functions
host_ip
Create HostIp from static hostname and IPv4 octets.
pub const
Constants
DOQ_LI
Pre-configured DoQ server list:
| Server | IP |
|---|---|
| AdGuard DNS | 94.140.14.140, 94.140.14.141 |
| ControlD | 76.76.2.11 |
| Alibaba DNS | 223.5.5.5, 223.6.6.6 |
site module
Server hostname constants:
site::ADGUARD-"unfiltered.adguard-dns.com"site::CONTROLD-"p0.freedns.controld.com"site::ALIDNS-"dns.alidns.com"
Types
QType
DNS query types (re-exported from idns):
QType::A(1) - IPv4 addressQType::AAAA(28) - IPv6 addressQType::MX(15) - Mail exchangeQType::TXT(16) - Text recordQType::NS(2) - Name serverQType::CNAME(5) - Canonical nameQType::PTR(12) - Pointer recordQType::SRV(33) - Service record
Architecture
graph TD
A[Client Code] --> B[HostIp.answer_li]
B --> C[query_with]
C --> D[connect]
C --> E[query_dns]
D --> F[QUIC Endpoint]
F --> G[TLS Handshake]
G --> H[QUIC Connection]
E --> I[build_query]
E --> J[Send DNS Message]
J --> K[Receive Response]
K --> L[parse]
L --> M[Answer List]
Query Flow
HostIp.answer_li()- Entry point implementingidns::Querytraitquery_with()- Establishes connection and executes queryconnect()- Creates QUIC endpoint with TLS 1.3, ALPN "doq"query_dns()- Opens bidirectional stream, sends query with 2-byte length prefixbuild_query()- Constructs DNS message (ID=0 per RFC 9250) with EDNSparse()- Parses DNS response, extracts answer records
Key Implementation Details
- DNS message ID set to 0 (RFC 9250 requirement)
- 2-byte length prefix for message framing
- EDNS OPT record with 4096 byte UDP payload size
- Lazy-initialized
ClientConfigfor connection reuse - 7-second timeout for connection and read operations
Tech Stack
| Component | Library |
|---|---|
| QUIC | quinn |
| TLS | rustls + ring |
| Async Runtime | tokio |
| Buffer | bytes |
| Error Handling | thiserror |
Directory Structure
idoq/
├── src/
│ ├── lib.rs # Public API, HostIp, DOQ_LI
│ ├── query.rs # QUIC connection, DNS query
│ ├── parser.rs # DNS message build/parse
│ └── error.rs # Error types
├── tests/
│ └── main.rs # Integration tests
└── Cargo.toml
History
DNS over QUIC (DoQ) was standardized in RFC 9250 (May 2022), building on the encrypted DNS movement that began with DNS over HTTPS (DoH, RFC 8484, 2018) and DNS over TLS (DoT, RFC 7858, 2016).
QUIC, originally developed by Google in 2012 as "Quick UDP Internet Connections", was standardized as RFC 9000 in 2021. It provides TLS 1.3 encryption at the transport layer with reduced connection latency through 0-RTT handshakes.
DoQ combines the privacy benefits of encrypted DNS with QUIC's performance advantages: multiplexed streams prevent head-of-line blocking, and connection migration handles network changes gracefully. Unlike DoH which runs over HTTP/2 or HTTP/3, DoQ operates directly over QUIC, reducing protocol overhead.
AdGuard was among the first to deploy public DoQ servers in 2020, followed by providers like Alibaba DNS and ControlD. The protocol is gaining adoption as QUIC becomes the foundation for HTTP/3 and other modern internet protocols.
About
This project is an open-source component of js0.site ⋅ Refactoring the Internet Plan.
We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:
idoq : Rust DNS over QUIC 客户端
目录
特性
- 符合 RFC 9250 的 DoQ 实现
- 内置 DoQ 服务器列表 (AdGuard、ControlD、阿里 DNS)
- 基于 Tokio 的异步支持
- TLS 1.3 + QUIC 传输
- 支持 A、AAAA、MX、TXT、NS、CNAME、PTR、SRV 记录
- 零拷贝 DNS 消息解析
- 延迟初始化的连接池
安装
添加到 Cargo.toml:
[]
= "0.1"
使用
使用内置服务器查询 DNS 记录:
use ;
use Query;
async
使用自定义服务器查询:
use ;
use Query;
async
API 参考
结构体
HostIp
DoQ 服务器配置,包含主机名和 IP 地址。
实现 idns::Query trait 用于 DNS 查询。
函数
host_ip
从静态主机名和 IPv4 八位组创建 HostIp。
pub const
常量
DOQ_LI
预配置的 DoQ 服务器列表:
| 服务器 | IP |
|---|---|
| AdGuard DNS | 94.140.14.140, 94.140.14.141 |
| ControlD | 76.76.2.11 |
| 阿里 DNS | 223.5.5.5, 223.6.6.6 |
site 模块
服务器主机名常量:
site::ADGUARD-"unfiltered.adguard-dns.com"site::CONTROLD-"p0.freedns.controld.com"site::ALIDNS-"dns.alidns.com"
类型
QType
DNS 查询类型 (从 idns 重导出):
QType::A(1) - IPv4 地址QType::AAAA(28) - IPv6 地址QType::MX(15) - 邮件交换QType::TXT(16) - 文本记录QType::NS(2) - 域名服务器QType::CNAME(5) - 别名QType::PTR(12) - 指针记录QType::SRV(33) - 服务记录
架构
graph TD
A[客户端代码] --> B[HostIp.answer_li]
B --> C[query_with]
C --> D[connect]
C --> E[query_dns]
D --> F[QUIC Endpoint]
F --> G[TLS 握手]
G --> H[QUIC 连接]
E --> I[build_query]
E --> J[发送 DNS 消息]
J --> K[接收响应]
K --> L[parse]
L --> M[Answer 列表]
查询流程
HostIp.answer_li()- 入口点,实现idns::Querytraitquery_with()- 建立连接并执行查询connect()- 创建 QUIC 端点,TLS 1.3,ALPN "doq"query_dns()- 打开双向流,发送带 2 字节长度前缀的查询build_query()- 构造 DNS 消息 (ID=0,符合 RFC 9250) 及 EDNSparse()- 解析 DNS 响应,提取应答记录
关键实现细节
- DNS 消息 ID 设为 0 (RFC 9250 要求)
- 2 字节长度前缀用于消息分帧
- EDNS OPT 记录,UDP 负载大小 4096 字节
- 延迟初始化
ClientConfig以复用连接 - 连接和读取操作 7 秒超时
技术栈
| 组件 | 库 |
|---|---|
| QUIC | quinn |
| TLS | rustls + ring |
| 异步运行时 | tokio |
| 缓冲区 | bytes |
| 错误处理 | thiserror |
目录结构
idoq/
├── src/
│ ├── lib.rs # 公开 API、HostIp、DOQ_LI
│ ├── query.rs # QUIC 连接、DNS 查询
│ ├── parser.rs # DNS 消息构建/解析
│ └── error.rs # 错误类型
├── tests/
│ └── main.rs # 集成测试
└── Cargo.toml
历史
DNS over QUIC (DoQ) 于 2022 年 5 月在 RFC 9250 中标准化,是加密 DNS 运动的延续。此前有 DNS over HTTPS (DoH, RFC 8484, 2018) 和 DNS over TLS (DoT, RFC 7858, 2016)。
QUIC 最初由 Google 于 2012 年开发,名为 "Quick UDP Internet Connections",2021 年标准化为 RFC 9000。它在传输层提供 TLS 1.3 加密,通过 0-RTT 握手降低连接延迟。
DoQ 结合了加密 DNS 的隐私优势和 QUIC 的性能优势:多路复用流避免队头阻塞,连接迁移优雅处理网络切换。与运行在 HTTP/2 或 HTTP/3 上的 DoH 不同,DoQ 直接运行在 QUIC 上,减少协议开销。
AdGuard 于 2020 年率先部署公共 DoQ 服务器,随后阿里 DNS、ControlD 等提供商跟进。随着 QUIC 成为 HTTP/3 和其他现代互联网协议的基础,DoQ 正在获得更广泛的采用。
关于
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: