Loading...
Searching...
No Matches
utils.h File Reference

Generic utilities (headers). More...

#include <glib.h>
#include <jansson.h>
Include dependency graph for utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  imquic_data
 Generic data buffer. More...
struct  imquic_data_fixed
 Generic fixed size data buffer. More...
struct  imquic_bitstream
 Bitstream abstraction. More...
struct  imquic_json_parameter
 JSON validation parameter. More...

Macros

#define htonll(x)
#define ntohll(x)
#define BYTE_TO_BINARY_PATTERN   "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte)

Functions

void imquic_print_hex (int level, uint8_t *buf, size_t buflen)
 Helper method mostly used for debugging: prints the content of a hex buffer.
const char * imquic_hex_str (uint8_t *buf, size_t buflen, char *buffer, size_t blen)
 Helper method to stringify a buffer to a hex string.
String utilities
size_t imquic_strlcat (char *dest, const char *src, size_t dest_size)
 Helper method to concatenate strings and log an error if truncation occurred.
int imquic_strlcat_fast (char *dest, const char *src, size_t dest_size, size_t *offset)
 Alternative helper method to concatenate strings and log an error if truncation occurred, which uses memccpy instead of g_strlcat and so is supposed to be faster.
64-bit unsigned integers utilities
uint64_t imquic_random_uint64 (void)
 Helper to generate random 64 bit unsigned integers.
uint64_t * imquic_dup_uint64 (uint64_t num)
 Helper to generate an allocated copy of a uint64_t number.
Variable size integers
uint64_t imquic_read_varint (uint8_t *bytes, size_t blen, uint8_t *length)
 Read a variable size integer from a buffer.
uint8_t imquic_write_varint (uint64_t number, uint8_t *bytes, size_t blen)
 Write a variable size integer to a buffer.
uint64_t imquic_read_pfxint (uint8_t n, uint8_t *bytes, size_t blen, uint8_t *length)
 Read a prefixed integer from a buffer (QPACK only).
uint8_t imquic_write_pfxint (uint64_t number, uint8_t n, uint8_t *bytes, size_t blen)
 Write a prefixed integer to a buffer (QPACK only).

JSON utilities (mostly only used for MoQ catalogs, for now)

#define IMQUIC_JSON_STRING   JSON_STRING
#define IMQUIC_JSON_INTEGER   JSON_INTEGER
#define IMQUIC_JSON_OBJECT   JSON_OBJECT
#define IMQUIC_JSON_ARRAY   JSON_ARRAY
#define IMQUIC_JSON_BOOL   JSON_TRUE
#define IMQUIC_JSON_PARAM_REQUIRED   1
#define IMQUIC_JSON_PARAM_POSITIVE   2
#define IMQUIC_JSON_PARAM_NONEMPTY   4
#define IMQUIC_JSON_MISSING_ELEMENT   404
#define IMQUIC_JSON_INVALID_ELEMENT   400
#define IMQUIC_VALIDATE_JSON_OBJECT_FORMAT(missing_format, invalid_format, obj, params, res)
 Validates the JSON object against the description of its parameters.
#define IMQUIC_VALIDATE_JSON_OBJECT(obj, params, res)
 Validates the JSON object against the description of its parameters.
typedef struct imquic_json_parameter imquic_json_parameter
 JSON validation parameter.
void imquic_get_json_type_name (int jtype, unsigned int flags, char *type_name)
 Creates a string describing the JSON type and constraint.
gboolean imquic_json_is_valid (json_t *val, json_type jtype, unsigned int flags)
 Checks whether the JSON value matches the type and constraint.

Generic data buffer

typedef struct imquic_data imquic_data
 Generic data buffer.
typedef struct imquic_data_fixed imquic_data_fixed
 Generic fixed size data buffer.
imquic_data * imquic_data_create (uint8_t *buffer, size_t length)
 Helper method to create a data buffer out of existing data.
gboolean imquic_data_equal (const void *a, const void *b)
 Helper comparator function, to check if two buffers contain the same data.
void imquic_data_destroy (imquic_data *data)
 Helper method to free an existing data buffer.

Bitstream (currently only used for Huffman in QPACK)

typedef struct imquic_bitstream imquic_bitstream
 Bitstream abstraction.
uint8_t imquic_bitstream_peek (imquic_bitstream *bs, uint8_t *len)
 Helper method to peek 8 bit in the bitstream.
size_t imquic_bitstream_write (imquic_bitstream *bs, uint32_t value, uint8_t bits)
 Helper method to add bits to a bitstream buffer.

Detailed Description

Generic utilities (headers).

Author
Lorenzo Miniero loren.nosp@m.zo@m.nosp@m.eetec.nosp@m.ho.c.nosp@m.om

Implementation of a few more generic functionality that is useful in the QUIC stack internals (e.g., varint support).

Macro Definition Documentation

◆ BYTE_TO_BINARY

#define BYTE_TO_BINARY ( byte)
Value:
((byte) & 0x80 ? '1' : '0'), \
((byte) & 0x40 ? '1' : '0'), \
((byte) & 0x20 ? '1' : '0'), \
((byte) & 0x10 ? '1' : '0'), \
((byte) & 0x08 ? '1' : '0'), \
((byte) & 0x04 ? '1' : '0'), \
((byte) & 0x02 ? '1' : '0'), \
((byte) & 0x01 ? '1' : '0')

◆ BYTE_TO_BINARY_PATTERN

#define BYTE_TO_BINARY_PATTERN   "%c%c%c%c%c%c%c%c"

◆ htonll

#define htonll ( x)
Value:
((1==htonl(1)) ? (x) : ((guint64)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))

◆ IMQUIC_JSON_ARRAY

#define IMQUIC_JSON_ARRAY   JSON_ARRAY

◆ IMQUIC_JSON_BOOL

#define IMQUIC_JSON_BOOL   JSON_TRUE

◆ IMQUIC_JSON_INTEGER

#define IMQUIC_JSON_INTEGER   JSON_INTEGER

◆ IMQUIC_JSON_INVALID_ELEMENT

#define IMQUIC_JSON_INVALID_ELEMENT   400

◆ IMQUIC_JSON_MISSING_ELEMENT

#define IMQUIC_JSON_MISSING_ELEMENT   404

◆ IMQUIC_JSON_OBJECT

#define IMQUIC_JSON_OBJECT   JSON_OBJECT

◆ IMQUIC_JSON_PARAM_NONEMPTY

#define IMQUIC_JSON_PARAM_NONEMPTY   4

◆ IMQUIC_JSON_PARAM_POSITIVE

#define IMQUIC_JSON_PARAM_POSITIVE   2

◆ IMQUIC_JSON_PARAM_REQUIRED

#define IMQUIC_JSON_PARAM_REQUIRED   1

◆ IMQUIC_JSON_STRING

#define IMQUIC_JSON_STRING   JSON_STRING

◆ IMQUIC_VALIDATE_JSON_OBJECT

#define IMQUIC_VALIDATE_JSON_OBJECT ( obj,
params,
res )
Value:
IMQUIC_VALIDATE_JSON_OBJECT_FORMAT("Missing mandatory element (%s)", "Invalid element type (%s should be %s)", obj, params, res)
#define IMQUIC_VALIDATE_JSON_OBJECT_FORMAT(missing_format, invalid_format, obj, params, res)
Validates the JSON object against the description of its parameters.
Definition utils.h:234

Validates the JSON object against the description of its parameters.

Parameters
objThe JSON object to be validated
paramsArray of struct imquic_json_parameter to describe the parameters; the array has to be a global or stack variable to make sizeof work
[out]resResult of the validation (will be 0 if no error occurred)

◆ IMQUIC_VALIDATE_JSON_OBJECT_FORMAT

#define IMQUIC_VALIDATE_JSON_OBJECT_FORMAT ( missing_format,
invalid_format,
obj,
params,
res )
Value:
do { \
res = 0; \
unsigned int i; \
for(i = 0; i < sizeof(params) / sizeof(struct imquic_json_parameter); i++) { \
json_t *val = json_object_get(obj, params[i].name); \
if(!val) { \
if((params[i].flags & IMQUIC_JSON_PARAM_REQUIRED) != 0) { \
IMQUIC_LOG(IMQUIC_LOG_ERR, missing_format "\n", params[i].name); \
break; \
} \
continue; \
} \
if(!imquic_json_is_valid(val, params[i].jtype, params[i].flags)) { \
char type_name[20]; \
imquic_get_json_type_name(params[i].jtype, params[i].flags, type_name); \
IMQUIC_LOG(IMQUIC_LOG_ERR, invalid_format "\n", params[i].name, type_name); \
break; \
} \
} \
} while(0)
#define IMQUIC_LOG_ERR
Non-fatal error.
Definition debug.h:45
JSON validation parameter.
Definition utils.h:209
gboolean imquic_json_is_valid(json_t *val, json_type jtype, unsigned int flags)
Checks whether the JSON value matches the type and constraint.
Definition utils.c:383
#define IMQUIC_JSON_INVALID_ELEMENT
Definition utils.h:206
#define IMQUIC_JSON_PARAM_REQUIRED
Definition utils.h:202
#define IMQUIC_JSON_MISSING_ELEMENT
Definition utils.h:205

Validates the JSON object against the description of its parameters.

Parameters
missing_formatprintf format to indicate a missing required parameter; needs one s for the parameter name
invalid_formatprintf format to indicate an invalid parameter; needs two s for parameter name and type description from imquic_get_json_type_name
objThe JSON object to be validated
paramsArray of struct imquic_json_parameter to describe the parameters; the array has to be a global or stack variable to make sizeof work
[out]resResult of the validation (will be 0 if no error occurred)

◆ ntohll

#define ntohll ( x)
Value:
((1==ntohl(1)) ? (x) : ((guint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))

Typedef Documentation

◆ imquic_bitstream

typedef struct imquic_bitstream imquic_bitstream

Bitstream abstraction.

◆ imquic_data

typedef struct imquic_data imquic_data

Generic data buffer.

◆ imquic_data_fixed

typedef struct imquic_data_fixed imquic_data_fixed

Generic fixed size data buffer.

◆ imquic_json_parameter

typedef struct imquic_json_parameter imquic_json_parameter

JSON validation parameter.

Function Documentation

◆ imquic_bitstream_peek()

uint8_t imquic_bitstream_peek ( imquic_bitstream * bs,
uint8_t * len )

Helper method to peek 8 bit in the bitstream.

Note
This method only peeks at the data, but doesn't advance the offset position in the bitstream. There's no function to "consume" data, as that can be done by simply modifying the offset property, which is what the QPACK stack does when decoding Huffman codes internally.
Parameters
[in]bsThe bitstream instance to peek
[out]lenHow many bits were actually put in the byte
Returns
A byte containing up to 8 bits from the bitstream, without advancing the offset

◆ imquic_bitstream_write()

size_t imquic_bitstream_write ( imquic_bitstream * bs,
uint32_t value,
uint8_t bits )

Helper method to add bits to a bitstream buffer.

Parameters
bsThe bitstream instance to update
valueInteger containing the data to write
bitsNumber of bits from the integer to actually write
Returns
The number of bits written to the buffer

◆ imquic_data_create()

imquic_data * imquic_data_create ( uint8_t * buffer,
size_t length )

Helper method to create a data buffer out of existing data.

Parameters
bufferThe data to copy in the new buffer
lengthHow many bytes to copy from the original data
Returns
A pointer to a new imquic_data instance, if successful, or NULL otherwise

◆ imquic_data_destroy()

void imquic_data_destroy ( imquic_data * data)

Helper method to free an existing data buffer.

Parameters
dataThe data buffer to free

◆ imquic_data_equal()

gboolean imquic_data_equal ( const void * a,
const void * b )

Helper comparator function, to check if two buffers contain the same data.

Note
Helpful as a callback comparator function
Parameters
aOpaque pointer to the first data buffer to compare
bOpaque pointer to the second data buffer to compare
Returns
TRUE if the two buffers contain the same data, FALSE otherwise

◆ imquic_dup_uint64()

uint64_t * imquic_dup_uint64 ( uint64_t num)

Helper to generate an allocated copy of a uint64_t number.

Note
While apparently silly, this is needed in order to make sure uint64_t values used as keys in GHashTable operations are not lost: using temporary uint64_t numbers in a g_hash_table_insert, for instance, will cause the key to contain garbage as soon as the temporary variable is lost, and all opererations on the key to fail
Parameters
numThe uint64_t number to duplicate
Returns
A pointer to a uint64_t number, if successful, NULL otherwise

◆ imquic_get_json_type_name()

void imquic_get_json_type_name ( int jtype,
unsigned int flags,
char * type_name )

Creates a string describing the JSON type and constraint.

Parameters
jtypeThe JSON type, e.g., JSON_STRING
flagsIndicates constraints for the described type
[out]type_nameThe type description, e.g., "a positive integer"; required size is 19 characters

◆ imquic_hex_str()

const char * imquic_hex_str ( uint8_t * buf,
size_t buflen,
char * buffer,
size_t blen )

Helper method to stringify a buffer to a hex string.

Parameters
[in]bufThe buffer to stringify
[in]buflenThe size of the buffer to stringify
[out]bufferThe output buffer where the string will be written
[in]blenSize of the string output buffer
Returns
A pointer to buffer, if successful, or NULL otherwise

◆ imquic_json_is_valid()

gboolean imquic_json_is_valid ( json_t * val,
json_type jtype,
unsigned int flags )

Checks whether the JSON value matches the type and constraint.

Parameters
valThe JSON value to be checked
jtypeThe JSON type, e.g., JSON_STRING
flagsIndicates constraints for the described type
Returns
TRUE if the value is valid

◆ imquic_print_hex()

void imquic_print_hex ( int level,
uint8_t * buf,
size_t buflen )

Helper method mostly used for debugging: prints the content of a hex buffer.

Parameters
levelLog level at which this should be printed
bufBuffer whose content need to be printed
buflenHow many bytes in the buffer should be printed

◆ imquic_random_uint64()

uint64_t imquic_random_uint64 ( void )

Helper to generate random 64 bit unsigned integers.

Note
This will fall back to a non-cryptographically safe PRNG in case the crypto library RAND_bytes() call fails.
Returns
A (mostly crypto-safe) random 64-bit unsigned integer

◆ imquic_read_pfxint()

uint64_t imquic_read_pfxint ( uint8_t n,
uint8_t * bytes,
size_t blen,
uint8_t * length )

Read a prefixed integer from a buffer (QPACK only).

Note
You can use the return value to know how many bytes to skip in the buffer to read the next value. In case of issues in the parsing, length will have value 0.
Parameters
[in]nThe N prefix
[in]bytesThe buffer to read
[in]blenThe size of the buffer
[out]lengthHow many bytes the variable size integer used
Returns
The prefixed integer, if length is higher than 0

◆ imquic_read_varint()

uint64_t imquic_read_varint ( uint8_t * bytes,
size_t blen,
uint8_t * length )

Read a variable size integer from a buffer.

Note
You can use the return value to know how many bytes to skip in the buffer to read the next value. In case of issues in the parsing, length will have value 0.
Parameters
[in]bytesThe buffer to read
[in]blenThe size of the buffer
[out]lengthHow many bytes the variable size integer used
Returns
The variable size integer, if length is higher than 0

◆ imquic_strlcat()

size_t imquic_strlcat ( char * dest,
const char * src,
size_t dest_size )

Helper method to concatenate strings and log an error if truncation occurred.

Parameters
[in]destDestination buffer, already containing one nul-terminated string
[in]srcSource buffer
[in]dest_sizeLength of dest buffer in bytes (not length of existing string inside dest)
Returns
Size of attempted result, if retval >= dest_size, truncation occurred (and an error will be logged).

◆ imquic_strlcat_fast()

int imquic_strlcat_fast ( char * dest,
const char * src,
size_t dest_size,
size_t * offset )

Alternative helper method to concatenate strings and log an error if truncation occurred, which uses memccpy instead of g_strlcat and so is supposed to be faster.

Note
The offset attribute is input/output, and updated any time the method is called
Parameters
[in]destDestination buffer, already containing one nul-terminated string
[in]srcSource buffer
[in]dest_sizeLength of dest buffer in bytes (not length of existing string inside dest)
[in]offsetOffset of where to start appending, in the destination buffer
Returns
0 in case of success, a negative integer otherwise

◆ imquic_write_pfxint()

uint8_t imquic_write_pfxint ( uint64_t number,
uint8_t n,
uint8_t * bytes,
size_t blen )

Write a prefixed integer to a buffer (QPACK only).

Note
You can use the return value to know how many bytes to skip in the buffer to write the next value. In case of issues in the writing, length will have value 0.
Parameters
[in]numberThe number to write as a variable size integer
[in]nThe N prefix
[in]bytesThe buffer to write to
[in]blenThe size of the buffer
Returns
How many bytes the variable size integer used, if successful, 0 otherwise

◆ imquic_write_varint()

uint8_t imquic_write_varint ( uint64_t number,
uint8_t * bytes,
size_t blen )

Write a variable size integer to a buffer.

Note
You can use the return value to know how many bytes to skip in the buffer to write the next value. In case of issues in the writing, length will have value 0.
Parameters
[in]numberThe number to write as a variable size integer
[in]bytesThe buffer to write to
[in]blenThe size of the buffer
Returns
How many bytes the variable size integer used, if successful, 0 otherwise