diff options
author | David Timber <dxdt@dev.snart.me> | 2022-06-02 12:19:11 +0800 |
---|---|---|
committer | David Timber <dxdt@dev.snart.me> | 2022-06-02 12:19:11 +0800 |
commit | 31e7acb5c965067463f33fa59fc463086a298350 (patch) | |
tree | 921df7d673b812255da0bca13b967930a498a7ff /src | |
parent | 80a062ef30a2f945f6634ca9a0bf2b886a54e3ae (diff) |
Doc and final touches ...
- Add .settings.json for doxygen settings
- Add /doc/impl.md
- Doc and change usage of /bootstrap.sh
- Add notes to docs
- Add 7-bit char machine check
- Normailise description for init and free functions
- Doc rest of source code
- Remove unused function: prne_str_shift_spaces()
Diffstat (limited to 'src')
-rw-r--r-- | src/bne.h | 10 | ||||
-rw-r--r-- | src/config.h | 6 | ||||
-rw-r--r-- | src/cred_dict.h | 10 | ||||
-rw-r--r-- | src/dvault.h | 11 | ||||
-rw-r--r-- | src/htbt.h | 10 | ||||
-rw-r--r-- | src/protocol.h | 99 | ||||
-rw-r--r-- | src/pth.h | 11 | ||||
-rw-r--r-- | src/recon.h | 10 | ||||
-rw-r--r-- | src/resolv.h | 40 | ||||
-rw-r--r-- | src/rnd.h | 10 | ||||
-rw-r--r-- | src/strmap.h | 10 | ||||
-rw-r--r-- | src/util_ct.h | 108 | ||||
-rw-r--r-- | src/util_rt.c | 49 | ||||
-rw-r--r-- | src/util_rt.h | 411 |
14 files changed, 606 insertions, 189 deletions
@@ -319,15 +319,13 @@ struct prne_bne_result { }; /** - * \brief Initialise the BNE worker parameter object - * \note Initialises the members of \p p to initial values. Prepares \p p so - * that it can be freed using \c prne_free_bne_param() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_bne_param (prne_bne_param_t *p); /** - * \brief Free the resources allocated for the BNE worker parameter object - * \param p The pointer to the object that has been initialised using - * \c prne_init_bne_param() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_bne_param (prne_bne_param_t *p); diff --git a/src/config.h b/src/config.h index 1b2a746..79c12f0 100644 --- a/src/config.h +++ b/src/config.h @@ -33,12 +33,18 @@ #endif #include "protocol.h" +#include <limits.h> #include <stdint.h> #include <stddef.h> #include <stdbool.h> #include <zlib.h> +// Refuse 7-bit byte +#if CHAR_BIT != 8 +#error "FIXME!" +#endif + /** \def PRNE_HOST_WORDSIZE * \brief Th system "word size". 32 if the system is a 32-bit machine. 64 if the * system is a 64-bit machine. diff --git a/src/cred_dict.h b/src/cred_dict.h index 2528a5d..872f6ae 100644 --- a/src/cred_dict.h +++ b/src/cred_dict.h @@ -54,15 +54,13 @@ struct prne_cred_dict { }; /** - * \brief Initialise the credential dictionary object - * \note Initialises the members of \p p to initial values. Prepares \p p so - * that it can be freed using \c prne_free_cred_dict() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_cred_dict (prne_cred_dict_t *p); /** - * \brief Free the resources allocated for the credential dictionary object. - * \param p The pointer to the object that has been initialised using - * \c prne_init_cred_dict() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_cred_dict (prne_cred_dict_t *p); diff --git a/src/dvault.h b/src/dvault.h index 0f52518..ef0b907 100644 --- a/src/dvault.h +++ b/src/dvault.h @@ -101,16 +101,13 @@ void prne_dvault_invert_mem ( const uint8_t *mask); /** - * \brief Initialise the data vault masking operation result object - * \note Initialises the members of \p r to initial values. Prepares \p r so - * that it can be freed using \c prne_free_dvault_mask_result() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_dvault_mask_result (prne_dvault_mask_result_t *r); /** - * \brief Free the resources allocated for the the data vault masking operation - * result object - * \param p The pointer to the object that has been initialised using - * \c prne_init_dvault_mask_result() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_dvault_mask_result (prne_dvault_mask_result_t *r); /** @@ -210,14 +210,12 @@ struct prne_htbt_param { prne_htbt_t *prne_alloc_htbt (prne_worker_t *w, const prne_htbt_param_t *param); /** - * \brief Initialise the heartbeat worker parameter object - * \note Initialises the members of \p p to initial values. Prepares \p p so - * that it can be freed using \c prne_htbt_free_param() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_param (prne_htbt_param_t *p); /** - * \brief Free the resources allocated for the heartbeat worker parameter object - * \param p The pointer to the object that has been initialised using - * \c prne_htbt_init_param() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_param (prne_htbt_param_t *p); diff --git a/src/protocol.h b/src/protocol.h index 99fb198..e730409 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -445,16 +445,13 @@ bool prne_net_ep_set_ipv6 ( const char *prne_htbt_op_tostr (const prne_htbt_op_t x); /** - * \brief Initialise the heartbeat framing protocol message header frame - * \note Initialises the members of \p mh to initial values. Prepares \p mh so - * that it can be freed using \c prne_htbt_free_msg_head() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_msg_head (prne_htbt_msg_head_t *mh); /** - * \brief Free the resources allocated for the heartbeat framing protocol - * message header frame - * \param mh The pointer to the object that has been initialised using - * \c prne_htbt_init_msg_head() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_msg_head (prne_htbt_msg_head_t *mh); /** @@ -468,16 +465,13 @@ bool prne_htbt_eq_msg_head ( const prne_htbt_msg_head_t *b); /** - * \brief Initialise the heartbeat framing protocol status frame - * \note Initialises the members of \p s to initial values. Prepares \p s so - * that it can be freed using \c prne_htbt_free_status() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_status (prne_htbt_status_t *s); /** - * \brief Free the resources allocated for the heartbeat framing protocol status - * frame - * \param s The pointer to the object that has been initialised using - * \c prne_htbt_init_status() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_status (prne_htbt_status_t *s); /** @@ -490,9 +484,8 @@ bool prne_htbt_eq_status ( const prne_htbt_status_t *b); /** - * \brief Initialise the host credential object - * \note Initialises the members of \p hc to initial values. Prepares \p hc so - * that it can be freed using \c prne_free_host_cred() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_host_cred (prne_host_cred_t *hc); /** @@ -512,9 +505,8 @@ bool prne_alloc_host_cred ( const uint8_t id_len, const uint8_t pw_len); /** - * \brief Free the resources allocated for the host credential object - * \param hc The pointer to the object that has been initialised using - * \c prne_init_host_cred() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_host_cred (prne_host_cred_t *hc); /** @@ -559,9 +551,8 @@ prne_htbt_ser_rc_t prne_dec_host_cred ( prne_host_cred_t *out); /** - * \brief Initialise the heartbeat framing protocol hostinfo frame - * \note Initialises the members of \p hi to initial values. Prepares \p hi so - * that it can be freed using \c prne_htbt_free_host_info() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_host_info (prne_htbt_host_info_t *hi); /** @@ -572,16 +563,15 @@ void prne_htbt_init_host_info (prne_htbt_host_info_t *hi); * \param bf_len The byte length required for the bit field data * \return true if allocation was successful * \return false on failure and \c errno set to \c ENOMEM + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ bool prne_htbt_alloc_host_info ( prne_htbt_host_info_t *hi, const size_t cred_len, const size_t bf_len); /** - * \brief Free the resources allocated for the heartbeat framing protocol - * hostinfo frame - * \param hi The pointer to the object that has been initialised using - * \c prne_htbt_init_host_info() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_host_info (prne_htbt_host_info_t *hi); /** @@ -594,9 +584,8 @@ bool prne_htbt_eq_host_info ( const prne_htbt_host_info_t *b); /** - * \brief Initialise the heartbeat framing protocol command frame - * \note Initialises the members of \p cmd to initial values. Prepares \p cmd so - * that it can be freed using \c prne_htbt_free_cmd() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_cmd (prne_htbt_cmd_t *cmd); /** @@ -615,10 +604,8 @@ bool prne_htbt_alloc_cmd ( const size_t *args_len); bool prne_htbt_set_cmd (prne_htbt_cmd_t *cmd, const char **args); /** - * \brief Free the resources allocated for the heartbeat framing protocol - * command frame - * \param cmd The pointer to the object that has been initialised using - * \c prne_htbt_init_cmd() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_cmd (prne_htbt_cmd_t *cmd); /** @@ -629,16 +616,13 @@ void prne_htbt_free_cmd (prne_htbt_cmd_t *cmd); bool prne_htbt_eq_cmd (const prne_htbt_cmd_t *a, const prne_htbt_cmd_t *b); /** - * \brief Initialise the heartbeat framing protocol binary meta frame - * \note Initialises the members of \p nb to initial values. Prepares \p nb so - * that it can be freed using \c prne_htbt_free_bin_meta() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_bin_meta (prne_htbt_bin_meta_t *nb); /** - * \brief Free the resources allocated for the the heartbeat framing protocol - * binary meta frame - * \param nb The pointer to the object that has been initialised using - * \c prne_htbt_init_bin_meta() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_bin_meta (prne_htbt_bin_meta_t *nb); /** @@ -652,16 +636,13 @@ bool prne_htbt_eq_bin_meta ( const prne_htbt_bin_meta_t *b); /** - * \brief Initialise the heartbeat framing protocol hand-over frame - * \note Initialises the members of \p ho to initial values. Prepares \p ho so - * that it can be freed using \c prne_htbt_free_hover() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_hover (prne_htbt_hover_t *ho); /** - * \brief Free the resources allocated for the heartbeat framing protocol - * hand-over frame - * \param ho The pointer to the object that has been initialised using - * \c prne_htbt_init_hover() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_hover (prne_htbt_hover_t *ho); /** @@ -685,16 +666,13 @@ bool prne_htbt_cp_hover ( prne_htbt_hover_t *dst); /** - * \brief Initialise the heartbeat framing protocol STDIO frame - * \note Initialises the members of \p s to initial values. Prepares \p s so - * that it can be freed using \c prne_htbt_free_stdio() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_stdio (prne_htbt_stdio_t *s); /** - * \brief Free the resources allocated for the heartbeat framing protocol STDIO - * frame - * \param s The pointer to the object that has been initialised using - * \c prne_htbt_init_stdio() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_stdio (prne_htbt_stdio_t *s); /** @@ -707,16 +685,13 @@ bool prne_htbt_eq_stdio ( const prne_htbt_stdio_t *b); /** - * \brief Initialise the heartbeat protocol binary RCB frame - * \note Initialises the members of \p r to initial values. Prepares \p r so - * that it can be freed using \c prne_htbt_free_rcb() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_init_rcb (prne_htbt_rcb_t *r); /** - * \brief Free the resources allocated for the heartbeat protocol binary RCB - * frame - * \param r The pointer to the object that has been initialised using - * \c prne_htbt_init_rcb() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_htbt_free_rcb (prne_htbt_rcb_t *r); /** @@ -50,16 +50,13 @@ typedef struct prne_pth_cv prne_pth_cv_t; /** - * \brief Initialise the worker object - * \note Initialises the members of \p w to initial values. Prepares \p w so - * that it can be freed using \c prne_free_worker() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_worker (prne_worker_t *w); /** - * \brief Free the resources allocated for the worker object - * \param w The pointer to the object that has been initialised using - * \c prne_init_worker() - * \warning The worker has to be joined using \c pth_join() beforehand! + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_worker (prne_worker_t *w); /** diff --git a/src/recon.h b/src/recon.h index ede9600..5fa6e25 100644 --- a/src/recon.h +++ b/src/recon.h @@ -84,15 +84,13 @@ prne_recon_t *prne_alloc_recon ( mbedtls_ctr_drbg_context *ctr_drbg, const prne_recon_param_t *param); /** - * \brief Initialise the recon worker parameter object - * \note Initialises the members of \p p to initial values. Prepares \p p so - * that it can be freed using \c prne_free_recon_param() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_recon_param (prne_recon_param_t *p); /** - * \brief Free the resources allocated for the recon worker parameter object - * \param p The pointer to the object that has been initialised using - * \c prne_init_recon_param() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_recon_param (prne_recon_param_t *p); /** diff --git a/src/resolv.h b/src/resolv.h index f823410..f671d21 100644 --- a/src/resolv.h +++ b/src/resolv.h @@ -287,15 +287,13 @@ bool prne_resolv_prm_gettxtrec ( prne_resolv_prm_t *out); /** - * \brief Initialise the name server pool object - * \note Initialises the members of \p pool to initial values. Prepares \p pool - * so that it can be freed using \c prne_resolv_free_ns_pool() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_resolv_init_ns_pool (prne_resolv_ns_pool_t *pool); /** - * \brief Free the resources allocated for the name server pool object - * \param pool The pointer to the object that has been initialised using - * \c prne_resolv_init_ns_pool() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_resolv_free_ns_pool (prne_resolv_ns_pool_t *pool); /** @@ -318,39 +316,33 @@ prne_resolv_ns_pool_t prne_resolv_own_ns_pool( const prne_resolv_ns_pool_t *pool, const bool ownership); /** - * \brief Initialise the query operation promise object - * \note Initialises the members of \p prm to initial values. Prepares \p prm so - * that it can be freed using \c prne_resolv_free_prm() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_resolv_init_prm (prne_resolv_prm_t *prm); /** - * \brief Free the resources allocated for the query operation promise object - * \param prm The pointer to the object that has been initialised using - * \c prne_resolv_init_prm() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_resolv_free_prm (prne_resolv_prm_t *prm); /** - * \brief Initialise the query operation future object - * \note Initialises the members of \p fut to initial values. Prepares \p fut so - * that it can be freed using \c prne_free_resolv_fut() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_resolv_fut (prne_resolv_fut_t *fut); /** - * \brief Free the resources allocated for the query operation future object - * \param fut The pointer to the object that has been initialised using - * \c prne_init_resolv_fut() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_resolv_fut (prne_resolv_fut_t *fut); /** - * \brief Initialise the query resource record - * \note Initialises the members of \p rr to initial values. Prepares \p rr so - * that it can be freed using \c prne_free_resolv_rr() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_resolv_rr (prne_resolv_rr_t *rr); /** - * \brief Free the resources allocated for the query resource record - * \param rr The pointer to the object that has been initialised using - * \c prne_init_resolv_rr() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_resolv_rr (prne_resolv_rr_t *rr); @@ -47,15 +47,13 @@ typedef struct prne_rnd prne_rnd_t; /** - * \brief Initialise the PRNG engine object - * \note Initialises the members of \p p to initial values. Prepares \p p so - * that it can be freed using \c prne_free_rnd() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_rnd (prne_rnd_t *p); /** - * \brief Free the resources allocated for the PRNG engine object - * \param p The pointer to the object that has been initialised using - * \c prne_init_rnd() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_rnd (prne_rnd_t *p); /** diff --git a/src/strmap.h b/src/strmap.h index 74a6956..634fdbf 100644 --- a/src/strmap.h +++ b/src/strmap.h @@ -47,15 +47,13 @@ struct prne_strmap_tuple { }; /** - * \brief Initialise the string map object - * \note Initialises the members of \p map to initial values. Prepares \p map so - * that it can be freed using \c prne_free_strmap() + * \brief Initialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_init_strmap (prne_strmap_t *map); /** - * \brief Free the resources allocated for the string map object - * \param map The pointer to the object that has been initialised using - * \c prne_init_strmap() + * \brief Deinitialisation function + * \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation) */ void prne_free_strmap (prne_strmap_t *map); diff --git a/src/util_ct.h b/src/util_ct.h index a58f170..2c2af1b 100644 --- a/src/util_ct.h +++ b/src/util_ct.h @@ -1,3 +1,11 @@ +/** \file + * \brief Compile-time utility and convenience functions + * \note \c _Static_assert() instead of \c static_assert() is used because some + * cross compilers do not support it. The use of \c _Static_assert() is + * still standard compliant. + * \note The expressions and values involved must be determinable during compile + * time! Basically, write what can be written using constexpr in C++. + */ /* * Copyright (c) 2019-2021 David Timber <mieabby@gmail.com> * @@ -32,28 +40,98 @@ #include <errno.h> #endif +/* Log levels + * The default level is 1. Using the value 1(PRNE_VL_ERR or PRNE_VL_INFO) will + * filter out all the log levels higher than 1 showing only info, err and fatal + * errors only. + * Generally, the native uint type is used. Note that minimum width of int for C + * is 16-bit. + */ +/* Fatal error + * The process cannot proceed further due to a serious error. The message + * must be the last message the process prints before calling abort() + */ #define PRNE_VL_FATAL 0 +/* General error + * An operation or a work unit failed due to an error + */ #define PRNE_VL_ERR 1 +/* Info + * The message carries essential information. The value is the same as + * PRNE_VL_ERR. This is intentional - this log level should only be used for + * essential info messages. + */ #define PRNE_VL_INFO 1 +/* Warning + * The message is about a warning that needs the user's attention. + */ #define PRNE_VL_WARN 2 +/* Debug Level 0 + * This level is the lowest possible debug log level. Use higher debug levels + * for more detailed data like raw packet data and diagnostic info. + */ #define PRNE_VL_DBG0 3 +/** + * \brief Limit the number of enums using static_assert() + */ #define PRNE_LIMIT_ENUM(t,x,l) _Static_assert((x) <= (l),"enum overflow: "#t) +/** + * \brief Do \c static_assert(). This is a workaround for the problem where some + * compilers don't have static_assert() exposed. + */ #define prne_static_assert(expr, msg) _Static_assert((expr), msg) +/** + * \brief Pick the smallest expression + */ #define prne_op_min(a, b) ((a) < (b) ? (a) : (b)) +/** + * \brief Pick the biggest expression + */ #define prne_op_max(a, b) ((a) > (b) ? (a) : (b)) +/** + * \brief The spaceship operator - compare \p a and \p b and return -1 if \p b + * is the biggest, return 1 if \p a is the biggest, return 0 if \p a and \p b + * are equal. + */ #define prne_op_spaceship(a, b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) +/** + * \brief Align the byte length \p x to the alignment \p align - calculate the + * multiple of \p align required to store the \p x bytes of data (much like + * ceiling function) + * \note Consider using APIs like \c posix_memalign() where suits. This macro is + * only for computation of byte size + */ #define prne_salign_next(x, align) \ (((x) % (align) == 0) ? (x) : ((x) / (align) + 1) * (align)) -#define prne_salign_at(x, align) \ - (((x) % (align) == 0) ? (x) : ((x) / (align)) * (align)) #if PRNE_DEBUG +/* + * These macros have effect only on debug builds. The macros are disabled for + * release builds to prevent info leak. + */ + +/** + * \brief The debug print function. Print the formatted message on the standard + * error. Effective only in debug. + */ #define prne_dbgpf(...) fprintf(stderr, __VA_ARGS__) +/** + * \brief The \c perror() function only effective in debug. + */ #define prne_dbgperr(str) perror(str) +/** + * \brief \c assert() macro - use \c assert() directly in debug, use \c abort() + * in release so the expression is not printed on the standard error. + */ #define prne_assert(expr) assert(expr) +/** + * \brief \c assert() macro, but instead of using the expression for the error + * message, use the formatted message instead. The messages will not be built + * into release builds. + */ #define prne_massert(expr, ...)\ if (!(expr)) {\ fprintf(stderr, "*** ");\ @@ -61,8 +139,21 @@ fprintf(stderr, "\n");\ abort();\ } +/** + * \brief Do \c assert() only in debug. This macro has no effect in release + * builds. + */ #define prne_dbgast(expr) prne_assert(expr) +/** + * \brief Do \c prne_massert() only in debug. This macro has no effect in + * release builds. + */ #define prne_dbgmast(expr, ...) prne_massert(expr, __VA_ARGS__) +/** + * \brief The debug trap macro. In debug mode, this macro simply acts as + * \c assert() In release mode, the expression is simply executed without its + * result evaluated by \c assert(). The macro is for non-critical assertions. + */ #define prne_dbgtrap(expr) prne_assert(expr) #else #define prne_dbgpf(...) @@ -77,10 +168,21 @@ #define prne_dbgtrap(expr) (expr) #endif +/** + * \brief Convenience macro for assigning value to the optional parameter + * pointer. Dereference the pointer \p l to assign the value \p r to it only if + * the pointer is not NULL. + */ #define prne_chk_assign(l, r) \ if ((l) != NULL) {\ *(l) = (r);\ } -// include <errno.h> if you get compilation errors +/** + * \brief Test if the expression is one of the "non-blocking" errors. Include + * <errno.h> to use this macro. The macro is a workaround for the issue where + * some platforms define \c EAGAIN and \c EWOULDBLOCK as seperate values. On + * platforms where they represent the same value, the compiler will optimise the + * expression into a single equality comparison operation. + */ #define prne_is_nberr(expr) ((expr) == EAGAIN || (expr) == EWOULDBLOCK) diff --git a/src/util_rt.c b/src/util_rt.c index 95f117f..692b5ed 100644 --- a/src/util_rt.c +++ b/src/util_rt.c @@ -36,12 +36,11 @@ #include <pthsem.h> -void prne_empty_func (void) {} - -void prne_close (const int fd) { +int prne_close (const int fd) { if (fd >= 0) { - close(fd); + return close(fd); } + return 0; } void prne_shutdown (const int fd, const int how) { @@ -59,9 +58,18 @@ int prne_chfd (const int old, const int ny) { int ret; if (old == ny) { + /* + * dup2() will do nothing if both are same. This is not desired because + * the function will end up closing the original fd! + */ return old; } + /* + * Be careful if you're changing this to dup3()! Using the same fd on dup2() + * is no op whereas dup3() considers this an invalid use case(EINVAL). The + * behaviour of dup2() is desired for this function. + */ ret = dup2(old, ny); if (ret < 0) { return ret; @@ -152,15 +160,7 @@ char *prne_redup_str (char *old, const char *str) { } void prne_sfree_str (char *s) { - char *p; - - if (s == NULL) { - return; - } - - for (p = s; *p != 0; p += 1) { - *p = 0; - } + prne_strzero(s); prne_free(s); } @@ -254,6 +254,8 @@ char *prne_strnchr (const char *p, const char c, const size_t n) { return (char*)p + i; } else if (p[i] == 0) { + // c == 0 is a valid use + // stop at a null terminator return NULL; } } @@ -261,27 +263,6 @@ char *prne_strnchr (const char *p, const char c, const size_t n) { return NULL; } -size_t prne_str_shift_spaces (char *str, const size_t len) { - size_t i, ret = len; - - for (i = 0; i < ret; ) { - if (prne_cisspace(str[i])) { - if (i + 1 >= ret) { - // last trailing whitespace - ret -= 1; - break; - } - memmove(str + i, str + i + 1, ret - i - 1); - ret -= 1; - } - else { - i += 1; - } - } - - return ret; -} - bool prne_chkcstr (const char *str, bool(*chk_f)(const char)) { bool ret = true; diff --git a/src/util_rt.h b/src/util_rt.h index b60bedd..48af5b6 100644 --- a/src/util_rt.h +++ b/src/util_rt.h @@ -1,3 +1,6 @@ +/** \file + * \brief Runtime utility and convenience functions + */ /* * Copyright (c) 2019-2021 David Timber <mieabby@gmail.com> * @@ -32,29 +35,183 @@ #include <mbedtls/ctr_drbg.h> -void prne_empty_func (void); -void prne_close (const int fd); +/** + * \brief Call \c close() only if the \p fd is zero or greater to preserve + * \c errno + * \retval 0 if \p fd is less than zero (no op) + * \return the value returned from \c close() otherwise + * \see \c close() + * \see [/doc/impl.md#Resource Allocation Hook](/doc/impl.md#resource_allocation_hook) + */ +int prne_close (const int fd); +/** + * \brief Call \c shutdown() only if the \p fd is zero or greater to preserve + * \c errno + * \see \c shutdown() + */ void prne_shutdown (const int fd, const int how); /* prne_sck_fcntl(fd) * * Sets FD_CLOEXEC and O_NONBLOCK. Failure to set FD_CLOEXEC is ignored. */ + +/** + * \brief Set the commmon socket flags associated with the fd. The common flags + * are \c FD_CLOEXEC and \c O_NONBLOCK + * \retval true if the mission critial flags(O_NONBLOCK) are successfully set + * \retval false otherwise. \c errno is set by \c fcntl() + * \warning The error occurred setting \c FD_CLOEXEC is ignored as the flag is + * considered non mission critial. + * \see \c fcntl() + */ bool prne_sck_fcntl (const int fd); +/** + * \brief Convenience function for changing the fd to a new fd using \c dup2() + * Upon successful \c dup2() call, the old fd is closed and the new fd is + * returned. + * \param old The old fd + * \param ny The desired value for the new fd + * \retval -1 on error + * \return The new fd returned by \c dup2() + * \see \c dup2() + * \warning This function assumes that as long as the new fd stays open, closing + * the old fd won't block the calling thread. There might be cases where close() + * fails or blocks regardless? + * \note As per the behaviour of \c dup2(), the new fd is silently closed if if + * is a valid fd. Use this function if you're absolutely sure that the new fd is + * not used. Like setting up a pipe as standard IO(fd 0, 1 and 2). + */ int prne_chfd (const int old, const int ny); +/** + * \brief Zero-fill the region of memory - call \c memset() with zero + */ void prne_memzero(void *addr, const size_t len); -void *prne_malloc (const size_t se, const size_t cnt); +/** + * \brief Safe \c malloc() - do overflow check and return NULL for zero length + * allocation + * \param se the size of an element + * \param cnt the number of elements + * \retval NULL if the size calculated is zero. \c errno left untouched + * \retval NULL on allocation failure or integer overflow. \c errno set to + * \c ENOMEM + * \return The pointer returned from \c malloc() + * \note The purpose of the functions including \c prne_realloc() + * \c prne_calloc() is following. + * - To have a version of \c malloc() that always returns NULL for zero-length + * allocation. A valid pointer is returned on most platforms and NULL is + * returned on some platforms. + * - Integer overflow check (especially for 16-bit machines) + * - To implement a memory allocation event system in the future. Valgrind might + * not be a suitable candidate to debug Proone and a different approach(like + * the one chosen for MSVCRT) could be desired. + * \see \c malloc() + */ +void *prne_malloc (const size_t se, const size_t cnt);\ +/** + * \brief Do \c reallocarray() See \c prne_malloc() + * \param ptr the pointer to the previously dynamically allocated memory + * acceptable by \c realloc() + * \param se the size of an element + * \param cnt the number of elements + * \retval NULL if the size calculated is zero. \c errno is left untouched. If + * \p ptr is not NULL, free() has been performed to free the memory. + * \retval NULL on allocation failure or integer overflow. \c errno set to + * \c ENOMEM + * \return The pointer returned from \c realloc() + * \note Unlike \c realloc() using this function with \p ptr to dynamically + * allocated memory and either of \p se or \p cnt zero has the same effect as + * \c free() + * \see \c prne_malloc() + */ void *prne_realloc (void *ptr, const size_t se, const size_t cnt); +/** + * \brief Call \c calloc() but ensure that NULL is always returned for + * zero-length allocation + * \param se the size of an element + * \param cnt the number of elements + * \retval NULL if the size calculated is zero. \c errno left untouched + * \retval NULL on allocation failure or integer overflow. \c errno set to + * \c ENOMEM + * \return The pointer returned from \c calloc() + * \see \c prne_malloc() + */ void *prne_calloc (const size_t se, const size_t cnt); +/** + * \brief Dynamically allocate memory for a string of the specified length. This + * is a convenience function for performing \c malloc(strlen(str)+1) + * \param len the byte length of the string excluding the null-terminator + * \retval NULL on allocation failure or integer overflow. \c errno set to + * \c ENOMEM + * \return The pointer to the dynamically allocated memory for storing the + * string of the specified length + * \see \c prne_realloc_str() + * \note Implemented using \c prne_realloc_str() + */ char *prne_alloc_str (const size_t len); +/** + * \brief Dynamically allocate memory for a string of the specified length. This + * is a convenience function for performing \c realloc(ptr,strlen(str)+1) + * \param old the pointer to the previously dynamically allocated memory + * \param len the new byte length of the string excluding the null-terminator + * \retval NULL on allocation failure or integer overflow. \c errno set to + * \c ENOMEM + * \return The pointer to the newly dynamically allocated memory for storing the + * string of the specified length + * \note Unlike \c prne_realloc() calling this function with zero \p len won't + * free \p old since the length of the new string is calculated as len + 1 + */ char *prne_realloc_str (char *old, const size_t len); +/** + * \brief Make a new copy of the string. This is a convenience function for + * performing \c malloc(strlen(str)+1) and then \c strcpy() + * \retval NULL on memory allocation error, \c errno set to \c ENOMEM + * \return The pointer to the new copy of the string + * \see \c prne_redup_str() + * \note Implemented using \c prne_redup_str() + */ char *prne_dup_str (const char *str); +/** + * \brief Make a new copy of the string. This is a convenience function for + * performing \c realloc(ptr,strlen(str)+1) and then \c strcpy() + * \retval NULL on memory allocation error, \c errno set to \c ENOMEM + * \return The pointer to the new copy of the string + * \see \c prne_redup_str() + * \note Implemented using \c prne_redup_str() + */ char *prne_redup_str (char *old, const char *str); +/** + * \brief Scrub and free the string. For freeing strings containing sensitive + * data + */ void prne_sfree_str (char *s); +/** + * \brief Do \c free() + * \see [/doc/impl.md#Resource Allocation Hook](/doc/impl.md#resource_allocation_hook) + */ void prne_free (void *ptr); +/** + * \brief Do \c sysconf(_SC_PAGESIZE) Call \c abort() on failure + */ size_t prne_getpagesize (void); +/** + * \brief Assume the ownership of the memory by doing \c realloc() if necessary. + * If \p ownership is unset, the function allocates new memory and copies the + * content of the original memory to the new memory, leaving the original memory + * intact. The \p ownership will always be set upon successful operation. If the + * flag is set, calling the function is equivalent to calling \c realloc() + * + * \param p The pointer to the pointer holding the address + * \param ownership The pointer to the the current ownership flag + * \param se The byte size of each element + * \param old The current number of elements + * \param req The number of elements requested + * \retval true if the operation was successful + * \retval false otherwise, \c errno set + * \see [/doc/impl.md#Ownership of Dynamically Resources](/doc/impl.md#ownership_of_dynamically_resources) + */ bool prne_own_realloc ( void **p, bool *ownership, @@ -62,101 +219,323 @@ bool prne_own_realloc ( size_t *old, const size_t req); -/* Locale "C" character category functions -*/ +/* Locale "C" character category functions */ +/** + * \brief The POSIX locale \c toupper() that does not use any global + */ char prne_ctoupper (const char c); +/** + * \brief The POSIX locale \c tolower() that does not use any global + */ char prne_ctolower (const char c); +/** + * \brief The POSIX locale \c isspace() that does not use any global + */ bool prne_cisspace (const char c); +/** + * \brief The POSIX locale \c isprint() that does not use any global + */ bool prne_cisprint (const char c); - +/** + * \brief Test if \p c is zero + */ bool prne_ciszero (const char c); +/** + * \brief Test if two strings are equal, treating a null pointer as an empty + * string + */ bool prne_nstreq (const char *a, const char *b); +/** + * \brief Calculate the number of non-zero characters in the string. A null + * pointer is treated as an empty string + */ size_t prne_nstrlen (const char *s); +/** + * \brief Find the first occurence of a character in the string + * + * \param p The string + * \param c The character to look for. A null character is valid + * \param n The number of characters in the string + * \return The pointer to the original string offset to the first character + * found in the string + * \retval NULL if the character is not found in the string or a null terminator + * was encountered + */ char *prne_strnchr (const char *p, const char c, const size_t n); -size_t prne_str_shift_spaces (char *str, const size_t len); +/** + * \brief Test the string with \p chk_f + * + * \param str The string + * \param chk_f The test function + * \retval true if \p chk_f returned true for all characters in the string + * \retval false otherwise + */ bool prne_chkcstr (const char *str, bool(*chk_f)(const char)); +/** + * \brief Test the memory with \c chk_f + * + * \param m The memory + * \param len The byte length of the memory + * \param chk_f The test function + * \retval true if \p chk_f returned true for all bytes in the memory + * \retval false otherwise + */ bool prne_chkcmem (const void *m, size_t len, bool(*chk_f)(const char)); +/** + * \brief Transform the string using \p trans_f + */ void prne_transstr (char *str, int(*trans_f)(int)); +/** + * \brief Transform the string using \p trans_f + */ void prne_transcstr (char *str, char(*trans_f)(char)); +/** + * \brief Transform the memory using \p trans_f + */ void prne_transmem (void *m, size_t len, int(*trans_f)(int)); +/** + * \brief Transform the memory using \p trans_f + */ void prne_transcmem (void *m, size_t len, char(*trans_f)(char)); +/** + * \brief Find the last occurrence of the character in the memory + * + * \param haystack The memory + * \param c The character + * \param hs_len The byte length of the memory + * \return The pointer to the original string offset to the last character found + * in the string + * \retval NULL if the character is not found in the string + */ void *prne_memrchr ( const void *haystack, const int c, const size_t hs_len); +/** + * \brief Find the last occurrence of the data in the memory + * + * \param haystack The memory + * \param hs_len The byte length of the memory + * \param needle The data + * \param n_len The byte length of the data + * \return The pointer to the original memory offset to the last occurrence of + * the data found in the memory + * \retval NULL if the data is not found in the memory + */ void *prne_memrmem ( const void *haystack, const size_t hs_len, const void *const needle, const size_t n_len); +/** + * \brief Find the first occurrence of the data in the memory + * + * \param haystack The memory + * \param hs_len The byte length of the memory + * \param needle The data + * \param n_len The byte length of the data + * \return The pointer to the original memory offset to the first occurrence of + * the data found in the memory + * \retval NULL if the data is not found in the memory + */ void *prne_memmem ( const void *haystack, const size_t hs_len, const void *const needle, const size_t n_len); +/** + * \brief Concatenate strings to build a new string + * + * \param arr The pointer to the array of null-terminated strings + * \param cnt The number of elements in \p arr + * \return The new string + * \retval NULL on error, \c errno set + * \see \c prne_rebuild_str() + */ char *prne_build_str (const char **const arr, const size_t cnt); +/** + * \brief Concatenate strings to build a new string, doing \c realloc() if + * necessary + * + * \param arr The pointer to the array of null-terminated strings + * \param cnt The number of elements in \p arr + * \return The new/reallocated string + * \retval NULL on error, \c errno set + * \see \c prne_build_str() + */ char *prne_rebuild_str (void *prev, const char **const arr, const size_t cnt); +/** + * \brief Scrub the string. Do nothing if \p str is NULL + */ void prne_strzero (char *str); +/** + * \brief Parse an \c uint8_t from the hex characters + * + * \param str The pointer to an array of characters at least 2 in length + * \param out The output + * \retval true on success + * \retval false if the array contains invalid characters, \c errno set to + * \c EINVAL + */ bool prne_hex_fromstr (const char *str, uint_fast8_t *out); +/** + * \brief Convert an \c uint8_t to hex characters + * + * \param in The value + * \param out The pointer to an array of characters at least 2 in length + * \param upper The uppercase flag. If set, uppercase characters will be used. + * Lowercase characters will be used otherwise. + */ void prne_hex_tochar (const uint_fast8_t in, char *out, const bool upper); -/* -* \param str: at least 36 bytes -* \param out: at least 16 bytes -*/ +/** + * \brief Parse a UUID from the string + * + * \param str The string containing a UUID, at least 36 characters long + * \param out The output memory, at least 16 bytes long + * \retval true on success + * \retval false on format error, \c errno set to EINVAL + */ bool prne_uuid_fromstr (const char *str, uint8_t *out); -/* -* \param in: at least 16 bytes -* \param out: at least 37 bytes (null-terminated) -*/ +/** + * \brief Convert the UUID to a null-terminated string + * + * \param in The memory of the UUID, at least 16 bytes long + * \param out The preallocated string for output, at least 37 characters long + */ void prne_uuid_tostr (const uint8_t *in, char *out); +/** + * \brief Compare two UUIDs + * + * \param a The pointer to memory at least 16 bytes long + * \param b The pointer to memory at least 16 bytes long + * \return an integer less than, equal to, or greater than zero if \p a is found + * respectively, to be less than, to match, or be greater than \p b + */ int prne_cmp_uuid_asc (const void *a, const void *b); +/** + * \brief Reverse function of \c prne_cmp_uuid_asc() + * \see \c prne_cmp_uuid_asc() + */ int prne_cmp_uuid_desc (const void *a, const void *b); +/** + * \brief Calculate the addition of two timespec structures + */ struct timespec prne_add_timespec ( const struct timespec a, const struct timespec b); +/** + * \brief Calculate the subtraction of two timespec structures + */ struct timespec prne_sub_timespec ( const struct timespec a, const struct timespec b); +/** + * \brief Convert the timespec structure to seconds + */ double prne_real_timespec (const struct timespec ts); +/** + * \brief Convert the timespec structure to milliseconds + */ long prne_timespec_ms (const struct timespec ts); +/** + * \brief Construct a timespec structure from milliseconds + */ struct timespec prne_ms_timespec (const long ms); +/** + * \brief Compare two timespec strucrures + * \return an integer less than, equal to, or greater than zero if \p a is found + * respectively, to be less than, to match, or be greater than \p b + */ int prne_cmp_timespec (const struct timespec a, const struct timespec b); +/** + * \brief Return the timespec structure with the smallest value + */ struct timespec prne_min_timespec ( const struct timespec a, const struct timespec b); +/** + * \brief Return the timespec structure with the largest value + */ struct timespec prne_max_timespec ( const struct timespec a, const struct timespec b); +/** + * \brief Do \c clock_gettime() call, \c abort() on error + */ struct timespec prne_gettime (const clockid_t cid); +/** + * \brief Convert a timespec structure to a timeval structure + */ struct timeval prne_ts2tv (const struct timespec ts); +/** + * \brief Construct a timeval structure from milliseconds + */ struct timeval prne_ms_timeval (const long ms); +/** + * \brief Encode data in Base64 in memory. Allocates memory for output + * + * \param data The data to encode + * \param size The byte length of the data + * \return The pointer to a newly allocated string containing encoded data + */ char *prne_enc_base64_mem (const uint8_t *data, const size_t size); +/** + * \brief Decode the base64 string. Allocates memory for output + * + * \param str The input string containing base64 encoded data + * \param str_len The length of the input string + * \param data The pointer for output data + * \param size The pointer for the byte length of the output data + * \retval true on success + * \retval false on memory error(ENOMEM) or parsing error(EINVAL) + */ bool prne_dec_base64_mem ( const char *str, const size_t str_len, uint8_t **data, size_t *size); -// getrandom polyfill +/** + * \brief Read \c /dev/urandom directly. + * + * \param buf The pointer to memory for output + * \param len The number of bytes to read + * \return The value returned from \c read() function. \c errno set to the value + * from the \c read() function + * \note This function is made to avoid the use of \c getrandom() which can + * potentially block the caller thread in the event of insufficient entropy + */ ssize_t prne_geturandom (void *buf, const size_t len); +/** + * \brief Output the result of bitwise AND operation of the contents of two byte + * arrays to \p c + */ void prne_bitop_and ( const uint8_t *a, const uint8_t *b, uint8_t *c, const size_t len); +/** + * \brief Output the result of bitwise OR operation of the contents of two byte + * arrays to \p c + */ void prne_bitop_or ( const uint8_t *a, const uint8_t *b, uint8_t *c, const size_t len); +/** + * \brief Output the result of bitwise NOT operation of the contents of the byte + * array \p x to \p y + */ void prne_bitop_inv ( const uint8_t *x, uint8_t *y, |