[bind10-dev] DNS message API: how to handle to-be-truncated case

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Tue Sep 29 23:18:39 UTC 2009


While I considered the API for DNS message parsing/rendering, I
encountered one specific question (among many others): what's the
reasonable interface for message rendering when the message is going
to be too big (i.e., over 512 bytes or the notified EDNS0 buffer
size)?

In BIND9, dns_message_rendersection() returns ISC_R_NOSPACE.  The
caller is responsible for setting the TC bit and finishing the
incomplete message.  I don't like this interface because it makes the
API inconvenient for the rare event.

Other libraries/tools don't seem good, however:
- dnspython (dns.message.to_wire()) throws an exception if the
  message is too big.  This is probably better than the BIND9's
  interface, but still not good enough to me.  The caller will still
  need to catch and handle the exception if it expects a big message
  (like the case of our authoritative name server), so the resulting
  client code will still be complicated.  Also, exception handling is
  generally much more expensive.  Even if this is a relatively rare
  event, we'd avoid this bottleneck in our performance-sensitive code
  (and I thought our general consensus is to avoid using exceptions
  when the event can happen as a result of a valid operation, not a
  bug).
- dnsruby (Dnsruby::Message.encode()) and ldns
  (ldns_pkt2buffer_wire()) seem to ignore such events.  It's bad, of
  course:-)

What I'm currently thinking about is a behavior like this:

- by default, our "message" object throws an exception from the
  "to_wire" method if the message is too big.
- the client code can customize the behavior if it wants the message
  object handle this case internally.  for example, it can request the
  object set the TC bit automatically and successfully finish the
  rendering with a truncated message.

Most third party programs will be happy with the default behavior.
Truncation should be rare event, anyway, and the client code will be
as simple as something like:

  message.to_wire();  // almost always succeed.  the client will
                      // happily die with the exceptional case
  message.sendto(somewhere);

A performance-sensitive client code that must expect truncation should
still be pretty simple:
  message.allow_truncation();
  message.to_wire();  // always succeed.  it may be an incomplete msg with TC
  message.sendto(somewhere);

and since it doesn't have to handle an exception, it should still be
reasonably fast.

Comments/suggestions?

---
JINMEI, Tatuya



More information about the bind10-dev mailing list