DNS

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


功能概述

DNS(Domain Name System,域名系统)是一种基于UDP协议的域名解析工具,用于将域名转换为IP地址。其原理是:发送 DNS 查询请求,等待服务器返回 IP 地址信息。

在嵌入式/物联网场景中,DNS常见用途:

  • 网络连接初始化

  • 域名解析以访问远程服务器

  • 故障定位(检查DNS服务器可用性)

模块支持异步和同步解析模式,支持IPv4/IPv6双栈,适用于资源受限的嵌入式设备。遵循RFC 1035标准,确保兼容性。

基本要素

  1. 工作原理:客户端发送UDP查询包到DNS服务器,服务器返回包含IP地址的响应包。支持递归/迭代查询。

  2. 网络协议支持:基于UDP(端口53),可选TCP用于大响应。

  3. 输入信息

    • 域名(hostname):如"www.example.com",最大256字符。

    • 地址类型(hints):指定IPv4 (AF_INET) 或 IPv6 (AF_INET6)。

  4. 输出信息

    • IP地址链表:qosa_addrinfo_s 结构体,包含 ip_addrai_family

  5. 常见结果

    • 成功:返回IP地址链表。

    • 失败:如域名不存在、超时或内存不足。

  6. 故障排查步骤

    • 检查网络连接(Ping DNS服务器,如8.8.8.8)。

    • 验证域名格式。

    • 测试IPv4/IPv6分别解析。

流程概述

DNS操作流程主要包括以下步骤:

  1. 初始化参数:设置SIM/PDP ID、域名、hints(地址类型)。

  2. 等待网络就绪(PDP激活)。

  3. 发送查询:异步(qosa_dns_asyn_getaddrinfo())或同步(qosa_dns_syn_getaddrinfo())。

  4. 处理响应:解析IP地址链表。

  5. 释放资源:调用 qosa_dns_result_free()

消息结构

DNS消息基于UDP,使用端口53。标准DNS消息包括头部(12字节)、问题区、回答区、授权区和附加区。根据RFC 1035,消息格式如下。

以下是DNS消息结构图:

image
  • 偏移量细节(字节为单位):

    • 0~1:ID

    • 2~3:Flags (QR、Opcode、AA、TC、RD、RA、Z、RCODE)

    • 4~5:QDCOUNT

    • 6~7:ANCOUNT

    • 8~9:NSCOUNT

    • 10~11:ARCOUNT

    • 12+:Question/Answer等(可变)。

备注

域名使用压缩指针避免重复;QTYPE:1 = A (IPv4), 28 = AAAA (IPv6)。

API说明

头文件

qosa_asyn_dns.h

函数概览

函数

描述

qosa_dns_asyn_getaddrinfo()

异步DNS解析域名

qosa_dns_syn_getaddrinfo()

同步DNS解析域名

qosa_dns_result_free()

释放DNS解析结果

qosa_dns_asyn_getaddrinfo

  • 功能描述
    异步DNS解析接口,用于解析域名到IP地址,支持IPv4或IPv6,并通过回调函数通知结果。该函数适用于需要非阻塞操作的场景,如多任务环境,避免阻塞主线程。

  • 函数原型

qosa_dns_error_e qosa_dns_asyn_getaddrinfo(qosa_uint8_t           simcid,
                                           qosa_uint8_t           pdpcid,
                                           const char             *hostname,
                                           struct qosa_addrinfo_s *hints,
                                           dns_result_callback    cb,
                                           void                   *user_argv);
  • 参数说明

参数名

输入/输出

类型

说明

simcid

输入

qosa_uint8_t

SIM ID

pdpcid

输入

qosa_uint8_t

PDP ID

hostname

输入

const char*

要解析的域名信息,长度不超过 QOSA_DNS_REQUEST_MAX_LEN (256 字符)

hints

输入

struct qosa_addrinfo_s*

主要用于指定解析的地址类型(如IPv4或IPv6);详见 qosa_addrinfo_s

cb

输入

dns_result_callback

用户注册的异步通知回调函数,在回调函数中禁止进行自己的数据业务,可能导致数据临界问题

user_argv

输入

void*

用户自定义参数指针

  • 返回值说明
    QOSA_DNS_RESULT_OK:函数执行成功
    其他值:函数执行失败;详见 qosa_dns_error_e

备注

  1. 如果DNS请求成功,调用者需要在回调函数中调用 qosa_dns_result_free() 函数释放地址指针。

  2. 回调函数中禁止进行阻塞操作或复杂业务逻辑,以避免影响系统性能。

  3. hostname 长度超过256字符将导致解析失败,返回 QOSA_DNS_RESULT_ERROR

  4. hints 参数用于指定 ai_family(如AF_INET for IPv4, AF_INET6 for IPv6),其他成员可设为0。

  5. 该函数异步执行,不会阻塞调用线程,结果通过 cb 回调返回。

  6. 如果内存分配失败,返回 QOSA_DNS_MEMORY_ERROR

qosa_dns_syn_getaddrinfo

  • 功能描述
    同步DNS解析接口,用于解析域名到IP地址,支持IPv4或IPv6,直接返回结果。该函数适用于简单场景,需要阻塞等待解析完成。

  • 函数原型

qosa_dns_error_e qosa_dns_syn_getaddrinfo(qosa_uint8_t           simcid, 
                                          qosa_uint8_t           pdpcid, 
                                          const char             *hostname, 
                                          struct qosa_addrinfo_s *hints, 
                                          struct qosa_addrinfo_s **res);
  • 参数说明

参数名

输入/输出

类型

说明

simcid

输入

qosa_uint8_t

SIM ID

pdpcid

输入

qosa_uint8_t

PDP ID

hostname

输入

const char*

要解析的域名信息,长度不超过 QOSA_DNS_REQUEST_MAX_LEN (256 字符)

hints

输入

struct qosa_addrinfo_s*

主要用于指定解析的地址类型(如IPv4或IPv6);详见 qosa_addrinfo_s

res

输入

struct qosa_addrinfo_s**

解析结果输出,如果失败则 *res = NULL;详见 qosa_addrinfo_s

  • 返回值说明
    QOSA_DNS_RESULT_OK:函数执行成功
    其他值:函数执行失败;详见 qosa_dns_error_e

备注

  1. 如果DNS请求成功,调用者需要调用 qosa_dns_result_free() 函数释放 res 指向的内存。

  2. 该函数是同步的,会阻塞调用线程直到解析完成或超时,可能影响实时性。

  3. hostname 长度超过256字符将导致解析失败,返回 QOSA_DNS_RESULT_ERROR

  4. hints 参数用于指定 ai_family(如AF_INET for IPv4, AF_INET6 for IPv6),其他成员可设为0。

  5. 如果内存分配失败,返回 QOSA_DNS_MEMORY_ERROR

qosa_dns_result_free

  • 功能描述
    释放DNS返回结果内存,适用于异步或同步解析成功后的结果释放。

  • 函数原型

void qosa_dns_result_free(struct qosa_addrinfo_s *info);
  • 参数说明

参数名

输入/输出

类型

说明

info

输入

struct qosa_addrinfo_s*

要释放的 qosa_addrinfo_s 结构体;详见 qosa_addrinfo_s

  • 返回值说明

备注

  1. 必须在DNS解析成功后调用此函数释放内存,以避免内存泄漏。

  2. 如果 info 为NULL,则无操作,不引发错误。

  3. 链表结构中会递归释放所有 ai_next 节点。

结构体定义

qosa_addrinfo_s

struct qosa_addrinfo_s
{
    int                     ai_family;                             
    char                    ip_addr[CONFIG_QOSA_INET6_ADDRSTRLEN]; 
    struct qosa_addrinfo_s *ai_next;                         
};

参数

类型

说明

ai_family

int

IP地址类型(如AF_INET或AF_INET6)

ip_addr

char

字符类型IP地址,如"127.0.0.1"或IPv6地址,最大48字符

ai_next

struct qosa_addrinfo_s

存储地址的下一个节点(链表结构);详见 qosa_addrinfo_s

枚举定义

qosa_dns_error_e

typedef enum
{
    QOSA_DNS_RESULT_OK = 0,                            
    QOSA_DNS_RESULT_ERROR = 1 | QOSA_ERRCODE_DNS_BASE, 
    QOSA_DNS_MEMORY_ERROR = 2,                        

    QOSA_DNS_RESULT_MAX
} qosa_dns_error_e;

成员

说明

QOSA_DNS_RESULT_OK

DNS请求成功

QOSA_DNS_RESULT_ERROR

DNS请求失败

QOSA_DNS_MEMORY_ERROR

DNS内部内存分配失败

QOSA_DNS_RESULT_MAX

最大枚举值

应用逻辑流程图

image

示例代码

完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/dns/dns_demo.c

功能配置建议

DNS配置主要通过hints结构体指定解析类型。以下是详细建议,适用于嵌入式场景。

  1. simcid(SIM卡ID)

    • 推荐:0(主SIM)。

    • 解释:选择稳定SIM;在双SIM设备中动态检测信号。

  2. pdpcid(PDP ID)

    • 推荐:1(默认上下文)。

    • 解释:确保PDP激活前调用。

  3. hostname(域名)

    • 推荐:有效域名,如"www.baidu.com",< 256字符。

    • 解释:避免无效域名导致 QOSA_DNS_RESULT_ERROR

  4. hints.ai_family(地址类型)

    • 推荐:AF_INET (IPv4) 或 AF_INET6 (IPv6)。

    • 解释:默认IPv4;IPv6需网络支持。其他成员设为0。

通用指南:异步模式优先(非阻塞);释放内存避免泄漏。示例中 hints.ai_family = AF_INET。

常见问题排查指南

问题现象(错误码)

可能原因

建议解决方案

QOSA_DNS_RESULT_ERROR

域名无效、超时或网络问题

检查 hostname;测试网络(Ping DNS服务器);增大超时。

QOSA_DNS_MEMORY_ERROR

内存不足

优化代码;增加栈大小;检查系统负载。

回调未触发(异步)

任务/队列初始化失败

检查异步回调是否已正确注册;确认网络已就绪且调用线程未阻塞结果处理流程;如使用异步解析,请确保应用层事件循环能够正常接收并处理回调通知。

res = NULL(同步)

解析失败

验证 hints;使用IP代替域名测试。

内存泄漏

未调用 qosa_dns_result_free()

在成功后释放 info

附录

术语缩写表

缩写

全称

说明

DNS

Domain Name System

域名系统,用于地址解析

UDP

User Datagram Protocol

用户数据报协议,DNS传输层

IP

Internet Protocol

互联网协议

IPv4

Internet Protocol version 4

互联网协议第4版

IPv6

Internet Protocol version 6

互联网协议第6版

PDP

Packet Data Protocol

分组数据协议,用于移动网络

SIM

Subscriber Identity Module

用户身份模块(SIM卡)