You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ldns库解析unbound返回的ub_result中data字段为TLSA记录?

将Unbound的ub_result中data字段解析为TLSA记录(ldns库实现)

Unbound DNS解析器返回的ub_result结构定义如下:

struct ub_result {
    char* qname; /* text string, original question */
    int qtype;   /* type code asked for */
    int qclass;  /* class code asked for */
    char** data; /* array of rdata items, NULL terminated*/
    int* len;    /* array with lengths of rdata items */
    char* canonname; /* canonical name of result */
    int rcode;   /* additional error code in case of no data */
    void* answer_packet; /* full network format answer packet */
    int answer_len; /* length of packet in octets */
    int havedata; /* true if there is data */
    int nxdomain; /* true if nodata because name does not exist */
    int secure;  /* true if result is secure */
    int bogus;   /* true if a security failure happened */
    char* why_bogus; /* string with error if bogus */
};

问题

需要使用ldns库解析上述结构中的data字段,将其转换为已解析的TLSA记录。ldns文档仅描述了从零创建TLSA记录的方法,缺少反向解析的相关说明。

解决方案

ub_result->data中的每个元素是TLSA记录的原始二进制RData(网络字节序),需通过以下ldns API步骤解析:

1. 将二进制数据转为ldns_rdf对象

ldns_rdf是ldns中表示资源数据的基础结构,使用ldns_rdf_new_frm_data()将data字段的二进制内容包装成对应类型的RDF:

// 遍历data数组(NULL终止),i为当前索引
ldns_rdf *tlsa_rdf = ldns_rdf_new_frm_data(
    LDNS_RDF_TYPE_TLSA,
    ub_result->len[i],
    (uint8_t*)ub_result->data[i]
);

2. 将ldns_rdf包装为完整的TLSA资源记录(ldns_rr)

TLSA是完整的DNS资源记录,需把RDF包装成ldns_rr对象,可直接使用ldns_rr_new_frm_rdf():

ldns_rr *tlsa_rr = ldns_rr_new_frm_rdf(
    LDNS_RR_TYPE_TLSA,
    ub_result->qclass, // 使用Unbound返回的类,通常为IN类(LDNS_RR_CLASS_IN)
    tlsa_rdf
);

注:通过ldns_rr_new_frm_rdf()创建的ldns_rr会自动管理tlsa_rdf的内存,无需单独释放tlsa_rdf。

3. 提取TLSA记录的各个字段

使用ldns提供的TLSA专用访问函数,可直接获取解析后的各个字段:

  • 证书使用字段:uint8_t cert_usage = ldns_rr_tlsa_cert_usage(tlsa_rr);
  • 选择器字段:uint8_t selector = ldns_rr_tlsa_selector(tlsa_rr);
  • 匹配类型字段:uint8_t matching_type = ldns_rr_tlsa_matching_type(tlsa_rr);
  • 证书关联数据:ldns_rdf *assoc_data = ldns_rr_tlsa_association_data(tlsa_rr);
    可通过ldns_rdf_data(assoc_data)获取二进制数据指针,ldns_rdf_size(assoc_data)获取数据长度。

4. 内存清理

使用完资源后释放ldns_rr对象:

ldns_rr_free(tlsa_rr);

注意事项

  • 处理前需检查ub_result->havedata为真,且ub_result->qtype等于LDNS_RR_TYPE_TLSA(数值为52),避免处理非TLSA数据。
  • ub_result->data是NULL终止的数组,需循环遍历直到遇到NULL元素。

内容的提问来源于stack exchange,提问作者Graham Leggett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:07:23