xref: /openbsd/usr.bin/dig/lib/isc/include/isc/buffer.h (revision 873f12b9)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: buffer.h,v 1.9 2020/02/26 18:48:00 florian Exp $ */
18 
19 #ifndef ISC_BUFFER_H
20 #define ISC_BUFFER_H 1
21 
22 /*****
23  ***** Module Info
24  *****/
25 
26 /*! \file isc/buffer.h
27  *
28  * \brief A buffer is a region of memory, together with a set of related subregions.
29  * Buffers are used for parsing and I/O operations.
30  *
31  * The 'used region' and the 'available' region are disjoint, and their
32  * union is the buffer's region.  The used region extends from the beginning
33  * of the buffer region to the last used byte.  The available region
34  * extends from one byte greater than the last used byte to the end of the
35  * buffer's region.  The size of the used region can be changed using various
36  * buffer commands.  Initially, the used region is empty.
37  *
38  * The used region is further subdivided into two disjoint regions: the
39  * 'consumed region' and the 'remaining region'.  The union of these two
40  * regions is the used region.  The consumed region extends from the beginning
41  * of the used region to the byte before the 'current' offset (if any).  The
42  * 'remaining' region the current pointer to the end of the used
43  * region.  The size of the consumed region can be changed using various
44  * buffer commands.  Initially, the consumed region is empty.
45  *
46  * The 'active region' is an (optional) subregion of the remaining region.
47  * It extends from the current offset to an offset in the remaining region
48  * that is selected with isc_buffer_setactive().  Initially, the active region
49  * is empty.  If the current offset advances beyond the chosen offset, the
50  * active region will also be empty.
51  *
52  * \verbatim
53  *  /------------entire length---------------\
54  *  /----- used region -----\/-- available --\
55  *  +----------------------------------------+
56  *  | consumed  | remaining |                |
57  *  +----------------------------------------+
58  *  a           b     c     d                e
59  *
60  * a == base of buffer.
61  * b == current pointer.  Can be anywhere between a and d.
62  * c == active pointer.  Meaningful between b and d.
63  * d == used pointer.
64  * e == length of buffer.
65  *
66  * a-e == entire length of buffer.
67  * a-d == used region.
68  * a-b == consumed region.
69  * b-d == remaining region.
70  * b-c == optional active region.
71  *\endverbatim
72  *
73  * The following invariants are maintained by all routines:
74  *
75  *\code
76  *	length > 0
77  *
78  *	base is a valid pointer to length bytes of memory
79  *
80  *	0 <= used <= length
81  *
82  *	0 <= current <= used
83  *
84  *	0 <= active <= used
85  *	(although active < current implies empty active region)
86  *\endcode
87  *
88  * \li MP:
89  *	Buffers have no synchronization.  Clients must ensure exclusive
90  *	access.
91  *
92  * \li Reliability:
93  *	No anticipated impact.
94  *
95  * \li Resources:
96  *	Memory: 1 pointer + 6 unsigned integers per buffer.
97  *
98  * \li Security:
99  *	No anticipated impact.
100  *
101  * \li Standards:
102  *	None.
103  */
104 
105 /***
106  *** Imports
107  ***/
108 
109 #include <inttypes.h>
110 
111 #include <isc/types.h>
112 
113 /*
114  * The following macros MUST be used only on valid buffers.  It is the
115  * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
116  * check above, or by calling another isc_buffer_*() function (rather than
117  * another macro.)
118  */
119 
120 /*@{*/
121 /*!
122  * Fundamental buffer elements.  (A through E in the introductory comment.)
123  */
124 #define isc_buffer_base(b)    ((void *)(b)->base)			  /*a*/
125 #define isc_buffer_current(b) \
126 		((void *)((unsigned char *)(b)->base + (b)->current))     /*b*/
127 #define isc_buffer_active(b)  \
128 		((void *)((unsigned char *)(b)->base + (b)->active))      /*c*/
129 #define isc_buffer_used(b)    \
130 		((void *)((unsigned char *)(b)->base + (b)->used))        /*d*/
131 #define isc_buffer_length(b)  ((b)->length)				  /*e*/
132 /*@}*/
133 
134 /*@{*/
135 /*!
136  * Derived lengths.  (Described in the introductory comment.)
137  */
138 #define isc_buffer_usedlength(b)	((b)->used)		      /* d-a */
139 #define isc_buffer_consumedlength(b)	((b)->current)		      /* b-a */
140 #define isc_buffer_remaininglength(b)	((b)->used - (b)->current)    /* d-b */
141 #define isc_buffer_activelength(b)	((b)->active - (b)->current)  /* c-b */
142 #define isc_buffer_availablelength(b)	((b)->length - (b)->used)     /* e-d */
143 /*@}*/
144 
145 /*!
146  * Note that the buffer structure is public.  This is principally so buffer
147  * operations can be implemented using macros.  Applications are strongly
148  * discouraged from directly manipulating the structure.
149  */
150 
151 struct isc_buffer {
152 	void		       *base;
153 	/*@{*/
154 	/*! The following integers are byte offsets from 'base'. */
155 	unsigned int		length;
156 	unsigned int		used;
157 	unsigned int 		current;
158 	unsigned int 		active;
159 	/*@}*/
160 	/*! linkable */
161 	ISC_LINK(isc_buffer_t)	link;
162 	/*! private internal elements */
163 };
164 
165 /***
166  *** Functions
167  ***/
168 
169 isc_result_t
170 isc_buffer_allocate(isc_buffer_t **dynbuffer,
171 		    unsigned int length);
172 /*!<
173  * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
174  * data region.
175  *
176  * Requires:
177  *\li	"mctx" is valid.
178  *
179  *\li	"dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
180  *
181  * Returns:
182  *\li	ISC_R_SUCCESS		- success
183  *\li	ISC_R_NOMEMORY		- no memory available
184  *
185  * Note:
186  *\li	Changing the buffer's length field is not permitted.
187  */
188 
189 void
190 isc_buffer_free(isc_buffer_t **dynbuffer);
191 /*!<
192  * \brief Release resources allocated for a dynamic buffer.
193  *
194  * Requires:
195  *\li	"dynbuffer" is not NULL.
196  *
197  *\li	"*dynbuffer" is a valid dynamic buffer.
198  *
199  * Ensures:
200  *\li	"*dynbuffer" will be NULL on return, and all memory associated with
201  *	the dynamic buffer is returned to the memory context used in
202  *	isc_buffer_allocate().
203  */
204 
205 void
206 isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
207 /*!<
208  * \brief Make 'b' refer to the 'length'-byte region starting at base.
209  *
210  * Requires:
211  *
212  *\li	'length' > 0
213  *
214  *\li	'base' is a pointer to a sequence of 'length' bytes.
215  *
216  */
217 
218 void
219 isc__buffer_invalidate(isc_buffer_t *b);
220 /*!<
221  * \brief Make 'b' an invalid buffer.
222  *
223  * Requires:
224  *\li	'b' is a valid buffer.
225  *
226  * Ensures:
227  *\li	If assertion checking is enabled, future attempts to use 'b' without
228  *	calling isc_buffer_init() on it will cause an assertion failure.
229  */
230 
231 void
232 isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
233 /*!<
234  * \brief Make 'r' refer to the used region of 'b'.
235  *
236  * Requires:
237  *
238  *\li	'b' is a valid buffer.
239  *
240  *\li	'r' points to a region structure.
241  */
242 
243 void
244 isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
245 /*!<
246  * \brief Make 'r' refer to the available region of 'b'.
247  *
248  * Requires:
249  *
250  *\li	'b' is a valid buffer.
251  *
252  *\li	'r' points to a region structure.
253  */
254 
255 void
256 isc__buffer_add(isc_buffer_t *b, unsigned int n);
257 /*!<
258  * \brief Increase the 'used' region of 'b' by 'n' bytes.
259  *
260  * Requires:
261  *
262  *\li	'b' is a valid buffer
263  *
264  *\li	used + n <= length
265  *
266  */
267 
268 void
269 isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
270 /*!<
271  * \brief Decrease the 'used' region of 'b' by 'n' bytes.
272  *
273  * Requires:
274  *
275  *\li	'b' is a valid buffer
276  *
277  *\li	used >= n
278  *
279  */
280 
281 void
282 isc__buffer_clear(isc_buffer_t *b);
283 /*!<
284  * \brief Make the used region empty.
285  *
286  * Requires:
287  *
288  *\li	'b' is a valid buffer
289  *
290  * Ensures:
291  *
292  *\li	used = 0
293  *
294  */
295 
296 void
297 isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
298 /*!<
299  * \brief Make 'r' refer to the remaining region of 'b'.
300  *
301  * Requires:
302  *
303  *\li	'b' is a valid buffer.
304  *
305  *\li	'r' points to a region structure.
306  */
307 
308 void
309 isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
310 /*!<
311  * \brief Make 'r' refer to the active region of 'b'.
312  *
313  * Requires:
314  *
315  *\li	'b' is a valid buffer.
316  *
317  *\li	'r' points to a region structure.
318  */
319 
320 void
321 isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
322 /*!<
323  * \brief Sets the end of the active region 'n' bytes after current.
324  *
325  * Requires:
326  *
327  *\li	'b' is a valid buffer.
328  *
329  *\li	current + n <= used
330  */
331 
332 void
333 isc__buffer_first(isc_buffer_t *b);
334 /*!<
335  * \brief Make the consumed region empty.
336  *
337  * Requires:
338  *
339  *\li	'b' is a valid buffer
340  *
341  * Ensures:
342  *
343  *\li	current == 0
344  *
345  */
346 
347 void
348 isc__buffer_forward(isc_buffer_t *b, unsigned int n);
349 /*!<
350  * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
351  *
352  * Requires:
353  *
354  *\li	'b' is a valid buffer
355  *
356  *\li	current + n <= used
357  *
358  */
359 
360 void
361 isc_buffer_compact(isc_buffer_t *b);
362 /*!<
363  * \brief Compact the used region by moving the remaining region so it occurs
364  * at the start of the buffer.  The used region is shrunk by the size of
365  * the consumed region, and the consumed region is then made empty.
366  *
367  * Requires:
368  *
369  *\li	'b' is a valid buffer
370  *
371  * Ensures:
372  *
373  *\li	current == 0
374  *
375  *\li	The size of the used region is now equal to the size of the remaining
376  *	region (as it was before the call).  The contents of the used region
377  *	are those of the remaining region (as it was before the call).
378  */
379 
380 uint8_t
381 isc_buffer_getuint8(isc_buffer_t *b);
382 /*!<
383  * \brief Read an unsigned 8-bit integer from 'b' and return it.
384  *
385  * Requires:
386  *
387  *\li	'b' is a valid buffer.
388  *
389  *\li	The length of the available region of 'b' is at least 1.
390  *
391  * Ensures:
392  *
393  *\li	The current pointer in 'b' is advanced by 1.
394  *
395  * Returns:
396  *
397  *\li	A 8-bit unsigned integer.
398  */
399 
400 void
401 isc__buffer_putuint8(isc_buffer_t *b, uint8_t val);
402 /*!<
403  * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
404  *
405  * Requires:
406  *\li	'b' is a valid buffer.
407  *
408  *\li	The length of the unused region of 'b' is at least 1.
409  *
410  * Ensures:
411  *\li	The used pointer in 'b' is advanced by 1.
412  */
413 
414 uint16_t
415 isc_buffer_getuint16(isc_buffer_t *b);
416 /*!<
417  * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
418  * it to host byte order, and return it.
419  *
420  * Requires:
421  *
422  *\li	'b' is a valid buffer.
423  *
424  *\li	The length of the available region of 'b' is at least 2.
425  *
426  * Ensures:
427  *
428  *\li	The current pointer in 'b' is advanced by 2.
429  *
430  * Returns:
431  *
432  *\li	A 16-bit unsigned integer.
433  */
434 
435 void
436 isc__buffer_putuint16(isc_buffer_t *b, uint16_t val);
437 /*!<
438  * \brief Store an unsigned 16-bit integer in host byte order from 'val'
439  * into 'b' in network byte order.
440  *
441  * Requires:
442  *\li	'b' is a valid buffer.
443  *
444  *\li	The length of the unused region of 'b' is at least 2.
445  *
446  * Ensures:
447  *\li	The used pointer in 'b' is advanced by 2.
448  */
449 
450 uint32_t
451 isc_buffer_getuint32(isc_buffer_t *b);
452 /*!<
453  * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
454  * it to host byte order, and return it.
455  *
456  * Requires:
457  *
458  *\li	'b' is a valid buffer.
459  *
460  *\li	The length of the available region of 'b' is at least 4.
461  *
462  * Ensures:
463  *
464  *\li	The current pointer in 'b' is advanced by 4.
465  *
466  * Returns:
467  *
468  *\li	A 32-bit unsigned integer.
469  */
470 
471 void
472 isc__buffer_putuint32(isc_buffer_t *b, uint32_t val);
473 /*!<
474  * \brief Store an unsigned 32-bit integer in host byte order from 'val'
475  * into 'b' in network byte order.
476  *
477  * Requires:
478  *\li	'b' is a valid buffer.
479  *
480  *\li	The length of the unused region of 'b' is at least 4.
481  *
482  * Ensures:
483  *\li	The used pointer in 'b' is advanced by 4.
484  */
485 
486 void
487 isc__buffer_putuint48(isc_buffer_t *b, uint64_t val);
488 /*!<
489  * \brief Store an unsigned 48-bit integer in host byte order from 'val'
490  * into 'b' in network byte order.
491  *
492  * Requires:
493  *\li	'b' is a valid buffer.
494  *
495  *\li	The length of the unused region of 'b' is at least 6.
496  *
497  * Ensures:
498  *\li	The used pointer in 'b' is advanced by 6.
499  */
500 
501 void
502 isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
503 		   unsigned int length);
504 /*!<
505  * \brief Copy 'length' bytes of memory at 'base' into 'b'.
506  *
507  * Requires:
508  *\li	'b' is a valid buffer.
509  *
510  *\li	'base' points to 'length' bytes of valid memory.
511  *
512  */
513 
514 void
515 isc__buffer_putstr(isc_buffer_t *b, const char *source);
516 /*!<
517  * \brief Copy 'source' into 'b', not including terminating NUL.
518  *
519  * Requires:
520  *\li	'b' is a valid buffer.
521  *
522  *\li	'source' to be a valid NULL terminated string.
523  *
524  *\li	strlen(source) <= isc_buffer_available(b)
525  */
526 
527 isc_result_t
528 isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
529 /*!<
530  * \brief Copy the contents of 'r' into 'b'.
531  *
532  * Requires:
533  *\li	'b' is a valid buffer.
534  *
535  *\li	'r' is a valid region.
536  *
537  * Returns:
538  *
539  *\li	ISC_R_SUCCESS
540  *\li	ISC_R_NOSPACE			The available region of 'b' is not
541  *					big enough.
542  */
543 
544 /*
545  * Inline macro versions of the functions.  These should never be called
546  * directly by an application, but will be used by the functions within
547  * buffer.c.  The callers should always use "isc_buffer_*()" names, never
548  * ones beginning with "isc__"
549  */
550 
551 /*! \note
552  * XXXDCL Something more could be done with initializing buffers that
553  * point to const data.  For example, isc_buffer_constinit() could
554  * set a new boolean flag in the buffer structure indicating whether
555  * the buffer was initialized with that function.  * Then if the
556  * boolean were true, the isc_buffer_put* functions could assert a
557  * contractual requirement for a non-const buffer.
558  *
559  * One drawback is that the isc_buffer_* functions (macros) that return
560  * pointers would still need to return non-const pointers to avoid compiler
561  * warnings, so it would be up to code that uses them to have to deal
562  * with the possibility that the buffer was initialized as const --
563  * a problem that they *already* have to deal with but have absolutely
564  * no ability to.  With a new isc_buffer_isconst() function returning
565  * true/false, they could at least assert a contractual requirement for
566  * non-const buffers when needed.
567  */
568 #define ISC__BUFFER_INIT(_b, _base, _length) \
569 	do { \
570 		(_b)->base = _base; \
571 		(_b)->length = (_length); \
572 		(_b)->used = 0; \
573 		(_b)->current = 0; \
574 		(_b)->active = 0; \
575 		ISC_LINK_INIT(_b, link); \
576 	} while (0)
577 
578 #define ISC__BUFFER_INVALIDATE(_b) \
579 	do { \
580 		(_b)->base = NULL; \
581 		(_b)->length = 0; \
582 		(_b)->used = 0; \
583 		(_b)->current = 0; \
584 		(_b)->active = 0; \
585 	} while (0)
586 
587 #define ISC__BUFFER_USEDREGION(_b, _r) \
588 	do { \
589 		(_r)->base = (_b)->base; \
590 		(_r)->length = (_b)->used; \
591 	} while (0)
592 
593 #define ISC__BUFFER_AVAILABLEREGION(_b, _r) \
594 	do { \
595 		(_r)->base = isc_buffer_used(_b); \
596 		(_r)->length = isc_buffer_availablelength(_b); \
597 	} while (0)
598 
599 #define ISC__BUFFER_ADD(_b, _n) \
600 	do { \
601 		(_b)->used += (_n); \
602 	} while (0)
603 
604 #define ISC__BUFFER_SUBTRACT(_b, _n) \
605 	do { \
606 		(_b)->used -= (_n); \
607 		if ((_b)->current > (_b)->used) \
608 			(_b)->current = (_b)->used; \
609 		if ((_b)->active > (_b)->used) \
610 			(_b)->active = (_b)->used; \
611 	} while (0)
612 
613 #define ISC__BUFFER_CLEAR(_b) \
614 	do { \
615 		(_b)->used = 0; \
616 		(_b)->current = 0; \
617 		(_b)->active = 0; \
618 	} while (0)
619 
620 #define ISC__BUFFER_REMAININGREGION(_b, _r) \
621 	do { \
622 		(_r)->base = isc_buffer_current(_b); \
623 		(_r)->length = isc_buffer_remaininglength(_b); \
624 	} while (0)
625 
626 #define ISC__BUFFER_ACTIVEREGION(_b, _r) \
627 	do { \
628 		if ((_b)->current < (_b)->active) { \
629 			(_r)->base = isc_buffer_current(_b); \
630 			(_r)->length = isc_buffer_activelength(_b); \
631 		} else { \
632 			(_r)->base = NULL; \
633 			(_r)->length = 0; \
634 		} \
635 	} while (0)
636 
637 #define ISC__BUFFER_SETACTIVE(_b, _n) \
638 	do { \
639 		(_b)->active = (_b)->current + (_n); \
640 	} while (0)
641 
642 #define ISC__BUFFER_FIRST(_b) \
643 	do { \
644 		(_b)->current = 0; \
645 	} while (0)
646 
647 #define ISC__BUFFER_FORWARD(_b, _n) \
648 	do { \
649 		(_b)->current += (_n); \
650 	} while (0)
651 
652 #define ISC__BUFFER_PUTMEM(_b, _base, _length) \
653 	do { \
654 		memmove(isc_buffer_used(_b), (_base), (_length)); \
655 		(_b)->used += (_length); \
656 	} while (0)
657 
658 #define ISC__BUFFER_PUTSTR(_b, _source) \
659 	do { \
660 		unsigned int _length; \
661 		unsigned char *_cp; \
662 		_length = (unsigned int)strlen(_source); \
663 		_cp = isc_buffer_used(_b); \
664 		memmove(_cp, (_source), _length); \
665 		(_b)->used += (_length); \
666 	} while (0)
667 
668 #define ISC__BUFFER_PUTUINT8(_b, _val) \
669 	do { \
670 		unsigned char *_cp; \
671 		uint8_t _val2 = (_val); \
672 		_cp = isc_buffer_used(_b); \
673 		(_b)->used++; \
674 		_cp[0] = _val2 & 0x00ff; \
675 	} while (0)
676 
677 #define ISC__BUFFER_PUTUINT16(_b, _val) \
678 	do { \
679 		unsigned char *_cp; \
680 		uint16_t _val2 = (_val); \
681 		_cp = isc_buffer_used(_b); \
682 		(_b)->used += 2; \
683 		_cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
684 		_cp[1] = (unsigned char)(_val2 & 0x00ffU); \
685 	} while (0)
686 
687 #define ISC__BUFFER_PUTUINT32(_b, _val) \
688 	do { \
689 		unsigned char *_cp; \
690 		uint32_t _val2 = (_val); \
691 		_cp = isc_buffer_used(_b); \
692 		(_b)->used += 4; \
693 		_cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
694 		_cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
695 		_cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
696 		_cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
697 	} while (0)
698 
699 #define isc_buffer_init			isc__buffer_init
700 #define isc_buffer_invalidate		isc__buffer_invalidate
701 #define isc_buffer_usedregion		isc__buffer_usedregion
702 #define isc_buffer_availableregion	isc__buffer_availableregion
703 #define isc_buffer_add			isc__buffer_add
704 #define isc_buffer_subtract		isc__buffer_subtract
705 #define isc_buffer_clear		isc__buffer_clear
706 #define isc_buffer_remainingregion	isc__buffer_remainingregion
707 #define isc_buffer_activeregion		isc__buffer_activeregion
708 #define isc_buffer_setactive		isc__buffer_setactive
709 #define isc_buffer_first		isc__buffer_first
710 #define isc_buffer_forward		isc__buffer_forward
711 #define isc_buffer_putmem		isc__buffer_putmem
712 #define isc_buffer_putstr		isc__buffer_putstr
713 #define isc_buffer_putuint8		isc__buffer_putuint8
714 #define isc_buffer_putuint16		isc__buffer_putuint16
715 #define isc_buffer_putuint32		isc__buffer_putuint32
716 #define isc_buffer_putuint48		isc__buffer_putuint48
717 
718 isc_result_t
719 isc_mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
720 
721 /* this used to be str_totext() in rdata.c etc. */
722 isc_result_t
723 isc_str_tobuffer(const char *source, isc_buffer_t *target);
724 #endif /* ISC_BUFFER_H */
725