Getting and parsing a HTTPS record
eugeny gladkih
john at drweb.com
Thu Jan 16 13:33:58 CET 2025
>
> I want is to create a request for a HTTPS record and get the answer or an error. I struggle to understand how to do this. The ares_dns_record_create is hard to follow and understand what sequence to use and how to glue everything together.
>
> I think the docs would benefit from being split up to document one function per man page as God intended. With examples showing how they can be used.
>
> This is my initial attempt to send off the HTTPS RR request:
>
> ares_dns_record_create(&dnsrec, 0 /* id */, 0, /* flags */
> ARES_OPCODE_QUERY, ARES_RCODE_NOERROR);
> ares_dns_record_query_add(dnsrec, hostname,
> ARES_REC_TYPE_HTTPS, ARES_CLASS_IN);
> ares_send_dnsrec((ares_channel)resolver_hgandle,
> dnsrec, dnsrec_done_cb, data, NULL);
>
> But I simply cannot figure out how the dnsrec_done_cb callback should be written to parse the incoming reply?
>
> What helpers should I use?
>
>
like this:
_buf - memory buffer with DNS reply
int parse_A_reply( const lstr_t& _buf, std::vector<in_addr>& _list ) {
return parse_GEN_reply<ARES_REC_TYPE_A,ARES_RR_A_ADDR>( _buf, ares_dns_rr_get_addr, _list );
}
int parse_AAAA_reply( const lstr_t& _buf, std::vector<ip6pp_t>& _list ) {
return parse_GEN_reply<ARES_REC_TYPE_AAAA,ARES_RR_AAAA_ADDR>( _buf, ares_dns_rr_get_addr6, _list );
}
template<ares_dns_rec_type_t Type, ares_dns_rr_key_t Key, typename List>
int parse_GEN_reply( const lstr_t& _buf, auto& _func, List& _list ) {
AUTOFREE_RES( ares_dns_record_t*, nullptr, ares_dns_record_destroy ) reply;
auto status = ares_dns_parse( (const unsigned char*)_buf.Buf, _buf.Len, 0, reply.ptr() );
if( unlikely( ARES_SUCCESS != status ) ) {
return status;
}
const size_t count = ares_dns_record_rr_cnt( reply, ARES_SECTION_ANSWER );
bool done = false;
for( size_t cur = 0; cur < count; ++cur ) {
const ares_dns_rr_t *rr = ares_dns_record_rr_get_const( reply, ARES_SECTION_ANSWER, cur );
if( unlikely( !rr ) ) {
continue;
}
const auto ty = ares_dns_rr_get_type( rr );
const auto cl = ares_dns_rr_get_class( rr );
if( unlikely( ty != Type || cl != ARES_CLASS_IN ) )
continue;
if( auto ptr = (typename List::value_type*)_func( rr, Key ); likely( ptr ) ) {
_list.emplace_back( *ptr );
done = true;
}
}
return done ? ARES_SUCCESS : ARES_ENODATA;
}
--
Yours sincerely, Eugeny.
More information about the c-ares
mailing list