26 RCSIDH(dbuff_h,
"$Id: 348a481e9e6eb2b98cfb3ff3847db2339c8f392a $")
33 #include <freeradius-devel/missing.h>
34 #include <freeradius-devel/util/debug.h>
35 #include <freeradius-devel/util/nbo.h>
39 #include <sys/types.h>
113 struct fr_dbuff_marker_s {
124 #define FR_DBUFF_ADV_PARENT_CURRENT 0x01
126 #define FR_DBUFF_ADV_PARENT_END 0x02
184 #define FR_DBUFF_RETURN(_func, ...) \
186 ssize_t _slen = _func(__VA_ARGS__ ); \
187 if (_slen < 0) return _slen; \
200 #define _FR_DBUFF(_dbuff_or_marker, _start, _adv_parent) \
202 .buff = fr_dbuff_buff(_dbuff_or_marker), \
204 .end = fr_dbuff_end(_dbuff_or_marker), \
205 .p = fr_dbuff_current(_dbuff_or_marker), \
206 .is_const = fr_dbuff_ptr(_dbuff_or_marker)->is_const, \
207 .adv_parent = (_adv_parent), \
208 .shifted = fr_dbuff_ptr(_dbuff_or_marker)->shifted, \
209 .extend = fr_dbuff_ptr(_dbuff_or_marker)->extend, \
210 .uctx = fr_dbuff_ptr(_dbuff_or_marker)->uctx, \
211 .parent = fr_dbuff_ptr(_dbuff_or_marker) \
222 #define FR_DBUFF(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), 0x00)
231 #define FR_DBUFF_ABS(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), 0x00)
240 #define FR_DBUFF_BIND_CURRENT(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT)
249 #define FR_DBUFF_BIND_CURRENT_ABS(_dbuff_or_marker) FR_DBUFF_ABS(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT)
260 #define FR_DBUFF_BIND_END_ABS(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_END)
267 #define _FR_DBUFF_MAX(_dbuff_or_marker, _max, _adv_parent) \
269 .buff = fr_dbuff_buff(_dbuff_or_marker), \
270 .start = fr_dbuff_current(_dbuff_or_marker), \
271 .end = (((fr_dbuff_end(_dbuff_or_marker) - (_max) < fr_dbuff_current(_dbuff_or_marker))) ? fr_dbuff_end(_dbuff_or_marker) : (fr_dbuff_current(_dbuff_or_marker) + (_max))), \
272 .p = fr_dbuff_current(_dbuff_or_marker), \
273 .is_const = fr_dbuff_ptr(_dbuff_or_marker)->is_const, \
274 .adv_parent = _adv_parent, \
275 .shifted = fr_dbuff_ptr(_dbuff_or_marker)->shifted, \
278 .parent = fr_dbuff_ptr(_dbuff_or_marker) \
301 #define FR_DBUFF_MAX(_dbuff_or_marker, _max) _FR_DBUFF_MAX(_dbuff_or_marker, _max, 0x00)
318 #define FR_DBUFF_MAX_BIND_CURRENT(_dbuff_or_marker, _max) _FR_DBUFF_MAX(_dbuff_or_marker, _max, FR_DBUFF_ADV_PARENT_CURRENT)
324 #if defined(__GNUC__) && __GNUC__ >= 11
336 if (
unlikely(end < start)) end = start;
354 #define fr_dbuff_init(_out, _start, _len_or_end) \
355 _fr_dbuff_init(_out, \
356 (uint8_t const *)(_start), \
357 _Generic((_len_or_end), \
358 size_t : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
359 long : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
360 int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
361 unsigned int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
362 uint8_t * : (uint8_t const *)(_len_or_end), \
363 uint8_t const * : (uint8_t const *)(_len_or_end), \
364 char * : (uint8_t const *)(_len_or_end), \
365 char const * : (uint8_t const *)(_len_or_end) \
369 uint8_t const * : true, \
371 char const * : true \
373 #if defined(__GNUC__) && __GNUC__ >= 11
377 #define FR_DBUFF_INIT(_out, _start, _len_or_end) do { \
378 fr_dbuff_init(_out, _start, _len_or_end); \
379 *(unsigned char *) _start = '\0'; \
398 } fr_dbuff_uctx_talloc_t;
412 fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx,
413 size_t init,
size_t max)
417 *tctx = (fr_dbuff_uctx_talloc_t){
434 memset(dbuff, 0,
sizeof(*dbuff));
455 TALLOC_FREE(dbuff->buff);
470 } fr_dbuff_uctx_fd_t;
488 *fctx = (fr_dbuff_uctx_fd_t){
491 .buff_end =
buff + len
514 #define FR_DBUFF_TMP(_start, _len_or_end) \
516 .buff_i = (uint8_t const *)(_start), \
517 .start_i = (uint8_t const *)(_start), \
518 .end_i = _Generic((_len_or_end), \
519 size_t : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
520 long : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
521 int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
522 unsigned int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \
523 uint8_t * : (uint8_t const *)(_len_or_end), \
524 uint8_t const * : (uint8_t const *)(_len_or_end), \
525 char * : (uint8_t const *)(_len_or_end), \
526 char const * : (uint8_t const *)(_len_or_end) \
529 .is_const = _Generic((_start), \
531 uint8_t const * : true, \
533 char const * : true \
556 #define FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max) \
558 static _Thread_local fr_dbuff_thread_local_t *_dbuff_t_local; \
559 if (!_dbuff_t_local) { \
560 fr_dbuff_thread_local_t *dbtl = talloc_zero(NULL, fr_dbuff_thread_local_t); \
561 fr_dbuff_init_talloc(dbtl, &dbtl->dbuff, &dbtl->tctx, _init, _max); \
562 fr_atexit_thread_local(_dbuff_t_local, _dbuff_thread_local_free, dbtl); \
563 *(_out) = &_dbuff_t_local->dbuff; \
565 fr_dbuff_reset_talloc(&_dbuff_t_local->dbuff); \
566 *(_out) = &_dbuff_t_local->dbuff; \
582 #define FR_DBUFF_FLAG_EXTENDABLE 0x01
586 #define FR_DBUFF_FLAG_EXTENDED 0x02
610 #define fr_dbuff_is_extendable(_status) ((_status) & FR_DBUFF_FLAG_EXTENDABLE)
614 #define fr_dbuff_was_extended(_status) ((_status) & FR_DBUFF_FLAG_EXTENDED)
620 size_t remaining,
size_t lowat)
630 if (remaining >= lowat) {
635 if (!
in->extend || !(extended =
in->extend(
in, lowat - remaining)))
goto not_extendable;
639 return remaining + extended;
660 #define fr_dbuff_extend_lowat(_status, _dbuff_or_marker, _lowat) \
661 _fr_dbuff_extend_lowat(_status, \
662 fr_dbuff_ptr(_dbuff_or_marker), \
663 fr_dbuff_remaining(_dbuff_or_marker), _lowat)
673 #define FR_DBUFF_EXTEND_LOWAT_OR_RETURN(_dbuff_or_marker, _lowat) \
675 size_t _remaining = fr_dbuff_extend_lowat(NULL, _dbuff_or_marker, _lowat); \
676 if (_remaining < _lowat) return -(_lowat - _remaining); \
689 #define _FR_DBUFF_EXTEND_LOWAT_POS_OR_RETURN(_pos_p, _dbuff_or_marker, _lowat) \
691 size_t _remaining = _fr_dbuff_extend_lowat(NULL, \
692 fr_dbuff_ptr(_dbuff_or_marker), \
693 fr_dbuff_end(_dbuff_or_marker) - (*(_pos_p)), _lowat); \
694 if (_remaining < _lowat) return -(_lowat - _remaining); \
705 #define fr_dbuff_extend(_dbuff) fr_dbuff_extend_lowat(NULL, _dbuff, 1)
743 #define fr_dbuff_remaining(_dbuff_or_marker) \
744 ((size_t)(fr_dbuff_end(_dbuff_or_marker) < fr_dbuff_current(_dbuff_or_marker) ? \
745 0 : (fr_dbuff_end(_dbuff_or_marker) - fr_dbuff_current(_dbuff_or_marker))))
761 #define FR_DBUFF_REMAINING_RETURN(_dbuff_or_marker, _len) \
762 if ((_len) > fr_dbuff_remaining(_dbuff_or_marker)) return -((_len) - fr_dbuff_remaining(_dbuff_or_marker))
767 #define fr_dbuff_used(_dbuff_or_marker) \
768 ((size_t)(fr_dbuff_start(_dbuff_or_marker) > fr_dbuff_current(_dbuff_or_marker) ? \
769 0 : (fr_dbuff_current(_dbuff_or_marker) - fr_dbuff_start(_dbuff_or_marker))))
776 #define fr_dbuff_len(_dbuff_or_marker) \
777 ((size_t)(fr_dbuff_end(_dbuff_or_marker) - fr_dbuff_start(_dbuff_or_marker)))
786 #define fr_dbuff_behind(_dbuff_or_marker) \
787 (fr_dbuff_current(_dbuff_or_marker) > fr_dbuff_current((_dbuff_or_marker)->parent) ? \
788 0 : fr_dbuff_current((_dbuff_or_marker)->parent) - fr_dbuff_current(_dbuff_or_marker))
796 #define fr_dbuff_ahead(_dbuff_or_marker) \
797 (fr_dbuff_current((_dbuff_or_marker)->parent) > fr_dbuff_current(_dbuff_or_marker) ? \
798 0 : fr_dbuff_current(_dbuff_or_marker) - fr_dbuff_current((_dbuff_or_marker)->parent))
858 #define fr_dbuff_ptr(_dbuff_or_marker) \
859 _Generic((_dbuff_or_marker), \
860 fr_dbuff_t * : ((fr_dbuff_t *)(_dbuff_or_marker)), \
861 fr_dbuff_marker_t * : (((fr_dbuff_marker_t *)(_dbuff_or_marker))->parent) \
869 #define fr_dbuff_ptr_const(_dbuff_or_marker) \
870 _Generic((_dbuff_or_marker), \
871 fr_dbuff_t * : ((fr_dbuff_t const *)(_dbuff_or_marker)), \
872 fr_dbuff_t const * : ((fr_dbuff_t const *)(_dbuff_or_marker)), \
873 fr_dbuff_marker_t * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent), \
874 fr_dbuff_marker_t const * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent) \
882 #define fr_dbuff_buff(_dbuff_or_marker) \
883 _Generic((_dbuff_or_marker), \
884 fr_dbuff_t * : (((fr_dbuff_t const *)(_dbuff_or_marker))->buff), \
885 fr_dbuff_t const * : (((fr_dbuff_t const *)(_dbuff_or_marker))->buff), \
886 fr_dbuff_marker_t * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->buff), \
887 fr_dbuff_marker_t const * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->buff) \
898 #define fr_dbuff_start(_dbuff_or_marker) \
899 (_Generic((_dbuff_or_marker), \
900 fr_dbuff_t * : (((fr_dbuff_t const *)(_dbuff_or_marker))->start), \
901 fr_dbuff_t const * : (((fr_dbuff_t const *)(_dbuff_or_marker))->start), \
902 fr_dbuff_marker_t * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->start), \
903 fr_dbuff_marker_t const * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->start) \
911 #define fr_dbuff_current(_dbuff_or_marker) \
912 (_Generic((_dbuff_or_marker), \
913 fr_dbuff_t * : (((fr_dbuff_t const *)(_dbuff_or_marker))->p), \
914 fr_dbuff_t const * : (((fr_dbuff_t const *)(_dbuff_or_marker))->p), \
915 fr_dbuff_marker_t * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->p), \
916 fr_dbuff_marker_t const * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->p) \
926 #define _fr_dbuff_current_ptr(_dbuff_or_marker) \
927 (_Generic((_dbuff_or_marker), \
928 fr_dbuff_t * : &(((fr_dbuff_t *)(_dbuff_or_marker))->p), \
929 fr_dbuff_marker_t * : &(((fr_dbuff_marker_t *)(_dbuff_or_marker))->p) \
938 #define fr_dbuff_end(_dbuff_or_marker) \
939 (_Generic((_dbuff_or_marker), \
940 fr_dbuff_t * : (((fr_dbuff_t const *)(_dbuff_or_marker))->end), \
941 fr_dbuff_t const * : (((fr_dbuff_t const *)(_dbuff_or_marker))->end), \
942 fr_dbuff_marker_t * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->end), \
943 fr_dbuff_marker_t const * : (((fr_dbuff_marker_t const *)(_dbuff_or_marker))->parent->end) \
961 if (dbuff->adv_parent && dbuff->parent) _fr_dbuff_set_recurse(dbuff->parent, dbuff->adv_parent, p);
980 if (
unlikely(p > dbuff->end))
return -(p - dbuff->end);
981 if (
unlikely(p < dbuff->start))
return 0;
984 if (dbuff->adv_parent && dbuff->parent) _fr_dbuff_set_recurse(dbuff->parent, dbuff->adv_parent, p);
1004 #define fr_dbuff_set(_dst, _src) \
1006 _fr_dbuff_current_ptr(_dst), fr_dbuff_ptr(_dst), \
1008 fr_dbuff_t * : fr_dbuff_current((fr_dbuff_t const *)(_src)), \
1009 fr_dbuff_marker_t * : fr_dbuff_current((fr_dbuff_marker_t const *)(_src)), \
1010 uint8_t const * : (uint8_t const *)(_src), \
1011 uint8_t * : (uint8_t const *)(_src), \
1012 size_t : (fr_dbuff_start(_dst) + (uintptr_t)(_src)), \
1013 long : (fr_dbuff_start(_dst) + (uintptr_t)(_src)), \
1014 int : (fr_dbuff_start(_dst) + (uintptr_t)(_src)) \
1022 #define FR_DBUFF_SET_RETURN(_dst, _src) FR_DBUFF_RETURN(fr_dbuff_set, _dst, _src)
1035 if (
unlikely(p > dbuff->end))
return -(p - dbuff->end);
1036 if (
unlikely(p < dbuff->start))
return 0;
1040 return dbuff->end - p;
1051 #define fr_dbuff_set_end(_dst, _end) \
1053 fr_dbuff_ptr(_dst), \
1055 fr_dbuff_t * : fr_dbuff_current((fr_dbuff_t const *)(_end)), \
1056 fr_dbuff_marker_t * : fr_dbuff_current((fr_dbuff_marker_t const *)(_end)), \
1057 uint8_t const * : (uint8_t const *)(_end), \
1058 uint8_t * : (uint8_t const *)(_end) \
1072 #define fr_dbuff_advance(_dbuff_or_marker, _len) \
1073 fr_dbuff_set(_dbuff_or_marker, \
1074 (fr_dbuff_current(_dbuff_or_marker) + \
1076 unsigned char : (size_t)(_len), \
1077 unsigned short : (size_t)(_len), \
1078 unsigned int : (size_t)(_len), \
1079 unsigned long : (size_t)(_len), \
1080 unsigned long long : (size_t)(_len), \
1081 int : (size_t)(_len) \
1088 #define FR_DBUFF_ADVANCE_RETURN(_dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_advance, _dbuff_or_marker, _len)
1108 if (p > dbuff->end) {
1109 size_t rel = p - dbuff->start;
1111 if (!dbuff->extend) {
1113 return -((dbuff->start + rel) - dbuff->end);
1116 dbuff->extend(dbuff, p - dbuff->end);
1117 if ((dbuff->start + rel) > dbuff->end)
goto oos;
1119 *pos_p = dbuff->start + rel;
1124 if (dbuff->adv_parent && dbuff->parent) _fr_dbuff_set_recurse(dbuff->parent, dbuff->adv_parent, *pos_p);
1139 #define fr_dbuff_advance_extend(_dbuff_or_marker, _len) \
1140 _fr_dbuff_advance(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), \
1142 unsigned char : (size_t)(_len), \
1143 unsigned short : (size_t)(_len), \
1144 unsigned int : (size_t)(_len), \
1145 unsigned long : (size_t)(_len), \
1146 unsigned long long : (size_t)(_len), \
1147 int : (size_t)(_len) \
1150 #define FR_DBUFF_BIND_EXTEND_RETURN(_dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_advance_extend, _dbuff_or_marker, _len)
1155 #define fr_dbuff_set_to_start(_dbuff_or_marker) \
1156 fr_dbuff_set(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker))
1161 #define fr_dbuff_set_to_end(_dbuff_or_marker) \
1162 fr_dbuff_set(_dbuff_or_marker, fr_dbuff_end(_dbuff_or_marker))
1212 m->parent->m = m->next;
1215 memset(m, 0,
sizeof(*m));
1274 static inline CC_HINT(always_inline)
size_t _fr_dbuff_safecpy(
uint8_t *o_start,
uint8_t *o_end,
1278 size_t i_len = i_end - i_start;
1280 if (
unlikely((o_end < o_start) || (i_end < i_start)))
return 0;
1282 diff = (o_end - o_start) - (i_len);
1283 if (diff < 0)
return 0;
1285 if ((i_start > o_end) || (i_end < o_start)) {
1286 memcpy(o_start, i_start, i_len);
1288 memmove(o_start, i_start, i_len);
1303 _FR_DBUFF_EXTEND_LOWAT_POS_OR_RETURN(pos_p,
out,
inlen);
1305 return _fr_dbuff_set(pos_p,
out, (*pos_p) + _fr_dbuff_safecpy((*pos_p), (*pos_p) +
inlen,
in,
in +
inlen));
1319 memcpy(&our_in, &
in,
sizeof(our_in));
1320 memcpy(&our_in_p, &in_p,
sizeof(our_in_p));
1322 if (
inlen == SIZE_MAX) {
1323 ext_len = _fr_dbuff_extend_lowat(NULL, our_in,
fr_dbuff_end(our_in) - (*our_in_p),
inlen);
1326 _FR_DBUFF_EXTEND_LOWAT_POS_OR_RETURN(our_in_p, our_in,
inlen);
1328 return _fr_dbuff_in_memcpy(pos_p,
out, *our_in_p,
inlen);
1350 #define fr_dbuff_in_memcpy(_dbuff_or_marker, _in, _inlen) \
1352 uint8_t * : _fr_dbuff_in_memcpy(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1353 fr_dbuff_ptr(_dbuff_or_marker), \
1354 (uint8_t const *)(_in), \
1356 uint8_t const * : _fr_dbuff_in_memcpy(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1357 fr_dbuff_ptr(_dbuff_or_marker), \
1358 (uint8_t const *)(_in), \
1360 char * : _fr_dbuff_in_memcpy(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1361 fr_dbuff_ptr(_dbuff_or_marker), \
1362 (uint8_t const *)(_in), \
1363 (size_t)(_inlen) == SIZE_MAX ? strlen((char const *)(_in)) : (_inlen)), \
1364 char const * : _fr_dbuff_in_memcpy(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1365 fr_dbuff_ptr(_dbuff_or_marker), \
1366 (uint8_t const *)(_in), \
1367 (size_t)(_inlen) == SIZE_MAX ? strlen((char const *)(_in)) : (_inlen)), \
1368 fr_dbuff_t * : _fr_dbuff_in_memcpy_dbuff(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1369 fr_dbuff_ptr(_dbuff_or_marker), \
1370 &((fr_dbuff_t const *)(_in))->p, \
1371 ((fr_dbuff_t const *)(_in)), \
1373 fr_dbuff_marker_t * : _fr_dbuff_in_memcpy_dbuff(_fr_dbuff_current_ptr(_dbuff_or_marker), \
1374 fr_dbuff_ptr(_dbuff_or_marker), \
1375 &((fr_dbuff_marker_t const *)(_in))->p, \
1376 ((fr_dbuff_marker_t const *)(_in))->parent, _inlen) \
1382 #define FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, _in, _inlen) FR_DBUFF_RETURN(fr_dbuff_in_memcpy, _dbuff_or_marker, _in, _inlen)
1398 return _fr_dbuff_set(pos_p,
out, (*pos_p) + _fr_dbuff_safecpy((*pos_p), (*pos_p) +
inlen,
in,
in +
inlen));
1412 ext_len = _fr_dbuff_extend_lowat(NULL, our_in,
fr_dbuff_end(our_in) - (*our_in_p),
inlen);
1415 return _fr_dbuff_in_memcpy_partial(pos_p,
out, (*our_in_p),
inlen);
1438 #define fr_dbuff_in_memcpy_partial(_out, _in, _inlen) \
1440 uint8_t * : _fr_dbuff_in_memcpy_partial(_fr_dbuff_current_ptr(_out), _out, (uint8_t const *)(_in), _inlen), \
1441 uint8_t const * : _fr_dbuff_in_memcpy_partial(_fr_dbuff_current_ptr(_out), _out, (uint8_t const *)(_in), _inlen), \
1442 char * : _fr_dbuff_in_memcpy_partial(_fr_dbuff_current_ptr(_out), _out, (uint8_t const *)(_in), _inlen == SIZE_MAX ? strlen((char const *)(_in)) : _inlen), \
1443 char const * : _fr_dbuff_in_memcpy_partial(_fr_dbuff_current_ptr(_out), _out, (uint8_t const *)(_in), _inlen == SIZE_MAX ? strlen((char const *)(_in)) : _inlen), \
1444 fr_dbuff_t * : _fr_dbuff_in_memcpy_partial_dbuff(_fr_dbuff_current_ptr(_out), fr_dbuff_ptr(_out), &((fr_dbuff_t const *)(_in))->p, ((fr_dbuff_t const *)(_in)), _inlen), \
1445 fr_dbuff_marker_t * : _fr_dbuff_in_memcpy_partial_dbuff(_fr_dbuff_current_ptr(_out), fr_dbuff_ptr(_out), &((fr_dbuff_marker_t const *)(_in))->p, ((fr_dbuff_marker_t const *)(_in))->parent, _inlen) \
1455 #define fr_dbuff_in_bytes_partial(_dbuff, ...) \
1456 fr_dbuff_in_memcpy_partial(_dbuff, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ }))
1465 #define fr_dbuff_in_bytes(_dbuff_or_marker, ...) \
1466 fr_dbuff_in_memcpy(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ }))
1472 #define FR_DBUFF_IN_BYTES_RETURN(_dbuff_or_marker, ...) \
1473 FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ }))
1483 _FR_DBUFF_EXTEND_LOWAT_POS_OR_RETURN(pos_p, dbuff,
inlen);
1485 memset((*pos_p), c,
inlen);
1487 return _fr_dbuff_set(pos_p, dbuff, (*pos_p) +
inlen);
1501 #define fr_dbuff_memset(_dbuff_or_marker, _c, _inlen) \
1502 _fr_dbuff_memset(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _c, _inlen)
1508 #define FR_DBUFF_MEMSET_RETURN(_dbuff_or_marker, _c, _inlen) FR_DBUFF_RETURN(fr_dbuff_memset, _dbuff_or_marker, _c, _inlen)
1514 #define FR_DBUFF_PARSE_INT_DEF(_type) \
1515 static inline ssize_t _fr_dbuff_in_##_type(uint8_t **pos_p, fr_dbuff_t *out, _type##_t num) \
1517 fr_assert(!out->is_const); \
1518 _FR_DBUFF_EXTEND_LOWAT_POS_OR_RETURN(pos_p, out, sizeof(_type##_t)); \
1519 fr_nbo_from_##_type((*pos_p), num); \
1520 return _fr_dbuff_set(pos_p, out, (*pos_p) + sizeof(_type##_t)); \
1522 FR_DBUFF_PARSE_INT_DEF(uint16)
1523 FR_DBUFF_PARSE_INT_DEF(uint32)
1524 FR_DBUFF_PARSE_INT_DEF(uint64)
1525 FR_DBUFF_PARSE_INT_DEF(int16)
1526 FR_DBUFF_PARSE_INT_DEF(int32)
1527 FR_DBUFF_PARSE_INT_DEF(int64)
1544 return _fr_dbuff_in_uint32(pos_p,
out, *(
uint32_t *)(&num));
1555 return _fr_dbuff_in_uint64(pos_p,
out, *(uint64_t *)(&num));
1567 #define fr_dbuff_in(_dbuff_or_marker, _in) \
1569 int8_t : fr_dbuff_in_bytes(_dbuff_or_marker, (int8_t)_in), \
1570 int16_t : _fr_dbuff_in_int16(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (int16_t)_in), \
1571 int32_t : _fr_dbuff_in_int32(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (int32_t)_in), \
1572 int64_t : _fr_dbuff_in_int64(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (int64_t)_in), \
1573 uint8_t : fr_dbuff_in_bytes(_dbuff_or_marker, (uint8_t)_in), \
1574 uint16_t : _fr_dbuff_in_uint16(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (uint16_t)_in), \
1575 uint32_t : _fr_dbuff_in_uint32(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (uint32_t)_in), \
1576 uint64_t : _fr_dbuff_in_uint64(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (uint64_t)_in), \
1577 float : _fr_dbuff_in_float(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (float)_in), \
1578 double : _fr_dbuff_in_double(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), (double)_in) \
1585 #define FR_DBUFF_IN_RETURN(_dbuff_or_marker, _in) FR_DBUFF_RETURN(fr_dbuff_in, _dbuff_or_marker, _in)
1593 uint8_t swapped[
sizeof(uint64_t)];
1597 if (ret >
sizeof(uint64_t))
return -1;
1601 return _fr_dbuff_in_memcpy(pos_p, dbuff, (swapped + (
sizeof(uint64_t) - ret)), ret);
1612 #define fr_dbuff_in_uint64v(_dbuff_or_marker, _num) \
1613 _fr_dbuff_in_uint64v(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _num)
1619 #define FR_DBUFF_IN_UINT64V(_dbuff_or_marker, _num) FR_DBUFF_RETURN(fr_dbuff_in_uint64v, _dbuff_or_marker, _num)
1656 #define fr_dbuff_move(_out, _in, _len) \
1660 fr_dbuff_t * : _fr_dbuff_move_dbuff_to_dbuff((fr_dbuff_t *)_out, \
1661 (fr_dbuff_t *)_in, \
1663 fr_dbuff_marker_t * : _fr_dbuff_move_dbuff_marker_to_dbuff((fr_dbuff_t *)_out, \
1664 (fr_dbuff_marker_t *)_in, \
1667 fr_dbuff_marker_t * : \
1669 fr_dbuff_t * : _fr_dbuff_move_dbuff_to_dbuff_marker((fr_dbuff_marker_t *)_out, \
1670 (fr_dbuff_t *)_in, \
1672 fr_dbuff_marker_t * : _fr_dbuff_move_dbuff_marker_to_dbuff_marker((fr_dbuff_marker_t *)_out, \
1673 (fr_dbuff_marker_t *)_in, \
1689 size_t ext_len, to_copy, remaining;
1691 for (remaining = outlen; remaining > 0; remaining -= to_copy) {
1692 to_copy = remaining;
1693 ext_len = _fr_dbuff_extend_lowat(NULL,
in,
fr_dbuff_end(
in) - (*pos_p), 1);
1694 if (ext_len == 0)
return -remaining;
1695 if (ext_len < to_copy) to_copy = ext_len;
1696 out += _fr_dbuff_set(pos_p,
in,
1697 (*pos_p) + _fr_dbuff_safecpy(
out,
out + to_copy, (*pos_p), (*pos_p) + to_copy));
1708 if (outlen == SIZE_MAX) outlen = _fr_dbuff_extend_lowat(NULL,
out,
fr_dbuff_end(
out) - (*out_p), outlen);
1710 return _fr_dbuff_out_memcpy((*out_p), pos_p,
in, outlen);
1732 #define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen) \
1734 uint8_t * : _fr_dbuff_out_memcpy((uint8_t *)(_out), \
1735 _fr_dbuff_current_ptr(_dbuff_or_marker), \
1736 fr_dbuff_ptr(_dbuff_or_marker), \
1738 fr_dbuff_t * : _fr_dbuff_out_memcpy_dbuff(_fr_dbuff_current_ptr((fr_dbuff_t *)_out), \
1739 fr_dbuff_ptr((fr_dbuff_t *)(_out)), \
1740 _fr_dbuff_current_ptr(_dbuff_or_marker), \
1741 fr_dbuff_ptr(_dbuff_or_marker), _outlen), \
1742 fr_dbuff_marker_t * : _fr_dbuff_out_memcpy_dbuff(_fr_dbuff_current_ptr((fr_dbuff_marker_t *)_out), \
1743 fr_dbuff_ptr((fr_dbuff_marker_t *)(_out)), \
1744 _fr_dbuff_current_ptr(_dbuff_or_marker), \
1745 fr_dbuff_ptr(_dbuff_or_marker), _outlen) \
1752 #define FR_DBUFF_OUT_MEMCPY_RETURN(_out, _dbuff_or_marker, _outlen) FR_DBUFF_RETURN(fr_dbuff_out_memcpy, _out, _dbuff_or_marker, _outlen)
1758 #define FR_DBUFF_OUT_DEF(_type) \
1759 static inline ssize_t _fr_dbuff_out_##_type(_type##_t *out, uint8_t **pos_p, fr_dbuff_t *in) \
1762 FR_DBUFF_EXTEND_LOWAT_OR_RETURN(in, sizeof(_type##_t)); \
1763 *out = fr_nbo_to_##_type((*pos_p)); \
1764 return _fr_dbuff_set(pos_p, in, (*pos_p) + sizeof(_type##_t)); \
1767 FR_DBUFF_OUT_DEF(uint16)
1768 FR_DBUFF_OUT_DEF(uint32)
1769 FR_DBUFF_OUT_DEF(uint64)
1770 FR_DBUFF_OUT_DEF(int16)
1771 FR_DBUFF_OUT_DEF(int32)
1772 FR_DBUFF_OUT_DEF(int64)
1774 #define FR_DBUFF_OUT_DEF_NO_SWAP(_type) \
1775 static inline ssize_t _fr_dbuff_out_##_type(_type##_t *out, uint8_t **pos_p, fr_dbuff_t *in) \
1778 FR_DBUFF_EXTEND_LOWAT_OR_RETURN(in, sizeof(_type##_t)); \
1780 return _fr_dbuff_set(pos_p, in, (*pos_p) + sizeof(_type##_t)); \
1783 FR_DBUFF_OUT_DEF_NO_SWAP(uint8)
1784 FR_DBUFF_OUT_DEF_NO_SWAP(int8)
1799 #define fr_dbuff_out(_out, _dbuff_or_marker) \
1801 uint8_t * : _fr_dbuff_out_uint8((uint8_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1802 uint16_t * : _fr_dbuff_out_uint16((uint16_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1803 uint32_t * : _fr_dbuff_out_uint32((uint32_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1804 uint64_t * : _fr_dbuff_out_uint64((uint64_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1805 int8_t * : _fr_dbuff_out_int8((int8_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1806 int16_t * : _fr_dbuff_out_int16((int16_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1807 int32_t * : _fr_dbuff_out_int32((int32_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1808 int64_t * : _fr_dbuff_out_int64((int64_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1809 float * : _fr_dbuff_out_uint32((uint32_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)), \
1810 double * : _fr_dbuff_out_uint64((uint64_t *)(_out), _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker)) \
1817 #ifndef STATIC_ANALYZER
1818 #define FR_DBUFF_OUT_RETURN(_out, _dbuff_or_marker) FR_DBUFF_RETURN(fr_dbuff_out, _out, _dbuff_or_marker)
1820 #define FR_DBUFF_OUT_RETURN(_out, _dbuff_or_marker) do { *_out = 0; FR_DBUFF_RETURN(fr_dbuff_out, _out, _dbuff_or_marker); } while (0)
1830 fr_assert(length > 0 && length <=
sizeof(uint64_t));
1833 slen = _fr_dbuff_out_memcpy(((
uint8_t *) num) + (8 - length), pos_p, dbuff, length);
1834 if (slen <= 0)
return slen;
1851 #define fr_dbuff_out_uint64v(_num, _dbuff_or_marker, _len) \
1852 _fr_dbuff_out_uint64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len)
1858 #define FR_DBUFF_OUT_UINT64V_RETURN(_num, _dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_out_uint64v, _num, _dbuff_or_marker, _len)
1868 fr_assert(length > 0 && length <=
sizeof(uint64_t));
1871 slen = _fr_dbuff_out_memcpy(((
uint8_t *) num) + (8 - length), pos_p, dbuff, length);
1872 if (slen <= 0)
return slen;
1874 if (msb & 0x80) memset(((
uint8_t *)num), 0xff,
sizeof(*num) - length);
1891 #define fr_dbuff_out_int64v(_num, _dbuff_or_marker, _len) \
1892 _fr_dbuff_out_int64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len)
1898 #define FR_DBUFF_OUT_INT64V_RETURN(_num, _dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_out_int64v, _num, _dbuff_or_marker, _len)
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
struct fr_dbuff_s fr_dbuff_t
A dbuff.
#define fr_dbuff_behind(_dbuff_or_marker)
How many bytes the dbuff or marker is behind its parent.
#define FR_DBUFF_FLAG_EXTENDED
Flag indicating that during the last extend call the dbuff was extended.
fr_dbuff_uctx_talloc_t tctx
Thread local tctx.
int fr_dbuff_reset_talloc(fr_dbuff_t *dbuff)
Reset a talloced buffer to its initial length, clearing any data stored.
static void fr_dbuff_free_talloc(fr_dbuff_t *dbuff)
Free the talloc buffer associated with a dbuff.
static int _dbuff_thread_local_free(void *dbtl)
static size_t fr_dbuff_marker_release_behind(fr_dbuff_marker_t *m)
Trims the linked list back to the specified pointer and return how many bytes marker was behind p.
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
fr_dbuff_extend_status_t
Whether the buffer is currently extendable and whether it was extended.
@ FR_DBUFF_NOT_EXTENDABLE
dbuff cannot be extended
@ FR_DBUFF_EXTENDED
dbuff was extended in the last extend call but cannot be extended again
@ FR_DBUFF_EXTENDABLE
dbuff can be extended
@ FR_DBUFF_EXTENDABLE_EXTENDED
dbuff was extended in the last extend call and may be extended again
static fr_dbuff_t * fr_dbuff_init_fd(fr_dbuff_t *dbuff, fr_dbuff_uctx_fd_t *fctx, uint8_t *buff, size_t len, int fd, size_t max)
Initialise a special dbuff which automatically reads in more data as the buffer is exhausted.
size_t _fr_dbuff_extend_talloc(fr_dbuff_t *dbuff, size_t extension)
Reallocate the current buffer.
#define fr_dbuff_end(_dbuff_or_marker)
Return the current 'end' position of a dbuff or marker.
#define FR_DBUFF_ADV_PARENT_CURRENT
Advance current position of parent.
int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len)
Trim a talloced dbuff to the minimum length required to represent the contained string.
#define FR_DBUFF_FLAG_EXTENDABLE
Flag indicating a dbuff is extendable.
size_t _fr_dbuff_extend_fd(fr_dbuff_t *dbuff, size_t extension)
Refresh the buffer with more data from the file.
fr_dbuff_t dbuff
Thread local dbuff.
void fr_dbuff_update(fr_dbuff_t *dbuff, uint8_t *new_buff, size_t new_len)
Update all markers and pointers in the set of dbuffs to point to new_buff.
static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max)
Initialise a special dbuff which automatically extends as additional data is written.
static void fr_dbuff_marker_release(fr_dbuff_marker_t *m)
Releases the specified marker and any markers added before it.
#define fr_dbuff_is_extendable(_status)
Check if a dbuff can be extended again.
static uint8_t * fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
Initialises a new marker pointing to the 'current' position of the dbuff.
#define fr_dbuff_ahead(_dbuff_or_marker)
How many bytes the dbuff or marker is ahead of its parent.
static size_t fr_dbuff_marker_release_ahead(fr_dbuff_marker_t *m)
Trims the linked list back to the specified pointer and return how many bytes marker was ahead of p.
#define FR_DBUFF_ADV_PARENT_END
Advance end pointer of parent.
size_t(* fr_dbuff_extend_t)(fr_dbuff_t *dbuff, size_t req_extension)
dbuff extension callback
size_t fr_dbuff_shift(fr_dbuff_t *dbuff, size_t shift)
Shift the contents of the dbuff, returning the number of bytes we managed to shift.
Structure to encapsulate a thread local dbuff information.
fr_dcursor_eval_t void const * uctx
#define ROUND_UP_DIV(_x, _y)
Get the ceiling value of integer division.
static uint8_t fr_high_bit_pos(uint64_t num)
Find the highest order high bit in an unsigned 64 bit integer.
static uint64_t fr_nbo_to_uint64(uint8_t const data[static sizeof(uint64_t)])
Read an unsigned 64bit integer from wire format (big endian)
static void fr_nbo_from_uint64(uint8_t out[static sizeof(uint64_t)], uint64_t num)
Write out an unsigned 64bit integer in wire format (big endian)
#define fr_nbo_to_int64(_x)
static char buff[sizeof("18446744073709551615")+3]
init
Enter the EAP-IDENTITY state.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
static size_t char fr_sbuff_t size_t inlen
static size_t char ** out