In addition to this the allowed compression methods vary across
types and across client revisions thanks to EDNS.
To be able to compress a domain name you need to some or all of
the following pieces of information.
1. where the message starts.
2. where the current rdata starts in the message (local compression).
3. what the current owner name is (local compression).
4. existing global 14 bit compression targets.
5. existing global 16 bit compression targets.
6. existing local compression targets.
7. the current domain name.
8. what are allowable compression methods, these are not constant
BIND
4.x and BIND
8.x used a table of existing 14 bit compression
The implicit assumption is that we will use compression whenever
possible and when ever there are multiple alternatives available
we will choose the one that minimises the size of the message.
We will need functions that determine the allowable compression
methods, find the "best" match among the available compression
targets, add new compression targets.
We need to be able to back out any changes made to the compression
targets if we are unable to add a complete RR (RRset?). This is
only a problem for the global compression targets.
We will maintain two RBT, one for local compression targets and
one for global compression targets. The data for these RBT will
be the offset values. The local compression RBT only needs to
be maintained when local compression is possible. The global
compression RBT is maintained regardless. Unless there is a
perfect match (or the name is ".") we will add the name to the
compression RBTs provide the offset would not be too large for
the valid compression methods of the RBT. All nodes of the RBT
will have an offset excluding the root node.
The local compression RBT will be initalised with the owner name
and the start of the rdata will be recorded.
We will use deepest partial match to find the potential
We only need to maintain one global RBT as 16 bit compression
pointers are either valid or invalid for the whole message.
dns_compress_allowed(dns_rdatatype_t type, int edns,
Returns allowed compression methods based on type, edns, and whether
we are about to compress a owner name.
dns_compress_init(dns_compress_t *cctx, isc_boolean_t global16,
Initalises cctx to empty and sets whether 16 bit global
compression targets are to be added to the global RBT.
dns_compress_localinit(dns_compress_t *cctx, dns_name_t owner,
Initalise a RBT for local compression, freeing and existing RBT.
dns_compress_invalidate(dns_compress_t *cctx);
Free any RBT's and make empty.
dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed);
dns_compress_getmethods(dns_compress_t *cctx);
dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
'name' contains the current name to be added to the message 'target'.
'target' is assumed to only contain the message.
'cctx' contains the compression context and has to hold all the
information required that cannot be obtained from 'name' or 'target'.
unsigned int allowed; /* Allowed methods. */
unsigned int rdata; /* Start of local rdata */
isc_boolean_t global16; /* 16 bit offsets allowed */
dns_rbt_t *local; /* Local RBT */
dns_rbt_t *global; /* Global RBT */
isc_mem_t *mctx; /* Required by RBT */