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