| Crates.io | dns_parse |
| lib.rs | dns_parse |
| version | 0.1.2 |
| created_at | 2025-12-19 22:33:09.587773+00 |
| updated_at | 2025-12-19 22:41:07.879634+00 |
| description | DNS message build and parse / DNS 消息构建与解析 |
| homepage | https://github.com/js0-site/rust/tree/main/dns_parse |
| repository | https://github.com/js0-site/rust.git |
| max_upload_size | |
| id | 1995681 |
| size | 46,998 |
A lightweight DNS message builder and parser library, used by idoq (DoQ) and idot (DoT).
bytes crate[dependencies]
dns_parse = "0.1"
use dns_parse::build;
// Build query with message ID, domain, and query type
let msg = build(0x1234, "example.com", 1); // A record
let msg = build(0, "example.com", 28); // AAAA record (ID=0 for DoQ)
use dns_parse::parse;
use bytes::Bytes;
let response: Bytes = /* DNS response data */;
match parse(response) {
Ok(answers) => {
for a in answers {
println!("{} {} TTL={}", a.name, a.val, a.ttl);
}
}
Err(e) => eprintln!("Parse error: {e}"),
}
buildBuild a DNS query message.
pub fn build(id: u16, domain: &str, qtype: u16) -> Bytes
id: Message ID (0 for DoQ per RFC 9250, random for DoT)domain: Query domain nameqtype: Query type (1=A, 28=AAAA, 15=MX, etc.)Returns DNS query message with EDNS OPT record (4096 byte UDP payload).
parseParse a DNS response message.
pub fn parse(data: Bytes) -> Result<Vec<Answer>>
Returns parsed answer records. Empty vector for NXDOMAIN or error responses.
Answer (from idns)pub struct Answer {
pub name: String, // Record name
pub val: String, // Record value (formatted)
pub type_id: u16, // Record type
pub ttl: u32, // Time to live
}
ResponseTooShort - Response less than 12 bytesIncompleteData - Truncated record dataNameOutOfBounds - Name extends beyond messagePointerOutOfBounds - Invalid compression pointer| Type | Format |
|---|---|
| A (1) | 192.0.2.1 |
| AAAA (28) | 2001:db8::1 |
| MX (15) | 10 mail.example.com |
| TXT (16) | v=spf1 include:... |
| NS/CNAME/PTR | ns1.example.com |
| SRV (33) | 10 5 5060 sip.example.com |
| Other | Hex encoded |
| Component | Library |
|---|---|
| Buffer | bytes |
| Error | thiserror |
| Hex | hex |
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:
轻量级 DNS 消息构建和解析库,供 idoq (DoQ) 和 idot (DoT) 使用。
bytes 的零拷贝解析[dependencies]
dns_parse = "0.1"
use dns_parse::build;
// 构建查询:消息 ID、域名、查询类型
let msg = build(0x1234, "example.com", 1); // A 记录
let msg = build(0, "example.com", 28); // AAAA 记录 (DoQ 要求 ID=0)
use dns_parse::parse;
use bytes::Bytes;
let response: Bytes = /* DNS 响应数据 */;
match parse(response) {
Ok(answers) => {
for a in answers {
println!("{} {} TTL={}", a.name, a.val, a.ttl);
}
}
Err(e) => eprintln!("解析错误: {e}"),
}
build构建 DNS 查询消息。
pub fn build(id: u16, domain: &str, qtype: u16) -> Bytes
id: 消息 ID(DoQ 按 RFC 9250 要求为 0,DoT 可随机)domain: 查询域名qtype: 查询类型(1=A, 28=AAAA, 15=MX 等)返回带 EDNS OPT 记录(4096 字节 UDP 负载)的 DNS 查询消息。
parse解析 DNS 响应消息。
pub fn parse(data: Bytes) -> Result<Vec<Answer>>
返回解析后的应答记录。NXDOMAIN 或错误响应返回空向量。
Answer(来自 idns)pub struct Answer {
pub name: String, // 记录名称
pub val: String, // 记录值(格式化后)
pub type_id: u16, // 记录类型
pub ttl: u32, // 生存时间
}
ResponseTooShort - 响应小于 12 字节IncompleteData - 记录数据截断NameOutOfBounds - 名称超出消息边界PointerOutOfBounds - 无效压缩指针| 类型 | 格式 |
|---|---|
| A (1) | 192.0.2.1 |
| AAAA (28) | 2001:db8::1 |
| MX (15) | 10 mail.example.com |
| TXT (16) | v=spf1 include:... |
| NS/CNAME/PTR | ns1.example.com |
| SRV (33) | 10 5 5060 sip.example.com |
| 其他 | 十六进制编码 |
| 组件 | 库 |
|---|---|
| 缓冲 | bytes |
| 错误 | thiserror |
| 十六进制 | hex |
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: