[ldns-users] Resolver to use TCP if UDP > bufsize

Willem Toorop willem at nlnetlabs.nl
Thu Jan 17 16:18:27 UTC 2013

Op 17-01-13 09:54, Wolfgang Nagele schreef:
> Hi all,
> I have a case where we are sending large DNS packets that exceed 4096 bytes using 'ldns_resolver_send_pkt()'. I noticed that it will not realize that it exceeds the UDP bufsize and fallback to TCP but rather sends the message using UDP which will result in a FORMERR from BIND.

Interesting case! In the OPT rr you state the maximum size you are
willing to receive (but not what you can send). But, since the bind
server does not convey this information... still ldns should be able to
sent big (fragmented) udp messages. The ldns_resolver_edns_udp_size can
not be used. It is about what message sizes we are willing to receive,
not what the other site is willing to receive...

I guess you should copy the ldns_resolver_send_pkt function into a
my_ldns_resolver_send_pkt and replace ldns_send with my_ldns_send. Which
then could look like:

my_ldns_send(ldns_pkt **result_packet, ldns_resolver *r,
	     const ldns_pkt *query_pkt)
        ldns_buffer *qb;
        ldns_status result;
        ldns_rdf *tsig_mac = NULL;
	bool prev_usevc = ldns_resolver_usevc(r);

        qb = ldns_buffer_new(LDNS_MIN_BUFLEN);

        if (query_pkt && ldns_pkt_tsig(query_pkt)) {
                tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);

        if (!query_pkt ||
            ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
                result = LDNS_STATUS_ERR;
        } else {
		if (ldns_buffer_position(qb) > 4096) {
                result = ldns_send_buffer(result_packet, r, qb,
        return result;

> At this point I have implemented a check in our code that will set 'usevc()' for packets that exceed the bufsize. That brings me to another question - is there no better way to get the size of my packet than this?

No. Except for the method described above :(



More information about the ldns-users mailing list