Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: compress.h,v 1.1 2024/02/18 20:57:35 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #ifndef DNS_COMPRESS_H
     17 #define DNS_COMPRESS_H 1
     18 
     19 #include <inttypes.h>
     20 #include <stdbool.h>
     21 
     22 #include <isc/lang.h>
     23 #include <isc/region.h>
     24 
     25 #include <dns/name.h>
     26 #include <dns/types.h>
     27 
     28 ISC_LANG_BEGINDECLS
     29 
     30 /*! \file dns/compress.h
     31  * Direct manipulation of the structures is strongly discouraged.
     32  *
     33  * A name compression context handles compression of multiple DNS names
     34  * in relation to a single DNS message. The context can be used to
     35  * selectively turn on/off compression for specific names (depending on
     36  * the RR type) by using \c dns_compress_setmethods(). Alternately,
     37  * compression can be disabled completely using \c
     38  * dns_compress_disable().
     39  *
     40  * \c dns_compress_setmethods() is intended for use by RDATA towire()
     41  * implementations, whereas \c dns_compress_disable() is intended to be
     42  * used by a nameserver's configuration manager.
     43  */
     44 
     45 #define DNS_COMPRESS_NONE	   0x00 /*%< no compression */
     46 #define DNS_COMPRESS_GLOBAL14	   0x01 /*%< "normal" compression. */
     47 #define DNS_COMPRESS_ALL	   0x01 /*%< all compression. */
     48 #define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */
     49 #define DNS_COMPRESS_ENABLED	   0x04
     50 
     51 /*
     52  * DNS_COMPRESS_TABLESIZE must be a power of 2. The compress code
     53  * utilizes this assumption.
     54  */
     55 #define DNS_COMPRESS_TABLEBITS	  6
     56 #define DNS_COMPRESS_TABLESIZE	  (1U << DNS_COMPRESS_TABLEBITS)
     57 #define DNS_COMPRESS_TABLEMASK	  (DNS_COMPRESS_TABLESIZE - 1)
     58 #define DNS_COMPRESS_INITIALNODES 24
     59 #define DNS_COMPRESS_ARENA_SIZE	  640
     60 
     61 typedef struct dns_compressnode dns_compressnode_t;
     62 
     63 struct dns_compressnode {
     64 	dns_compressnode_t *next;
     65 	uint16_t	    offset;
     66 	uint16_t	    count;
     67 	isc_region_t	    r;
     68 	dns_name_t	    name;
     69 };
     70 
     71 struct dns_compress {
     72 	unsigned int magic;   /*%< Magic number. */
     73 	unsigned int allowed; /*%< Allowed methods. */
     74 	int	     edns;    /*%< Edns version or -1. */
     75 	/*% Global compression table. */
     76 	dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE];
     77 	/*% Preallocated arena for names. */
     78 	unsigned char arena[DNS_COMPRESS_ARENA_SIZE];
     79 	off_t	      arena_off;
     80 	/*% Preallocated nodes for the table. */
     81 	dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES];
     82 	uint16_t	   count; /*%< Number of nodes. */
     83 	isc_mem_t	  *mctx;  /*%< Memory context. */
     84 };
     85 
     86 typedef enum {
     87 	DNS_DECOMPRESS_ANY,    /*%< Any compression */
     88 	DNS_DECOMPRESS_STRICT, /*%< Allowed compression */
     89 	DNS_DECOMPRESS_NONE    /*%< No compression */
     90 } dns_decompresstype_t;
     91 
     92 struct dns_decompress {
     93 	unsigned int	     magic;   /*%< Magic number. */
     94 	unsigned int	     allowed; /*%< Allowed methods. */
     95 	int		     edns;    /*%< Edns version or -1. */
     96 	dns_decompresstype_t type;    /*%< Strict checking */
     97 };
     98 
     99 isc_result_t
    100 dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx);
    101 /*%<
    102  *	Initialise the compression context structure pointed to by
    103  *	'cctx'. A freshly initialized context has name compression
    104  *	enabled, but no methods are set. Please use \c
    105  *	dns_compress_setmethods() to set a compression method.
    106  *
    107  *	Requires:
    108  *	\li	'cctx' is a valid dns_compress_t structure.
    109  *	\li	'mctx' is an initialized memory context.
    110  *	Ensures:
    111  *	\li	cctx->global is initialized.
    112  *
    113  *	Returns:
    114  *	\li	#ISC_R_SUCCESS
    115  */
    116 
    117 void
    118 dns_compress_invalidate(dns_compress_t *cctx);
    119 
    120 /*%<
    121  *	Invalidate the compression structure pointed to by cctx.
    122  *
    123  *	Requires:
    124  *\li		'cctx' to be initialized.
    125  */
    126 
    127 void
    128 dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed);
    129 
    130 /*%<
    131  *	Sets allowed compression methods.
    132  *
    133  *	Requires:
    134  *\li		'cctx' to be initialized.
    135  */
    136 
    137 unsigned int
    138 dns_compress_getmethods(dns_compress_t *cctx);
    139 
    140 /*%<
    141  *	Gets allowed compression methods.
    142  *
    143  *	Requires:
    144  *\li		'cctx' to be initialized.
    145  *
    146  *	Returns:
    147  *\li		allowed compression bitmap.
    148  */
    149 
    150 void
    151 dns_compress_disable(dns_compress_t *cctx);
    152 /*%<
    153  *	Disables all name compression in the context. Once disabled,
    154  *	name compression cannot currently be re-enabled.
    155  *
    156  *	Requires:
    157  *\li		'cctx' to be initialized.
    158  *
    159  */
    160 
    161 void
    162 dns_compress_setsensitive(dns_compress_t *cctx, bool sensitive);
    163 
    164 /*
    165  *	Preserve the case of compressed domain names.
    166  *
    167  *	Requires:
    168  *		'cctx' to be initialized.
    169  */
    170 
    171 bool
    172 dns_compress_getsensitive(dns_compress_t *cctx);
    173 /*
    174  *	Return whether case is to be preserved when compressing
    175  *	domain names.
    176  *
    177  *	Requires:
    178  *		'cctx' to be initialized.
    179  */
    180 
    181 int
    182 dns_compress_getedns(dns_compress_t *cctx);
    183 
    184 /*%<
    185  *	Gets edns value.
    186  *
    187  *	Requires:
    188  *\li		'cctx' to be initialized.
    189  *
    190  *	Returns:
    191  *\li		-1 .. 255
    192  */
    193 
    194 bool
    195 dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
    196 			dns_name_t *prefix, uint16_t *offset);
    197 /*%<
    198  *	Finds longest possible match of 'name' in the global compression table.
    199  *
    200  *	Requires:
    201  *\li		'cctx' to be initialized.
    202  *\li		'name' to be a absolute name.
    203  *\li		'prefix' to be initialized.
    204  *\li		'offset' to point to an uint16_t.
    205  *
    206  *	Ensures:
    207  *\li		'prefix' and 'offset' are valid if true is 	returned.
    208  *
    209  *	Returns:
    210  *\li		#true / #false
    211  */
    212 
    213 void
    214 dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
    215 		 const dns_name_t *prefix, uint16_t offset);
    216 /*%<
    217  *	Add compression pointers for 'name' to the compression table,
    218  *	not replacing existing pointers.
    219  *
    220  *	Requires:
    221  *\li		'cctx' initialized
    222  *
    223  *\li		'name' must be initialized and absolute, and must remain
    224  *		valid until the message compression is complete.
    225  *
    226  *\li		'prefix' must be a prefix returned by
    227  *		dns_compress_findglobal(), or the same as 'name'.
    228  */
    229 
    230 void
    231 dns_compress_rollback(dns_compress_t *cctx, uint16_t offset);
    232 
    233 /*%<
    234  *	Remove any compression pointers from global table >= offset.
    235  *
    236  *	Requires:
    237  *\li		'cctx' is initialized.
    238  */
    239 
    240 void
    241 dns_decompress_init(dns_decompress_t *dctx, int edns,
    242 		    dns_decompresstype_t type);
    243 
    244 /*%<
    245  *	Initializes 'dctx'.
    246  *	Records 'edns' and 'type' into the structure.
    247  *
    248  *	Requires:
    249  *\li		'dctx' to be a valid pointer.
    250  */
    251 
    252 void
    253 dns_decompress_invalidate(dns_decompress_t *dctx);
    254 
    255 /*%<
    256  *	Invalidates 'dctx'.
    257  *
    258  *	Requires:
    259  *\li		'dctx' to be initialized
    260  */
    261 
    262 void
    263 dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed);
    264 
    265 /*%<
    266  *	Sets 'dctx->allowed' to 'allowed'.
    267  *
    268  *	Requires:
    269  *\li		'dctx' to be initialized
    270  */
    271 
    272 unsigned int
    273 dns_decompress_getmethods(dns_decompress_t *dctx);
    274 
    275 /*%<
    276  *	Returns 'dctx->allowed'
    277  *
    278  *	Requires:
    279  *\li		'dctx' to be initialized
    280  */
    281 
    282 int
    283 dns_decompress_edns(dns_decompress_t *dctx);
    284 
    285 /*%<
    286  *	Returns 'dctx->edns'
    287  *
    288  *	Requires:
    289  *\li		'dctx' to be initialized
    290  */
    291 
    292 dns_decompresstype_t
    293 dns_decompress_type(dns_decompress_t *dctx);
    294 
    295 /*%<
    296  *	Returns 'dctx->type'
    297  *
    298  *	Requires:
    299  *\li		'dctx' to be initialized
    300  */
    301 
    302 ISC_LANG_ENDDECLS
    303 
    304 #endif /* DNS_COMPRESS_H */
    305