EMS 知识库
首页 / knowledge/代码解析/midware/ethernt/lan

dns.h

源文件路径:midware/ethernt/lan/dns.h 所属模块:midware/ethernt/lan(W5500 以太网协议栈应用层 — DHCP/DNS/Socket) 代码行数:101

1. 文件职责

本文件是 WIZnet W5500 官方 DNS 客户端库的头文件,声明域名解析所需的三个接口(初始化、解析、1 秒计时)以及超时/重试/缓冲区尺寸等常量。

在 EMS 中它定义了"把服务器域名翻译成 IP"这条路径的契约:ethernet.c:296 用 DNS_init(SOCK_DNS, g_u8DNSBuf) 绑定 socket 0 与缓冲区,ethernet.c:497 在 dns_pro_fun() 里调用 DNS_run(),ethernet.c:1087 由 internet_time_handle() 每秒调用 DNS_time_handler()。

解析结果 ip_from_dns 输出到 g_stNetSysInfo.Domain_IP,是 TCP 客户端 connect() 的前置依赖,因此本文件处在"DHCP 拿到地址之后、TCP 建链之前"的环节。文件本身只有宏、返回值约定和函数原型,实现在 dns.c。

2. 关键数据结构与宏

名称类型说明
_DNS_DEBUG_宏调试开关,被注释掉(第 59 行)。打开后引入 <stdio.h>,并让 dns.c 中大量 printf 生效;注意 dns.c 里还有一处拼写错误 _DNS_DEUBG_
MAX_DNS_BUF_SIZE宏DNS 报文缓冲区上限 512,同时也是 UDP 收包的单包最大长度(第 61 行)
MAX_DOMAIN_NAME宏待查询域名的最大长度 168(第 67 行);注释警告会用它的 1.5 倍在栈上开 MAXCNAME 缓冲
MAX_DNS_RETRY宏重新查询次数 1(第 69 行)
DNS_WAIT_TIME宏等待应答时间 3,单位秒(第 70 行)
IPPORT_DOMAIN宏DNS 服务端口 53(第 72 行)
DNS_MSG_ID宏DNS 报文初始 ID 0x1122,实际发送时由 DNS_MSGID++ 递增(第 74 行)

本文件没有定义结构体、枚举、联合体或位域;DNS 报文头 dhdr 与各类 TYPE_* 记录类型定义在 dns.c(第 65-115 行),不对外暴露。

3. 函数清单

本文件只有函数声明,没有函数定义。

函数名作用域说明(一句话)
DNS_init(uint8_t s, uint8_t * buf)全局(声明,第 80 行)DNS 客户端初始化:绑定 socket 号、报文缓冲区和初始报文 ID
DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)全局(声明,第 93 行)发送 DNS 查询并接收应答;非阻塞,返回 -1/0/1,另在实际实现中返回 2 表示"处理中"
DNS_time_handler(void)全局(声明,第 99 行)1 秒节拍回调,需注册到系统 1s tick,供 DNS_run() 超时判断

4. 核心逻辑解析

4.1 返回值约定(第 88-91 行的注释与实际实现的差异)

头注释声明的返回值是:

但 dns.c 的实际实现把函数改成了分次调用的非阻塞状态机(dns.c:509 处的 static u8 s_u8_flag),因此多出一个未在头文件中说明的返回值 2 = 正在处理中,请再次调用。调用方 ethernet.c:499 必须靠 if(ret == 2) return; 显式处理这个未文档化的值——这是本头文件与实际行为最值得注意的偏差。

4.2 缓冲区尺寸契约

MAX_DNS_BUF_SIZE(512) 在 dns.c 中同时承担三个角色:sendto 的长度参数、recvfrom 的截断上限、parse_name()/dns_makequery() 的边界参照。实际缓冲区由 ethernet.c:38 的 u8 g_u8DNSBuf[MAX_DNS_BUF_SIZE] 提供并透传给 DNS_init()。由于域名(MAX_DOMAIN_NAME=168)在组帧时对名称点分段后的总长度未做校验,缓冲区尺寸与域名长度之间的约束并不真正由这两个宏保证。

4.3 计时契约

DNS_time_handler() 的约定是"注册到系统 1s tick"。本工程接线同样在 ethernet.c:1087,由 task_system_aux(优先级 8)驱动,与 DHCP_time_handler() 共用同一个 1 秒闸门。真正查询/收包的 DNS_run() 则在 task_ethernet(优先级 17)中被 dns_pro_fun() 以 500 tick(0.5 s)间隔调用(ethernet.c:424),因此一次域名解析是"跨多次任务调度分步完成"的。

5. 对外接口

本文件导出的函数(均在 dns.c 中实现):DNS_init()、DNS_run()、DNS_time_handler()。

本文件导出的宏(供调用方使用):MAX_DNS_BUF_SIZE(ethernet.c:38 用它定义缓冲区)、MAX_DOMAIN_NAME、MAX_DNS_RETRY、DNS_WAIT_TIME、IPPORT_DOMAIN、DNS_MSG_ID。

本文件自身显式 include 了 <stdint.h>(第 54 行),因此函数原型中的 uint8_t/int8_t 不依赖包含顺序——这一点比 dhcp.h 严谨。

6. 依赖关系

7. 备注与风险点