[bind10-dev] rendering logic (Re: DNS packet API: the name object)
JINMEI Tatuya / 神明達哉
jinmei at isc.org
Thu Oct 1 21:27:26 UTC 2009
At Tue, 25 Aug 2009 15:46:57 -0500,
Michael Graff <mgraff at isc.org> wrote:
> I thought a little about that in fact.
>
> Knowing where the names are is good, and the resource record itself is
> best suited for that goal. I would not want to see an API that did this:
>
> if (record->canCompress())
> record->renderCompressedWire(message)
> else
> record->renderUncompressedWire(message)
> end
>
> but just a simple record->renderWire(message) or something. The smarts
> are under the hood.
> Passing in the message (which might have things like a list of names
> currently in the message, for compression purposes) allows the smartness
> to be hidden.
In the initial prototype I committed, a resource record is rendered in
RRSet::to_wire(), which reads:
MessageRenderer& r = message.get_renderer();
NameCompressor& c = message.get_compressor();
for (vector<rdataptr_t>::iterator it = _rdatalist.begin();
it != _rdatalist.end();
++it, ++num_rrs)
{
_name.to_wire(r, c);
_rdtype.to_wire(r);
_rdclass.to_wire(r);
_ttl.to_wire(r);
(**it).to_wire(r, c);
// TBD: handle truncation case
}
(this is a straightforward version of the RRSet implementation.
We could also have a smarter variant of RRSet, where rendering
could be much more efficient)
That is, each component of an RR (name, type, class, TTL and data) has
its own to_wire() method, and we let them to render their data with
the current context ('r' and 'c' - this could also be 'message' itself).
Since the rdata may contain a name which may affect compression, we
also pass a 'Compressor' to its to_wire() method.
The renderer and compressor may be implemented in a straightforward
way or have some smartness under the hood. RR's components simply use
the common interface two these context objects and don't know the
underlying details.
Does this match what you intended in your previous message (quoted
above)?
> Note that many APIs reverse this, and use message->addRecord(). This is
Actually, I'm not sure about this. BIND9's libdns has
dns_rdata_towire(), which takes a buffer and a 'compress context',
both of which is a part of the message. So, essentially,
dns_rdata_towire() behaves equally as the to_wire() method for the
rdata object above. And, as far as I can see from the code, dnspython
works in a similar way.
> fine to build up a list of records, but I think the actual rendering
> should be as I describe above.
---
JINMEI, Tatuya
More information about the bind10-dev
mailing list