diff options
Diffstat (limited to 'include')
50 files changed, 2506 insertions, 490 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt deleted file mode 100644 index 8895c582..00000000 --- a/include/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(ouroboros) diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt deleted file mode 100644 index 8f248710..00000000 --- a/include/ouroboros/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/version.h" @ONLY) - -set(SOCK_BUF_SIZE 10240 CACHE STRING - "Size of the buffer used by the UNIX sockets for local IPC") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sockets.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/sockets.h" @ONLY) - -set(HEADER_FILES - cacep.h - cdefs.h - dev.h - errno.h - fccntl.h - fqueue.h - ipcp.h - irm.h - proto.h - qos.h - ${CMAKE_CURRENT_BINARY_DIR}/version.h - ) - -install(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ouroboros) diff --git a/include/ouroboros/bitmap.h b/include/ouroboros/bitmap.h index b557b3d1..04467a8a 100644 --- a/include/ouroboros/bitmap.h +++ b/include/ouroboros/bitmap.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Bitmap implementation * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_BITMAP_H -#define OUROBOROS_BITMAP_H +#ifndef OUROBOROS_LIB_BITMAP_H +#define OUROBOROS_LIB_BITMAP_H #include <stddef.h> #include <unistd.h> @@ -45,4 +45,4 @@ bool bmp_is_id_valid(struct bmp * bmp, bool bmp_is_id_used(struct bmp * bmp, ssize_t id); -#endif /* OUROBOROS_BITMAP_H */ +#endif /* OUROBOROS_LIB_BITMAP_H */ diff --git a/include/ouroboros/btree.h b/include/ouroboros/btree.h index c692ae9e..cf982856 100644 --- a/include/ouroboros/btree.h +++ b/include/ouroboros/btree.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * B-trees * diff --git a/include/ouroboros/cdefs.h b/include/ouroboros/cdefs.h index 5764fb41..f4a5dc65 100644 --- a/include/ouroboros/cdefs.h +++ b/include/ouroboros/cdefs.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * C Definitions * diff --git a/include/ouroboros/cacep.h b/include/ouroboros/cep.h index 6c11b701..4c1737f0 100644 --- a/include/ouroboros/cacep.h +++ b/include/ouroboros/cep.h @@ -1,7 +1,7 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * - * The Common Application Connection Establishment Protocol + * The Ouroboros Connection Establishment Protocol * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -20,20 +20,19 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_CACEP_H -#define OUROBOROS_CACEP_H +#ifndef OUROBOROS_CEP_H +#define OUROBOROS_CEP_H #include <ouroboros/cdefs.h> #include <ouroboros/proto.h> #include <stdint.h> -#include <sys/types.h> -#define CACEP_BUF_STRLEN 64 +#define OCEP_BUF_STRLEN 128 struct conn_info { - char comp_name[CACEP_BUF_STRLEN + 1]; - char protocol[CACEP_BUF_STRLEN + 1]; + char comp_name[OCEP_BUF_STRLEN + 1]; + char protocol[OCEP_BUF_STRLEN + 1]; uint32_t pref_version; enum proto_concrete_syntax pref_syntax; struct proto_field fixed_conc_syntax[PROTO_MAX_FIELDS]; @@ -43,12 +42,12 @@ struct conn_info { __BEGIN_DECLS -int cacep_snd(int fd, - const struct conn_info * in); +int cep_snd(int fd, + const struct conn_info * in); -int cacep_rcv(int fd, - struct conn_info * out); +int cep_rcv(int fd, + struct conn_info * out); __END_DECLS -#endif /* OUROBOROS_CACEP_H */ +#endif /* OUROBOROS_CEP_H */ diff --git a/include/ouroboros/crc32.h b/include/ouroboros/crc32.h index 4a2abafa..eb610797 100644 --- a/include/ouroboros/crc32.h +++ b/include/ouroboros/crc32.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * 32-bit Cyclic Redundancy Check * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_CRC32_H -#define OUROBOROS_CRC32_H +#ifndef OUROBOROS_LIB_CRC32_H +#define OUROBOROS_LIB_CRC32_H #include <stdint.h> #include <stddef.h> @@ -32,4 +32,4 @@ void crc32(uint32_t * crc, const void * buf, size_t len); -#endif /* OUROBOROS_CRC32_H */ +#endif /* OUROBOROS_LIB_CRC32_H */ diff --git a/include/ouroboros/crypt.h b/include/ouroboros/crypt.h new file mode 100644 index 00000000..5b39fb5f --- /dev/null +++ b/include/ouroboros/crypt.h @@ -0,0 +1,368 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Cryptography + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_CRYPT_H +#define OUROBOROS_LIB_CRYPT_H + +#include <ouroboros/ssm_pk_buff.h> +#include <ouroboros/utils.h> + +#include <assert.h> + +#define IVSZ 16 +#define SYMMKEYSZ 32 +#define MAX_HASH_SIZE 64 /* SHA-512/BLAKE2b max */ +#define KEX_ALGO_BUFSZ 32 +#define KEX_CIPHER_BUFSZ 32 +#define MSGBUFSZ 2048 + +/* + * On OSX the OpenSSL NIDs are automatically loaded with evp.h. + * Some have a different spelling. This header avoids the double definitions. + */ + + #define NID_undef 0 + +/* Cipher NIDs (match OpenSSL values) */ +#define NID_aes_128_gcm 895 +#define NID_aes_192_gcm 898 +#define NID_aes_256_gcm 901 +#define NID_aes_128_ctr 904 +#define NID_aes_192_ctr 905 +#define NID_aes_256_ctr 906 +#define NID_chacha20_poly1305 1018 + + #if !defined (__APPLE__) || !defined ( HAVE_OPENSSL ) +/* KEX algorithm NIDs (match OpenSSL values) */ +#define NID_X9_62_prime256v1 415 +#define NID_secp384r1 715 +#define NID_secp521r1 716 +#define NID_X25519 1034 +#define NID_X448 1035 +#define NID_ffdhe2048 1126 +#define NID_ffdhe3072 1127 +#define NID_ffdhe4096 1128 +#endif /* __APPLE__ */ +#define NID_MLKEM512 1454 +#define NID_MLKEM768 1455 +#define NID_MLKEM1024 1456 +#define NID_X25519MLKEM768 2053 /* !! not in OpenSSL */ +#define NID_X448MLKEM1024 2054 /* !! not in OpenSSL */ + +/* KDF NIDs (match OpenSSL values) */ +#define NID_hkdf 1036 +#define NID_sha256 672 +#define NID_sha384 673 +#define NID_sha512 674 +#if !defined (__APPLE__) || !defined ( HAVE_OPENSSL ) +#define NID_sha3_256 1096 +#define NID_sha3_384 1097 +#define NID_sha3_512 1098 +#endif /* __APPLE__ */ +#define NID_blake2b512 1056 +#define NID_blake2s256 1057 + + +#define IS_KEM_ALGORITHM(algo) \ + (strstr(algo, "ML-KEM") != NULL || strstr(algo, "MLKEM") != NULL) + +#define IS_HYBRID_KEM(algo) \ + ((strstr(algo, "X25519") != NULL || strstr(algo, "X448") != NULL) && \ + strstr(algo, "MLKEM") != NULL) + +#define X25519MLKEM768_PKSZ 1216 /* 32 + 1184 */ +#define X25519MLKEM768_CTSZ 1120 /* 32 + 1088 */ +#define X25519MLKEM768_SKSZ 2432 /* 32 + 2400 */ +#define X448MLKEM1024_PKSZ 1624 /* 56 + 1568 */ +#define X448MLKEM1024_SKSZ 3224 /* 56 + 3168 */ + +#define KEM_MODE_SERVER_ENCAP 0 /* Server encapsulates (default) */ +#define KEM_MODE_CLIENT_ENCAP 1 /* Client encapsulates */ +#define IS_KEX_ALGO_SET(cfg) ((cfg)->x.nid != NID_undef) +#define IS_KEX_CIPHER_SET(cfg) ((cfg)->c.nid != NID_undef) + + +struct crypt_sk { + int nid; + uint8_t * key; + uint8_t rot_bit; /* Rotation bit to control epoch */ +}; + +struct sec_config { + struct { + const char * str; + int nid; + int mode; + } x; /* key exchange */ + struct { + const char * str; + int nid; + } k; /* kdf */ + struct { + const char * str; + int nid; + } c; /* cipher */ + struct { + const char * str; + int nid; + } d; /* digest */ +}; + +/* Helper macros to set sec_config fields consistently */ +#define SET_KEX_ALGO(cfg, algo_str) do { \ + (cfg)->x.nid = kex_str_to_nid(algo_str); \ + (cfg)->x.str = kex_nid_to_str((cfg)->x.nid); \ + assert((cfg)->x.nid != NID_undef || (cfg)->x.str == NULL); \ +} while (0) + +#define SET_KEX_ALGO_NID(cfg, nid_val) do { \ + (cfg)->x.nid = (nid_val); \ + (cfg)->x.str = kex_nid_to_str((cfg)->x.nid); \ + assert((cfg)->x.nid != NID_undef || (cfg)->x.str == NULL); \ +} while (0) + +#define SET_KEX_KEM_MODE(cfg, mode_val) do { \ + (cfg)->x.mode = (mode_val); \ +} while (0) + +#define SET_KEX_KDF(cfg, kdf_str) do { \ + (cfg)->k.nid = md_str_to_nid(kdf_str); \ + (cfg)->k.str = md_nid_to_str((cfg)->k.nid); \ + assert((cfg)->k.nid != NID_undef || (cfg)->k.str == NULL); \ +} while (0) + +#define SET_KEX_KDF_NID(cfg, nid_val) do { \ + (cfg)->k.nid = (nid_val); \ + (cfg)->k.str = md_nid_to_str((cfg)->k.nid); \ + assert((cfg)->k.nid != NID_undef || (cfg)->k.str == NULL); \ +} while (0) + +#define SET_KEX_CIPHER(cfg, cipher_str) do { \ + (cfg)->c.nid = crypt_str_to_nid(cipher_str); \ + (cfg)->c.str = crypt_nid_to_str((cfg)->c.nid); \ + assert((cfg)->c.nid != NID_undef || (cfg)->c.str == NULL); \ +} while (0) + +#define SET_KEX_CIPHER_NID(cfg, nid_val) do { \ + (cfg)->c.nid = (nid_val); \ + (cfg)->c.str = crypt_nid_to_str((cfg)->c.nid); \ + assert((cfg)->c.nid != NID_undef || (cfg)->c.str == NULL); \ +} while (0) + +#define SET_KEX_DIGEST(cfg, digest_str) do { \ + (cfg)->d.nid = md_str_to_nid(digest_str); \ + (cfg)->d.str = md_nid_to_str((cfg)->d.nid); \ + assert((cfg)->d.nid != NID_undef || (cfg)->d.str == NULL); \ +} while (0) + +#define SET_KEX_DIGEST_NID(cfg, nid_val) do { \ + (cfg)->d.nid = (nid_val); \ + (cfg)->d.str = md_nid_to_str((cfg)->d.nid); \ + assert((cfg)->d.nid != NID_undef || (cfg)->d.str == NULL); \ +} while (0) + +#define CLEAR_KEX_ALGO(cfg) do { \ + (cfg)->x.nid = NID_undef; \ + (cfg)->x.str = NULL; \ +} while (0) + +#define CLEAR_KEX_KDF(cfg) do { \ + (cfg)->k.nid = NID_undef; \ + (cfg)->k.str = NULL; \ +} while (0) + +#define CLEAR_KEX_CIPHER(cfg) do { \ + (cfg)->c.nid = NID_undef; \ + (cfg)->c.str = NULL; \ +} while (0) + +#define CLEAR_KEX_DIGEST(cfg) do { \ + (cfg)->d.nid = NID_undef; \ + (cfg)->d.str = NULL; \ +} while (0) + +struct auth_ctx; +struct crypt_ctx; + +struct auth_ctx * auth_create_ctx(void); + +void auth_destroy_ctx(struct auth_ctx * ctx); + +int auth_add_crt_to_store(struct auth_ctx * ctx, + void * crt); + +int auth_verify_crt(struct auth_ctx * ctx, + void * crt); + +int auth_sign(void * pkp, + int md_nid, + buffer_t msg, + buffer_t * sig); + +int auth_verify_sig(void * pk, + int md_nid, + buffer_t msg, + buffer_t sig); + +int load_sec_config_file(struct sec_config * cfg, + const char * path); + +int kex_pkp_create(struct sec_config * cfg, + void ** pkp, + uint8_t * pk); + +void kex_pkp_destroy(void * pkp); + +int kex_dhe_derive(struct sec_config * cfg, + void * pkp, + buffer_t pk, + uint8_t * s); + +ssize_t kex_kem_encap(buffer_t pk, + uint8_t * ct, + int kdf_nid, + uint8_t * s); + +ssize_t kex_kem_encap_raw(buffer_t pk, + uint8_t * ct, + int kdf_nid, + uint8_t * s); + +int kex_kem_decap(void * pkp, + buffer_t ct, + int kdf_nid, + uint8_t * s); + +int kex_get_algo_from_pk_der(buffer_t pk, + char * algo); + +int kex_get_algo_from_pk_raw(buffer_t pk, + char * algo); + +int kex_validate_algo(const char * algo); + +int kex_validate_nid(int nid); + +const char * kex_nid_to_str(uint16_t nid); + +uint16_t kex_str_to_nid(const char * algo); + +struct crypt_ctx * crypt_create_ctx(struct crypt_sk * sk); + +void crypt_destroy_ctx(struct crypt_ctx * ctx); + +int crypt_validate_nid(int nid); + +const char * crypt_nid_to_str(uint16_t nid); + +uint16_t crypt_str_to_nid(const char * cipher); + +int md_validate_nid(int nid); + +const char * md_nid_to_str(uint16_t nid); + +uint16_t md_str_to_nid(const char * kdf); + +ssize_t md_digest(int md_nid, + buffer_t in, + uint8_t * out); + +ssize_t md_len(int md_nid); + +int crypt_encrypt(struct crypt_ctx * ctx, + buffer_t in, + buffer_t * out); + +int crypt_decrypt(struct crypt_ctx * ctx, + buffer_t in, + buffer_t * out); + +int crypt_get_ivsz(struct crypt_ctx * ctx); + +int crypt_get_tagsz(struct crypt_ctx * ctx); + +int crypt_load_crt_file(const char * path, + void ** crt); + +int crypt_load_crt_str(const char * str, + void ** crt); + +int crypt_load_crt_der(buffer_t buf, + void ** crt); + +int crypt_get_pubkey_crt(void * crt, + void ** pk); + +void crypt_free_crt(void * crt); + +int crypt_load_privkey_file(const char * path, + void ** key); + +int crypt_load_privkey_str(const char * str, + void ** key); + +int crypt_load_pubkey_str(const char * str, + void ** key); + +int crypt_load_pubkey_file(const char * path, + void ** key); + +int crypt_load_pubkey_file_to_der(const char * path, + buffer_t * buf); + +int crypt_load_pubkey_raw_file(const char * path, + buffer_t * buf); + +int crypt_load_privkey_raw_file(const char * path, + void ** key); + +int crypt_cmp_key(const void * key1, + const void * key2); + +void crypt_free_key(void * key); + +int crypt_crt_str(const void * crt, + char * buf); + +int crypt_crt_der(const void * crt, + buffer_t * buf); + +int crypt_check_crt_name(void * crt, + const char * name); + +int crypt_get_crt_name(void * crt, + char * name); + +/* Secure memory allocation for sensitive data (keys, secrets) */ +int crypt_secure_malloc_init(size_t max); + +void crypt_secure_malloc_fini(void); + +void * crypt_secure_malloc(size_t size); + +void crypt_secure_free(void * ptr, + size_t size); + +void crypt_secure_clear(void * ptr, + size_t size); + +#endif /* OUROBOROS_LIB_CRYPT_H */ diff --git a/include/ouroboros/dev.h b/include/ouroboros/dev.h index c402abd6..61464fbf 100644 --- a/include/ouroboros/dev.h +++ b/include/ouroboros/dev.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * API for applications * @@ -40,9 +40,8 @@ int flow_alloc(const char * dst_name, int flow_accept(qosspec_t * qs, const struct timespec * timeo); -/* Returns flow descriptor, qs updates to supplied QoS. */ +/* Returns flow descriptor. */ int flow_join(const char * bc, - qosspec_t * qs, const struct timespec * timeo); int flow_dealloc(int fd); diff --git a/include/ouroboros/endian.h b/include/ouroboros/endian.h index 530f66ba..6c3493d9 100644 --- a/include/ouroboros/endian.h +++ b/include/ouroboros/endian.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Endianness * @@ -20,9 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_ENDIAN_H -#define OUROBOROS_ENDIAN_H - +#ifndef OUROBOROS_LIB_ENDIAN_H +#define OUROBOROS_LIB_ENDIAN_H #if defined(__linux__) || defined(__CYGWIN__) || \ (defined(__MACH__) && !defined(__APPLE__)) @@ -67,10 +66,10 @@ #endif #define hton64(x) htobe64(x) -#define hton32(x) htobe32(x) #define ntoh64(x) betoh64(x) +#define hton32(x) htobe32(x) #define ntoh32(x) betoh32(x) #define hton16(x) htobe16(x) #define ntoh16(x) betoh16(x) -#endif /* OUROBOROS_ENDIAN_H */ +#endif /* OUROBOROS_LIB_ENDIAN_H */ diff --git a/include/ouroboros/errno.h b/include/ouroboros/errno.h index 06f33bef..6b808241 100644 --- a/include/ouroboros/errno.h +++ b/include/ouroboros/errno.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Ouroboros specific error numbers * @@ -31,7 +31,11 @@ #define EIPCP 1003 /* Failed to communicate with IPCP */ #define EIPCPSTATE 1004 /* Target in wrong state */ #define EFLOWDOWN 1005 /* Flow is down */ -#define ECRYPT 1006 /* Encryption error */ +#define EFLOWPEER 1006 /* Flow is down (peer timed out) */ #define ENAME 1007 /* Naming error */ +#define ECRYPT 1008 /* Encryption error */ +#ifndef EAUTH /* Exists on BSD */ +#define EAUTH 1009 /* Authentication error */ +#endif #endif /* OUROBOROS_ERRNO_H */ diff --git a/include/ouroboros/fccntl.h b/include/ouroboros/fccntl.h index e9f979f3..aa2b0d14 100644 --- a/include/ouroboros/fccntl.h +++ b/include/ouroboros/fccntl.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Flow and FRCT connection control * diff --git a/include/ouroboros/flow.h b/include/ouroboros/flow.h new file mode 100644 index 00000000..6b3dcde4 --- /dev/null +++ b/include/ouroboros/flow.h @@ -0,0 +1,58 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Flows + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_FLOW_H +#define OUROBOROS_LIB_FLOW_H + +#include <ouroboros/qos.h> + +#include <sys/types.h> + +#define SYMMKEYSZ 32 + +enum flow_state { /* DO NOT CHANGE ORDER! */ + FLOW_INIT = 0, + FLOW_ALLOC_PENDING, + FLOW_ACCEPT_PENDING, + FLOW_ALLOCATED, + FLOW_DEALLOC_PENDING, + FLOW_DEALLOCATED, + FLOW_DESTROY, /* TODO: REMOVE! */ + FLOW_NULL +}; + +struct flow_info { + int id; + + pid_t n_pid; + pid_t n_1_pid; + + uid_t uid; /* 0 = privileged (GSPP), > 0 = PUP uid */ + + time_t mpl; + + struct qos_spec qs; + + enum flow_state state; +}; + +#endif /* OUROBOROS_LIB_FLOW_H */ diff --git a/include/ouroboros/fqueue.h b/include/ouroboros/fqueue.h index f6828a4d..8eb2ff50 100644 --- a/include/ouroboros/fqueue.h +++ b/include/ouroboros/fqueue.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Flow queues * @@ -33,7 +33,8 @@ enum fqtype { FLOW_DOWN = (1 << 1), FLOW_UP = (1 << 2), FLOW_ALLOC = (1 << 3), - FLOW_DEALLOC = (1 << 4) + FLOW_DEALLOC = (1 << 4), + FLOW_PEER = (1 << 5) }; struct flow_set; diff --git a/include/ouroboros/hash.h b/include/ouroboros/hash.h index 917856a1..c44c2c8a 100644 --- a/include/ouroboros/hash.h +++ b/include/ouroboros/hash.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Hashing functions * @@ -25,49 +25,65 @@ #include "config.h" -#include <ouroboros/endian.h> +#include <ouroboros/ipcp.h> -#ifdef HAVE_LIBGCRYPT -#include <gcrypt.h> -#endif #include <stdint.h> #include <stddef.h> /* Hash algorithms */ enum hash_algo { -#ifdef HAVE_LIBGCRYPT - HASH_CRC32 = GCRY_MD_CRC32, - HASH_MD5 = GCRY_MD_MD5, - HASH_SHA3_224 = GCRY_MD_SHA3_224, - HASH_SHA3_256 = GCRY_MD_SHA3_256, - HASH_SHA3_384 = GCRY_MD_SHA3_384, - HASH_SHA3_512 = GCRY_MD_SHA3_512 -#else - HASH_CRC32 = 0, + HASH_SHA3_224 = DIR_HASH_SHA3_224, + HASH_SHA3_256 = DIR_HASH_SHA3_256, + HASH_SHA3_384 = DIR_HASH_SHA3_384, + HASH_SHA3_512 = DIR_HASH_SHA3_512, + HASH_CRC32, HASH_MD5, - HASH_SHA3_224, - HASH_SHA3_256, - HASH_SHA3_384, - HASH_SHA3_512 -#endif }; -#define HASH_FMT "%02x%02x%02x%02x" -#define HASH_VAL(hash) \ - (betoh32(*(uint32_t *) hash) & 0xFF000000) >> 24, \ - (betoh32(*(uint32_t *) hash) & 0x00FF0000) >> 16, \ - (betoh32(*(uint32_t *) hash) & 0x0000FF00) >> 8, \ - (betoh32(*(uint32_t *) hash) & 0x000000FF) +#define HASH_FMT32 "%02x%02x%02x%02x" +#define HASH_VAL32(hash) \ + ((uint8_t *) hash)[0], ((uint8_t *) hash)[1], \ + ((uint8_t *) hash)[2], ((uint8_t *) hash)[3] + +#define HASH_FMT64 HASH_FMT32 HASH_FMT32 +#define HASH_VAL64(hash64) \ + HASH_VAL32(hash64), HASH_VAL32(hash64 + 4) + +#define HASH_FMT128 HASH_FMT64 HASH_FMT64 +#define HASH_VAL128(hash128) \ + HASH_VAL64(hash128), HASH_VAL64(hash128 + 8) + +#define HASH_FMT192 HASH_FMT128 HASH_FMT64 +#define HASH_VAL192(hash192) \ + HASH_VAL128(hash192), HASH_VAL64(hash192 + 16) + +#define HASH_FMT224 HASH_FMT128 HASH_FMT64 HASH_FMT32 +#define HASH_VAL224(hash224) \ + HASH_VAL128(hash224), HASH_VAL64(hash224 + 16), \ + HASH_VAL32(hash224 + 24) + +#define HASH_FMT256 HASH_FMT128 HASH_FMT128 +#define HASH_VAL256(hash256) \ + HASH_VAL128(hash256), HASH_VAL128(hash256 + 16) + +#define HASH_FMT384 HASH_FMT256 HASH_FMT128 +#define HASH_VAL384(hash384) \ + HASH_VAL256(hash384), HASH_VAL128(hash384 + 32) + +#define HASH_FMT512 HASH_FMT256 HASH_FMT256 +#define HASH_VAL512(hash512) \ + HASH_VAL256(hash512), HASH_VAL256(hash512 + 32) + uint16_t hash_len(enum hash_algo algo); -void mem_hash(enum hash_algo algo, - void * dst, - const uint8_t * buf, - size_t len); +void mem_hash(enum hash_algo algo, + void * dst, + const uint8_t * buf, + size_t len); -void str_hash(enum hash_algo algo, - void * dst, - const char * str); +void str_hash(enum hash_algo algo, + void * dst, + const char * str); #endif /* OUROBOROS_LIB_HASH_H */ diff --git a/include/ouroboros/ipcp-dev.h b/include/ouroboros/ipcp-dev.h index 3cd40771..37c8064f 100644 --- a/include/ouroboros/ipcp-dev.h +++ b/include/ouroboros/ipcp-dev.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Additional API for IPCPs * @@ -20,30 +20,41 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#include <ouroboros/shm_rdrbuff.h> -#include <ouroboros/qoscube.h> +#ifndef OUROBOROS_LIB_IPCP_DEV_H +#define OUROBOROS_LIB_IPCP_DEV_H -#ifndef OUROBOROS_IPCP_DEV_H -#define OUROBOROS_IPCP_DEV_H +#include <ouroboros/ipcp.h> +#include <ouroboros/qoscube.h> +#include <ouroboros/ssm_pool.h> +#include <ouroboros/utils.h> -int ipcp_create_r(int result); +int ipcp_create_r(const struct ipcp_info * info); -int ipcp_flow_req_arr(const uint8_t * dst, - size_t len, - qosspec_t qs, - const void * data, - size_t dlen); +int ipcp_flow_req_arr(const buffer_t * dst, + qosspec_t qs, + time_t mpl, + const buffer_t * data); -int ipcp_flow_alloc_reply(int fd, - int response, - const void * data, - size_t len); +int ipcp_flow_alloc_reply(int fd, + int response, + time_t mpl, + const buffer_t * data); int ipcp_flow_read(int fd, - struct shm_du_buff ** sdb); + struct ssm_pk_buff ** spb); int ipcp_flow_write(int fd, - struct shm_du_buff * sdb); + struct ssm_pk_buff * spb); + +int np1_flow_read(int fd, + struct ssm_pk_buff ** spb, + struct ssm_pool * pool); + +int np1_flow_write(int fd, + struct ssm_pk_buff * spb, + struct ssm_pool * pool); + +int ipcp_flow_dealloc(int fd); int ipcp_flow_fini(int fd); @@ -52,9 +63,9 @@ int ipcp_flow_get_qoscube(int fd, size_t ipcp_flow_queued(int fd); -int ipcp_sdb_reserve(struct shm_du_buff ** sdb, +int ipcp_spb_reserve(struct ssm_pk_buff ** spb, size_t len); -void ipcp_sdb_release(struct shm_du_buff * sdb); +void ipcp_spb_release(struct ssm_pk_buff * spb); -#endif /* OUROBOROS_IPCP_DEV_H */ +#endif /* OUROBOROS_LIB_IPCP_DEV_H */ diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index a1bdae70..c397f250 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * IPCP definitions and policies * @@ -26,77 +26,349 @@ #include <stdint.h> #include <unistd.h> #include <stdbool.h> +#include <netinet/in.h> +#include <sys/types.h> +#define IPCP_NAME_SIZE 255 #define LAYER_NAME_SIZE 255 +#define DEV_NAME_SIZE 255 -/* - * NOTE: the IRMd uses this order to select an IPCP - * for flow allocation. - */ -enum ipcp_type { +/* TODO: Move state to ipcpd/ipcp.h, requires small change to reg/ipcp.c */ +enum ipcp_state { + IPCP_NULL = 0, + IPCP_INIT, + IPCP_BOOT, + IPCP_BOOTSTRAPPED, + IPCP_ENROLLED, + IPCP_OPERATIONAL, + IPCP_SHUTDOWN +}; + +enum ipcp_type { /* IRMd uses order to select an IPCP for flow allocation. */ IPCP_LOCAL = 0, IPCP_UNICAST, IPCP_BROADCAST, IPCP_ETH_LLC, IPCP_ETH_DIX, - IPCP_UDP, + IPCP_UDP4, + IPCP_UDP6, IPCP_INVALID }; +struct ipcp_info { + enum ipcp_type type; + pid_t pid; + char name[IPCP_NAME_SIZE + 1]; + enum ipcp_state state; /* TODO: remove. */ +}; + +/* Unicast IPCP components. */ +#define DT_COMP "Data Transfer" +#define MGMT_COMP "Management" + /* Unicast IPCP policies */ enum pol_addr_auth { - ADDR_AUTH_FLAT_RANDOM = 0 + ADDR_AUTH_FLAT_RANDOM = 0, + ADDR_AUTH_INVALID +}; + +enum pol_link_state { + LS_SIMPLE = 0, + LS_LFA, + LS_ECMP, + LS_INVALID +}; + +struct ls_config { + enum pol_link_state pol; /* Link state policy */ + time_t t_recalc; /* Time to recalculate PFF (s) */ + time_t t_update; /* Time between updates (s) */ + time_t t_timeo; /* Link timeout (s) */ +}; + +static const struct ls_config default_ls_config = { + .pol = LS_SIMPLE, + .t_recalc = 4, + .t_update = 15, + .t_timeo = 60 }; enum pol_routing { ROUTING_LINK_STATE = 0, - ROUTING_LINK_STATE_LFA, - ROUTING_LINK_STATE_ECMP + ROUTING_INVALID +}; + +struct routing_config { + enum pol_routing pol; /* Routing policy */ + union { + struct ls_config ls; /* Link state config */ + /* struct pv_config pv */ /* Path vector config */ + }; +}; + +static const struct routing_config default_routing_config = { + .pol = ROUTING_LINK_STATE, + .ls = { + .pol = LS_SIMPLE, + .t_recalc = 4, + .t_update = 15, + .t_timeo = 60 + } }; enum pol_cong_avoid { CA_NONE = 0, - CA_MB_ECN + CA_MB_ECN, + CA_INVALID +}; + +struct dt_config { + struct { + uint8_t addr_size; + uint8_t eid_size; + uint8_t max_ttl; + }; + struct routing_config routing; /* Routing policy */ +}; + +static const struct dt_config default_dt_config = { + .addr_size = 4, + .eid_size = 8, + .max_ttl = 60, + .routing = { + .pol = ROUTING_LINK_STATE, + .ls = { + .pol = LS_SIMPLE, + .t_recalc = 4, + .t_update = 15, + .t_timeo = 60 + } + } +}; + +enum pol_dir { + DIR_DHT = 0, + DIR_INVALID }; enum pol_dir_hash { - DIR_HASH_SHA3_224 = 0, + DIR_HASH_SHA3_224, DIR_HASH_SHA3_256, DIR_HASH_SHA3_384, - DIR_HASH_SHA3_512 + DIR_HASH_SHA3_512, + DIR_HASH_INVALID +}; + +enum dir_dht_config_limits { + DHT_ALPHA_MIN = 1, + DHT_K_MIN = 1, + DHT_T_EXPIRE_MIN = 10, + DHT_T_REFRESH_MIN = 3, + DHT_T_REPLICATE_MIN = 3, + + DHT_ALPHA_MAX = 10, + DHT_K_MAX = 20, + DHT_T_EXPIRE_MAX = 86400, + DHT_T_REFRESH_MAX = 3600, + DHT_T_REPLICATE_MAX = 3600, }; -/* Info reported back to the IRMd about the layer on enrollment */ +struct dir_dht_config { + struct { + uint32_t alpha; /* Parallel search factor */ + uint32_t k; /* Replication factor */ + uint32_t t_expire; /* Expire time (s) */ + uint32_t t_refresh; /* Refresh time (s) */ + uint32_t t_replicate; /* Replication time (s) */ + } params; + uint64_t peer; /* Initial peer address */ +}; + +static const struct dir_dht_config default_dht_config = { + .params = { + .alpha = 3, /* Proven optimal value */ + .k = 8, /* MDHT value */ + .t_expire = 86400, /* Expire after 1 day */ + .t_refresh = 900, /* MDHT value. */ + .t_replicate = 900 /* MDHT value. */ + } +}; + +/* TODO: Move hash algorithm in directory config */ +struct dir_config { + enum pol_dir pol; + union { + struct dir_dht_config dht; + }; +}; + +static const struct dir_config default_dir_config = { + .pol = DIR_DHT, + .dht = { + .params = { + .alpha = 3, + .k = 8, + .t_expire = 86400, + .t_refresh = 900, + .t_replicate = 900 + } + } +}; + +/* IPCP configuration */ +struct uni_config { + struct dt_config dt; + struct dir_config dir; + enum pol_addr_auth addr_auth_type; + enum pol_cong_avoid cong_avoid; +}; + +static const struct uni_config default_uni_config = { + .dt = { + .addr_size = 4, + .eid_size = 8, + .max_ttl = 60, + .routing = { + .pol = ROUTING_LINK_STATE, + .ls = { + .pol = LS_SIMPLE, + .t_recalc = 4, + .t_update = 15, + .t_timeo = 60 + } + } + }, + .dir = { + .pol = DIR_DHT, + .dht = { + .params = { + .alpha = 3, + .k = 8, + .t_expire = 86400, + .t_refresh = 900, + .t_replicate = 900 + } + } + }, + .addr_auth_type = ADDR_AUTH_FLAT_RANDOM, + .cong_avoid = CA_MB_ECN +}; + +struct eth_config { + char dev[DEV_NAME_SIZE + 1]; + uint16_t ethertype; /* DIX only*/ +}; + +struct udp4_config { + struct in_addr ip_addr; + struct in_addr dns_addr; + uint16_t port; +}; + +struct udp6_config { + struct in6_addr ip_addr; + struct in6_addr dns_addr; + uint16_t port; +}; + +/* Layers */ struct layer_info { - char layer_name[LAYER_NAME_SIZE + 1]; - int dir_hash_algo; + char name[LAYER_NAME_SIZE + 1]; + /* TODO: Move this to directory info ? */ + enum pol_dir_hash dir_hash_algo; }; /* Structure to configure the first IPCP */ struct ipcp_config { - struct layer_info layer_info; + struct layer_info layer_info; + enum ipcp_type type; - enum ipcp_type type; + union { + struct uni_config unicast; + struct udp4_config udp4; + struct udp6_config udp6; + struct eth_config eth; + }; +}; - /* Unicast */ - uint8_t addr_size; - uint8_t eid_size; - uint8_t max_ttl; +/* default configurations */ +static const struct ipcp_config local_default_conf = { + .type = IPCP_LOCAL, + .layer_info = { + .dir_hash_algo = DIR_HASH_SHA3_256 + } +}; - enum pol_addr_auth addr_auth_type; - enum pol_routing routing_type; - enum pol_cong_avoid cong_avoid; +static const struct ipcp_config eth_dix_default_conf = { + .type = IPCP_ETH_DIX, + .layer_info = { + .dir_hash_algo = DIR_HASH_SHA3_256 + }, + .eth = { + .ethertype=0xA000, + } +}; + +static const struct ipcp_config eth_llc_default_conf = { + .type = IPCP_ETH_LLC, + .layer_info = { + .dir_hash_algo = DIR_HASH_SHA3_256 + } +}; - /* UDP */ - uint32_t ip_addr; - uint32_t dns_addr; - uint16_t port; +static const struct ipcp_config udp4_default_conf = { + .type = IPCP_UDP4, + .udp4 = { + .port = 3435 + } +}; - /* Ethernet */ - char * dev; +static const struct ipcp_config udp6_default_conf = { + .type = IPCP_UDP6, + .udp6 = { + .port = 3435 + } +}; + +static const struct ipcp_config uni_default_conf = { + .type = IPCP_UNICAST, + .layer_info = { + .dir_hash_algo = DIR_HASH_SHA3_256 + }, + .unicast = { + .dt = { + .addr_size = 4, + .eid_size = 8, + .max_ttl = 60, + .routing = { + .pol = ROUTING_LINK_STATE, + .ls = { + .pol = LS_SIMPLE, + .t_recalc = 4, + .t_update = 15, + .t_timeo = 60 + } + } + }, + .dir = { + .pol = DIR_DHT, + .dht = { + .params = { + .alpha = 3, + .k = 8, + .t_expire = 86400, + .t_refresh = 900, + .t_replicate = 900 + } + } + }, + .addr_auth_type = ADDR_AUTH_FLAT_RANDOM, + .cong_avoid = CA_MB_ECN + } +}; - /* Ethernet DIX */ - uint16_t ethertype; +static const struct ipcp_config bc_default_conf = { + .type = IPCP_BROADCAST }; #endif /* OUROBOROS_IPCP_H */ diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index d2a4c263..70a21ed7 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * The API to instruct the IPC Resource Manager * @@ -25,36 +25,16 @@ #include <ouroboros/cdefs.h> #include <ouroboros/ipcp.h> +#include <ouroboros/name.h> #include <ouroboros/qos.h> #include <sys/types.h> -/* Unicast IPCP components. */ -#define DT_COMP "Data Transfer" -#define MGMT_COMP "Management" - -/* Name binding options. */ -#define BIND_AUTO 0x01 - -#define NAME_SIZE 256 -#define LAYER_SIZE LAYER_NAME_SIZE - -/* Load balancing policy for incoming flows. */ -enum pol_balance { - LB_RR = 0, - LB_SPILL -}; - -struct ipcp_info { +struct ipcp_list_info { pid_t pid; enum ipcp_type type; char name[NAME_SIZE]; - char layer[LAYER_SIZE]; -}; - -struct name_info { - char name[NAME_SIZE]; - enum pol_balance pol_lb; + char layer[LAYER_NAME_SIZE]; }; __BEGIN_DECLS @@ -64,7 +44,7 @@ pid_t irm_create_ipcp(const char * name, int irm_destroy_ipcp(pid_t pid); -ssize_t irm_list_ipcps(struct ipcp_info ** ipcps); +ssize_t irm_list_ipcps(struct ipcp_list_info ** ipcps); int irm_enroll_ipcp(pid_t pid, const char * dst); @@ -96,8 +76,7 @@ int irm_bind_process(pid_t pid, int irm_unbind_process(pid_t pid, const char * name); -int irm_create_name(const char * name, - enum pol_balance pol); +int irm_create_name(struct name_info * info); int irm_destroy_name(const char * name); diff --git a/include/ouroboros/list.h b/include/ouroboros/list.h index 408aa64e..f3ea0e46 100644 --- a/include/ouroboros/list.h +++ b/include/ouroboros/list.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Simple doubly linked list implementation. * @@ -61,6 +61,6 @@ void list_del(struct list_head * e); void list_move(struct list_head * dst, struct list_head * src); -bool list_is_empty(struct list_head * h); +bool list_is_empty(const struct list_head * h); #endif /* OUROBOROS_LIB_LIST_H */ diff --git a/include/ouroboros/local-dev.h b/include/ouroboros/local-dev.h index 103fe37b..cd0298d3 100644 --- a/include/ouroboros/local-dev.h +++ b/include/ouroboros/local-dev.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Optimized calls for the local IPCPs * @@ -20,12 +20,14 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_LOCAL_DEV_H -#define OUROBOROS_LOCAL_DEV_H +#ifndef OUROBOROS_LIB_LOCAL_DEV_H +#define OUROBOROS_LIB_LOCAL_DEV_H -ssize_t local_flow_read(int fd); +#include <ouroboros/ssm_pool.h> -int local_flow_write(int fd, - size_t idx); +int local_flow_transfer(int src_fd, + int dst_fd, + struct ssm_pool * src_pool, + struct ssm_pool * dst_pool); -#endif /* OUROBOROS_LOCAL_DEV_H */ +#endif /* OUROBOROS_LIB_LOCAL_DEV_H */ diff --git a/include/ouroboros/lockfile.h b/include/ouroboros/lockfile.h index b188d2b4..85a57313 100644 --- a/include/ouroboros/lockfile.h +++ b/include/ouroboros/lockfile.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Lockfile for Ouroboros * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_LOCKFILE_H -#define OUROBOROS_LOCKFILE_H +#ifndef OUROBOROS_LIB_LOCKFILE_H +#define OUROBOROS_LIB_LOCKFILE_H #include <sys/types.h> @@ -37,4 +37,4 @@ void lockfile_destroy(struct lockfile * lf); pid_t lockfile_owner(struct lockfile * lf); -#endif +#endif /* OUROBOROS_LIB_LOCKFILE_H */ diff --git a/include/ouroboros/logs.h b/include/ouroboros/logs.h index bffba477..31f11836 100644 --- a/include/ouroboros/logs.h +++ b/include/ouroboros/logs.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Logging facilities * @@ -20,56 +20,105 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_LOGS_H -#define OUROBOROS_LOGS_H - -#include <unistd.h> -#include <stdio.h> -#include <stdbool.h> -#include <syslog.h> +#ifndef OUROBOROS_LIB_LOGS_H +#define OUROBOROS_LIB_LOGS_H #ifndef OUROBOROS_PREFIX #error You must define OUROBOROS_PREFIX before including this file #endif -void log_init(bool sysout); +#include <ouroboros/hash.h> -void log_fini(void); +#include <unistd.h> +#include <stdio.h> +#include <stdbool.h> +#include <syslog.h> #define CLR_RED "\x1b[31m" #define CLR_GREEN "\x1b[32m" #define CLR_YELLOW "\x1b[33m" +#define CLR_BLUE "\x1b[34m" #define CLR_RESET "\x1b[0m" #define DEBUG_CODE "DB" #define ERROR_CODE "EE" #define WARN_CODE "WW" #define INFO_CODE "II" +#define PROTO_CODE "PP" extern bool log_syslog; -#define __olog(CLR, LVL, SYSLVL, ...) \ - do { \ - if (log_syslog) { \ - syslog(SYSLVL, OUROBOROS_PREFIX ": " \ - __VA_ARGS__); \ - } else { \ - printf(CLR "==%05d== " OUROBOROS_PREFIX \ - "(" LVL "): ", getpid()); \ - printf(__VA_ARGS__); \ - printf(CLR_RESET "\n"); \ - fflush(stdout); \ - } \ +void log_init(bool sysout); + +void log_fini(void); + + +#define __olog(CLR, LVL, SYSLVL, ...) \ + do { \ + if (log_syslog) { \ + syslog(SYSLVL, __VA_ARGS__); \ + } else { \ + printf(CLR "==%05d== " OUROBOROS_PREFIX \ + "(" LVL "): ", getpid()); \ + printf(__VA_ARGS__); \ + printf(CLR_RESET "\n"); \ + fflush(stdout); \ + } \ } while (0) -#define log_err(...) __olog(CLR_RED, ERROR_CODE, LOG_ERR, __VA_ARGS__) -#define log_warn(...) __olog(CLR_YELLOW, WARN_CODE, LOG_WARNING, __VA_ARGS__) -#define log_info(...) __olog(CLR_GREEN, INFO_CODE, LOG_INFO, __VA_ARGS__) +#define __olog_id(CLR, LVL, SYSLVL, id, fmt, ...) \ + do { \ + if (log_syslog) { \ + syslog(SYSLVL, "[" HASH_FMT64 "] " fmt, \ + HASH_VAL64(id), ## __VA_ARGS__); \ + } else { \ + printf(CLR "==%05d== " OUROBOROS_PREFIX \ + "(" LVL "): ", getpid()); \ + printf("[" HASH_FMT64 "] " fmt, \ + HASH_VAL64(id), ## __VA_ARGS__); \ + printf(CLR_RESET "\n"); \ + fflush(stdout); \ + } \ + } while (0) -#ifdef CONFIG_OUROBOROS_DEBUG -#define log_dbg(...) __olog("", DEBUG_CODE, LOG_DEBUG, __VA_ARGS__) -#else +#ifndef OUROBOROS_DISABLE_LOGGING +#define log_err(...) \ + __olog(CLR_RED, ERROR_CODE, LOG_ERR, __VA_ARGS__) +#define log_warn(...) \ + __olog(CLR_YELLOW, WARN_CODE, LOG_WARNING, __VA_ARGS__) +#define log_info(...) \ + __olog(CLR_GREEN, INFO_CODE, LOG_INFO, __VA_ARGS__) + + +#define log_err_id(id, fmt, ...) \ + __olog_id(CLR_RED, ERROR_CODE, LOG_ERR, id, fmt, ## __VA_ARGS__) +#define log_warn_id(id, fmt, ...) \ + __olog_id(CLR_YELLOW, WARN_CODE, LOG_WARNING, id, fmt, ## __VA_ARGS__) +#define log_info_id(id, fmt, ...) \ + __olog_id(CLR_GREEN, INFO_CODE, LOG_INFO, id, fmt, ## __VA_ARGS__) +#else /* OUROBOROS_DISABLE_LOGGING: all logging disabled */ +#define log_err(...) do { } while (0) +#define log_warn(...) do { } while (0) +#define log_info(...) do { } while (0) + +#define log_err_id(id, fmt, ...) do { (void)(id); } while (0) +#define log_warn_id(id, fmt, ...) do { (void)(id); } while (0) +#define log_info_id(id, fmt, ...) do { (void)(id); } while (0) + +#endif /* OUROBOROS_DISABLE_LOGGING */ + +#if defined(OUROBOROS_DISABLE_LOGGING) || !defined(CONFIG_OUROBOROS_DEBUG) #define log_dbg(...) do { } while (0) +#define log_dbg_id(id, ...) do { (void)(id); } while (0) +#define log_proto(...) do { } while (0) +#define log_proto_id(id, ...) do { (void)(id); } while (0) +#else +#define log_dbg(...) __olog("", DEBUG_CODE, LOG_DEBUG, __VA_ARGS__) +#define log_dbg_id(id, fmt, ...) \ + __olog_id("", DEBUG_CODE, LOG_DEBUG, id, fmt, ## __VA_ARGS__) +#define log_proto(...) __olog(CLR_BLUE, PROTO_CODE, LOG_DEBUG, __VA_ARGS__) +#define log_proto_id(id, fmt, ...) \ + __olog_id(CLR_BLUE, INFO_CODE, LOG_INFO, id, fmt, ## __VA_ARGS__) #endif -#endif /* OUROBOROS_LOGS_H */ +#endif /* OUROBOROS_LIB_LOGS_H */ diff --git a/include/ouroboros/md5.h b/include/ouroboros/md5.h index ab01996d..85a22544 100644 --- a/include/ouroboros/md5.h +++ b/include/ouroboros/md5.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * MD5 algorithm * diff --git a/include/ouroboros/name.h b/include/ouroboros/name.h new file mode 100644 index 00000000..892f2a1f --- /dev/null +++ b/include/ouroboros/name.h @@ -0,0 +1,50 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Names + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_NAME_H +#define OUROBOROS_NAME_H + +#define NAME_SIZE 255 +#define NAME_PATH_SIZE (NAME_SIZE + 256) +#define BIND_AUTO 0x01 + +enum pol_balance { + LB_RR = 0, + LB_SPILL, + LB_INVALID +}; + +struct name_sec_paths { + char enc[NAME_PATH_SIZE + 1]; /* path to crypt for this name */ + char key[NAME_PATH_SIZE + 1]; /* path to key for this name */ + char crt[NAME_PATH_SIZE + 1]; /* path to crt for this name */ +}; + +struct name_info { + char name[NAME_SIZE + 1]; + enum pol_balance pol_lb; + + struct name_sec_paths s; /* server */ + struct name_sec_paths c; /* client */ +}; + +#endif /* OUROBOROS_NAME_H */ diff --git a/include/ouroboros/notifier.h b/include/ouroboros/notifier.h index 429a8d97..db945f1e 100644 --- a/include/ouroboros/notifier.h +++ b/include/ouroboros/notifier.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Notifier event system using callbacks * diff --git a/include/ouroboros/np1_flow.h b/include/ouroboros/np1_flow.h index b764de91..4110ab6a 100644 --- a/include/ouroboros/np1_flow.h +++ b/include/ouroboros/np1_flow.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Adapter functions for N + 1 flow descriptors * @@ -20,20 +20,31 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_NP1_FLOW_H -#define OUROBOROS_NP1_FLOW_H +#ifndef OUROBOROS_LIB_NP1_FLOW_H +#define OUROBOROS_LIB_NP1_FLOW_H #include <ouroboros/qos.h> #include <unistd.h> -int np1_flow_alloc(pid_t n_pid, - int flow_id, - qosspec_t qs); +int np1_flow_alloc(pid_t n_pid, + int flow_id); -int np1_flow_resp(int flow_id); +int np1_flow_resp(int flow_id, + int resp); -int np1_flow_dealloc(int flow_id, +int np1_flow_dealloc(int flow_id, time_t timeo); -#endif /* OUROBOROS_NP1_FLOW_H */ +static const qosspec_t qos_np1 = { + .delay = UINT32_MAX, + .bandwidth = 0, + .availability = 0, + .loss = UINT32_MAX, + .ber = UINT32_MAX, + .in_order = 0, + .max_gap = UINT32_MAX, + .timeout = 0 +}; + +#endif /* OUROBOROS_LIB_NP1_FLOW_H */ diff --git a/include/ouroboros/proc.h b/include/ouroboros/proc.h new file mode 100644 index 00000000..0e27362e --- /dev/null +++ b/include/ouroboros/proc.h @@ -0,0 +1,45 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Processes and Programs + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_PROC_H +#define OUROBOROS_LIB_PROC_H + +#include <sys/types.h> + +#define PROG_NAME_SIZE 255 +#define PROG_PATH_SIZE 255 + +/* Processes */ +struct proc_info { + pid_t pid; + char prog[PROG_NAME_SIZE + 1]; + uid_t uid; + gid_t gid; +}; + +/* Programs */ +struct prog_info { + char name[PROG_NAME_SIZE + 1]; + char path[PROG_PATH_SIZE + 1]; +}; + +#endif /* OUROBOROS_LIB_PROC_H */ diff --git a/include/ouroboros/proto.h b/include/ouroboros/proto.h index f289e761..5c863c8b 100644 --- a/include/ouroboros/proto.h +++ b/include/ouroboros/proto.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Protocol syntax definitions * diff --git a/include/ouroboros/protobuf.h b/include/ouroboros/protobuf.h new file mode 100644 index 00000000..780d58dc --- /dev/null +++ b/include/ouroboros/protobuf.h @@ -0,0 +1,130 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Protobuf syntax conversion + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_PROTOBUF_H +#define OUROBOROS_LIB_PROTOBUF_H + +#include <ouroboros/flow.h> +#include <ouroboros/qos.h> +#include <ouroboros/ipcp.h> +#include <ouroboros/irm.h> +#include <ouroboros/serdes-irm.h> +#include <ouroboros/serdes-oep.h> + +#include "ipcp_config.pb-c.h" +typedef IpcpConfigMsg ipcp_config_msg_t; +typedef LsConfigMsg ls_config_msg_t; +typedef RoutingConfigMsg routing_config_msg_t; +typedef DtConfigMsg dt_config_msg_t; +typedef DirConfigMsg dir_config_msg_t; +typedef DirDhtConfigMsg dir_dht_config_msg_t; +typedef EthConfigMsg eth_config_msg_t; +typedef Udp4ConfigMsg udp4_config_msg_t; +typedef Udp6ConfigMsg udp6_config_msg_t; +typedef UniConfigMsg uni_config_msg_t; + +#include "ipcp.pb-c.h" +typedef IpcpMsg ipcp_msg_t; + +#include "irm.pb-c.h" +typedef IrmMsg irm_msg_t; +typedef TimespecMsg timespec_msg_t; +typedef IpcpInfoMsg ipcp_info_msg_t; +typedef IpcpListMsg ipcp_list_msg_t; + +#include "model.pb-c.h" +typedef FlowInfoMsg flow_info_msg_t; +typedef NameInfoMsg name_info_msg_t; +typedef LayerInfoMsg layer_info_msg_t; +typedef QosspecMsg qosspec_msg_t; + +#include "enroll.pb-c.h" +typedef EnrollReqMsg enroll_req_msg_t; +typedef EnrollRespMsg enroll_resp_msg_t; +typedef EnrollAckMsg enroll_ack_msg_t; + +/* IPCP configuration */ +timespec_msg_t * timespec_s_to_msg(const struct timespec * s); + +struct timespec timespec_msg_to_s(timespec_msg_t * msg); + +flow_info_msg_t * flow_info_s_to_msg(const struct flow_info * s); + +struct flow_info flow_info_msg_to_s(const flow_info_msg_t * msg); + +name_info_msg_t * name_info_s_to_msg(const struct name_info * s); + +struct name_info name_info_msg_to_s(const name_info_msg_t * msg); + +layer_info_msg_t * layer_info_s_to_msg(const struct layer_info * s); + +struct layer_info layer_info_msg_to_s(const layer_info_msg_t * msg); + +ipcp_info_msg_t * ipcp_info_s_to_msg(const struct ipcp_info * s); + +struct ipcp_info ipcp_info_msg_to_s(const ipcp_info_msg_t * msg); + +dt_config_msg_t * dt_config_s_to_msg(const struct dt_config * s); + +struct dt_config dt_config_msg_to_s(const dt_config_msg_t * msg); + +uni_config_msg_t * uni_config_s_to_msg(const struct uni_config * s); + +struct uni_config uni_config_msg_to_s(const uni_config_msg_t * msg); + +eth_config_msg_t * eth_config_s_to_msg(const struct eth_config * s); + +struct eth_config eth_config_msg_to_s(const eth_config_msg_t * msg); + +udp4_config_msg_t * udp4_config_s_to_msg(const struct udp4_config * s); + +struct udp4_config udp4_config_msg_to_s(const udp4_config_msg_t * msg); + +udp6_config_msg_t * udp6_config_s_to_msg(const struct udp6_config * s); + +struct udp6_config udp6_config_msg_to_s(const udp6_config_msg_t * msg); + +ipcp_config_msg_t * ipcp_config_s_to_msg(const struct ipcp_config * s); + +struct ipcp_config ipcp_config_msg_to_s(const ipcp_config_msg_t * msg); + +/* QoS */ + +qosspec_msg_t * qos_spec_s_to_msg(const struct qos_spec * s); + +struct qos_spec qos_spec_msg_to_s(const qosspec_msg_t * msg); + +/* Enrollment */ + +enroll_req_msg_t * enroll_req_s_to_msg(const struct enroll_req * s); + +struct enroll_req enroll_req_msg_to_s(const enroll_req_msg_t * msg); + +enroll_resp_msg_t * enroll_resp_s_to_msg(const struct enroll_resp * s); + +struct enroll_resp enroll_resp_msg_to_s(const enroll_resp_msg_t * msg); + +enroll_ack_msg_t * enroll_ack_s_to_msg(const struct enroll_ack * s); + +struct enroll_ack enroll_ack_msg_to_s(const enroll_ack_msg_t * msg); + +#endif /* OUROBOROS_LIB_PROTOBUF_H */ diff --git a/include/ouroboros/pthread.h b/include/ouroboros/pthread.h index 735557d2..7044cb5e 100644 --- a/include/ouroboros/pthread.h +++ b/include/ouroboros/pthread.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Useful cleanup functions for pthreads * @@ -20,20 +20,32 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_PTHREAD_H -#define OUROBOROS_PTHREAD_H +#ifndef OUROBOROS_LIB_PTHREAD_H +#define OUROBOROS_LIB_PTHREAD_H #include <pthread.h> +static int __attribute__((unused)) __timedwait(pthread_cond_t * cond, + pthread_mutex_t * mtx, + const struct timespec * abstime) +{ + if (abstime == NULL) + return pthread_cond_wait(cond, mtx); + + return pthread_cond_timedwait(cond, mtx, abstime); +} + +#if defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L /* various cleanup functions for pthread_cleanup_push */ static void __attribute__((unused)) __cleanup_rwlock_unlock(void * rwlock) { pthread_rwlock_unlock((pthread_rwlock_t *) rwlock); } +#endif static void __attribute__((unused)) __cleanup_mutex_unlock(void * mutex) { pthread_mutex_unlock((pthread_mutex_t *) mutex); } -#endif /* OUROBOROS_PTHREAD_H */ +#endif /* OUROBOROS_LIB_PTHREAD_H */ diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h index 6391347a..2be31305 100644 --- a/include/ouroboros/qos.h +++ b/include/ouroboros/qos.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Quality of Service specification * @@ -26,15 +26,17 @@ #include <stdint.h> #include <stdbool.h> +#define DEFAULT_PEER_TIMEOUT 120000 + typedef struct qos_spec { - uint32_t delay; /* In ms */ - uint64_t bandwidth; /* In bits/s */ - uint8_t availability; /* Class of 9s */ - uint32_t loss; /* Packet loss */ - uint32_t ber; /* Bit error rate, errors per billion bits */ - uint8_t in_order; /* In-order delivery, enables FRCT */ - uint32_t max_gap; /* In ms */ - uint16_t cypher_s; /* Cypher strength, 0 = no encryption */ + uint32_t delay; /* In ms. */ + uint64_t bandwidth; /* In bits/s. */ + uint8_t availability; /* Class of 9s. */ + uint32_t loss; /* Packet loss. */ + uint32_t ber; /* Bit error rate, errors per billion bits. */ + uint8_t in_order; /* In-order delivery, enables FRCT. */ + uint32_t max_gap; /* In ms. */ + uint32_t timeout; /* Peer timeout time, in ms, 0 = no timeout. */ } qosspec_t; static const qosspec_t qos_raw = { @@ -45,7 +47,7 @@ static const qosspec_t qos_raw = { .ber = 1, .in_order = 0, .max_gap = UINT32_MAX, - .cypher_s = 0 + .timeout = DEFAULT_PEER_TIMEOUT }; static const qosspec_t qos_raw_no_errors = { @@ -56,18 +58,7 @@ static const qosspec_t qos_raw_no_errors = { .ber = 0, .in_order = 0, .max_gap = UINT32_MAX, - .cypher_s = 0 -}; - -static const qosspec_t qos_raw_crypt = { - .delay = UINT32_MAX, - .bandwidth = 0, - .availability = 0, - .loss = 1, - .ber = 0, - .in_order = 0, - .max_gap = UINT32_MAX, - .cypher_s = 256 + .timeout = DEFAULT_PEER_TIMEOUT }; static const qosspec_t qos_best_effort = { @@ -78,18 +69,7 @@ static const qosspec_t qos_best_effort = { .ber = 0, .in_order = 1, .max_gap = UINT32_MAX, - .cypher_s = 0 -}; - -static const qosspec_t qos_best_effort_crypt = { - .delay = UINT32_MAX, - .bandwidth = 0, - .availability = 0, - .loss = 1, - .ber = 0, - .in_order = 1, - .max_gap = UINT32_MAX, - .cypher_s = 256 + .timeout = DEFAULT_PEER_TIMEOUT }; static const qosspec_t qos_video = { @@ -100,18 +80,7 @@ static const qosspec_t qos_video = { .ber = 0, .in_order = 1, .max_gap = 100, - .cypher_s = 0 -}; - -static const qosspec_t qos_video_crypt = { - .delay = 100, - .bandwidth = UINT64_MAX, - .availability = 3, - .loss = 1, - .ber = 0, - .in_order = 1, - .max_gap = 100, - .cypher_s = 256 + .timeout = DEFAULT_PEER_TIMEOUT }; static const qosspec_t qos_voice = { @@ -122,18 +91,7 @@ static const qosspec_t qos_voice = { .ber = 0, .in_order = 1, .max_gap = 50, - .cypher_s = 0 -}; - -static const qosspec_t qos_voice_crypt = { - .delay = 50, - .bandwidth = 100000, - .availability = 5, - .loss = 1, - .ber = 0, - .in_order = 1, - .max_gap = 50, - .cypher_s = 256 + .timeout = DEFAULT_PEER_TIMEOUT }; static const qosspec_t qos_data = { @@ -144,18 +102,7 @@ static const qosspec_t qos_data = { .ber = 0, .in_order = 1, .max_gap = 2000, - .cypher_s = 0 -}; - -static const qosspec_t qos_data_crypt = { - .delay = 1000, - .bandwidth = 0, - .availability = 0, - .loss = 0, - .ber = 0, - .in_order = 1, - .max_gap = 2000, - .cypher_s = 256 + .timeout = DEFAULT_PEER_TIMEOUT }; #endif /* OUROBOROS_QOS_H */ diff --git a/include/ouroboros/qoscube.h b/include/ouroboros/qoscube.h index 48705ffc..ed20484c 100644 --- a/include/ouroboros/qoscube.h +++ b/include/ouroboros/qoscube.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Quality of Service cubes * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_QOSCUBE_H -#define OUROBOROS_QOSCUBE_H +#ifndef OUROBOROS_LIB_QOSCUBE_H +#define OUROBOROS_LIB_QOSCUBE_H #include <ouroboros/qos.h> @@ -35,4 +35,4 @@ typedef enum qos_cube { qoscube_t qos_spec_to_cube(qosspec_t qs); qosspec_t qos_cube_to_spec(qoscube_t qc); -#endif +#endif /* OUROBOROS_LIB_QOSCUBE_H */ diff --git a/include/ouroboros/random.h b/include/ouroboros/random.h index 1f1ab057..e1b25e5d 100644 --- a/include/ouroboros/random.h +++ b/include/ouroboros/random.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Pseudo random generator * @@ -20,12 +20,12 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_RANDOM_H -#define OUROBOROS_RANDOM_H +#ifndef OUROBOROS_LIB_RANDOM_H +#define OUROBOROS_LIB_RANDOM_H #include <sys/types.h> int random_buffer(void * buf, size_t len); -#endif /* OUROBOROS_RANDOM_H */ +#endif /* OUROBOROS_LIB_RANDOM_H */ diff --git a/include/ouroboros/rib.h b/include/ouroboros/rib.h index 9eab6334..cdc5a9d5 100644 --- a/include/ouroboros/rib.h +++ b/include/ouroboros/rib.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * RIB export using FUSE * @@ -23,8 +23,10 @@ #ifndef OUROBOROS_LIB_RIB_H #define OUROBOROS_LIB_RIB_H -#define RIB_PATH_LEN 128 +#define RIB_PATH_LEN 300 #define RIB_SEPARATOR "/" +#define RIB_TM_STRLEN 26 +#define RIB_TM_FORMAT "%F %T (UTC)" #include <sys/types.h> @@ -53,4 +55,6 @@ int rib_reg(const char * path, void rib_unreg(const char * path); +void rib_cleanup(const char * mnt); + #endif /* OUROBOROS_LIB_RIB_H */ diff --git a/include/ouroboros/serdes-irm.h b/include/ouroboros/serdes-irm.h new file mode 100644 index 00000000..bd04fc57 --- /dev/null +++ b/include/ouroboros/serdes-irm.h @@ -0,0 +1,80 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Ouroboros IRM Protocol - serialization/deserialization + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_SERDES_IRM_H +#define OUROBOROS_LIB_SERDES_IRM_H + +#include <ouroboros/crypt.h> +#include <ouroboros/flow.h> +#include <ouroboros/ipcp.h> +#include <ouroboros/proc.h> +#include <ouroboros/time.h> +#include <ouroboros/utils.h> + +#include <inttypes.h> + +int flow_alloc__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const char * dst, + const struct timespec * timeo); + +int flow_join__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const char * dst, + const struct timespec * timeo); + +int flow_accept__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const struct timespec * timeo); + +int ipcp_flow_req_arr__irm_req_ser(buffer_t * buf, + const buffer_t * dst, + const struct flow_info * flow, + const buffer_t * data); + +int ipcp_flow_alloc_reply__irm_msg_ser(buffer_t * buf, + const struct flow_info * flow, + int response, + const buffer_t * data); + +int flow__irm_result_des(buffer_t * buf, + struct flow_info * flow, + struct crypt_sk * sk); + +int flow_dealloc__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const struct timespec * timeo); + +int ipcp_flow_dealloc__irm_req_ser(buffer_t * buf, + const struct flow_info * info); + +int ipcp_create_r__irm_req_ser(buffer_t * buf, + const struct ipcp_info * ipcp); + +int proc_announce__irm_req_ser(buffer_t * buf, + const struct proc_info * proc); + +int proc_exit__irm_req_ser(buffer_t * buf); + +int irm__irm_result_des(buffer_t * buf); + +#endif /* OUROBOROS_LIB_SERDES_IRM_H*/ diff --git a/include/ouroboros/serdes-oep.h b/include/ouroboros/serdes-oep.h new file mode 100644 index 00000000..f7d8561a --- /dev/null +++ b/include/ouroboros/serdes-oep.h @@ -0,0 +1,69 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Ouroboros Enrollment Protocol - serialization/deserialization + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_SERDES_OEP_H +#define OUROBOROS_LIB_SERDES_OEP_H + +#include <ouroboros/ipcp.h> +#include <ouroboros/utils.h> + +#include <sys/time.h> + +/* Enrollment */ + +#define ENROLL_ID_LEN 8 + +struct enroll_req { + uint8_t id[ENROLL_ID_LEN]; +}; + +struct enroll_resp { + uint8_t id[ENROLL_ID_LEN]; + struct timespec t; + int response; + struct ipcp_config conf; +}; + +struct enroll_ack { + uint8_t id[ENROLL_ID_LEN]; + int result; +}; + +ssize_t enroll_req_ser(const struct enroll_req * req, + buffer_t buf); + +int enroll_req_des(struct enroll_req * req, + const buffer_t buf); + +ssize_t enroll_resp_ser(const struct enroll_resp * resp, + buffer_t buf); + +int enroll_resp_des(struct enroll_resp * resp, + buffer_t buf); + +ssize_t enroll_ack_ser(const struct enroll_ack * ack, + buffer_t buf); + +int enroll_ack_des(struct enroll_ack * ack, + const buffer_t buf); + +#endif /* OUROBOROS_LIB_SERDES_OEP_H*/ diff --git a/include/ouroboros/sha3.h b/include/ouroboros/sha3.h index 41967599..04871f3b 100644 --- a/include/ouroboros/sha3.h +++ b/include/ouroboros/sha3.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * SHA3 algorithm * diff --git a/include/ouroboros/shm_rdrbuff.h b/include/ouroboros/shm_rdrbuff.h deleted file mode 100644 index 0bce681b..00000000 --- a/include/ouroboros/shm_rdrbuff.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2021 - * - * Random Deletion Ring Buffer for Data Units - * - * Dimitri Staessens <dimitri@ouroboros.rocks> - * Sander Vrijders <sander@ouroboros.rocks> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_SHM_RDRBUFF_H -#define OUROBOROS_SHM_RDRBUFF_H - -#include <ouroboros/shm_du_buff.h> -#include <ouroboros/time_utils.h> - -#include <stdint.h> -#include <pthread.h> -#include <sys/types.h> - -struct shm_rdrbuff; - -struct shm_rdrbuff * shm_rdrbuff_create(void); - -struct shm_rdrbuff * shm_rdrbuff_open(void); - -void shm_rdrbuff_close(struct shm_rdrbuff * rdrb); - -void shm_rdrbuff_destroy(struct shm_rdrbuff * rdrb); - -void shm_rdrbuff_purge(void); - -/* Returns block index, a ptr and du_buff. */ -ssize_t shm_rdrbuff_alloc(struct shm_rdrbuff * rdrb, - size_t count, - uint8_t ** ptr, - struct shm_du_buff ** sdb); - -ssize_t shm_rdrbuff_alloc_b(struct shm_rdrbuff * rdrb, - size_t count, - uint8_t ** ptr, - struct shm_du_buff ** sdb, - const struct timespec * abstime); - -ssize_t shm_rdrbuff_read(uint8_t ** dst, - struct shm_rdrbuff * rdrb, - size_t idx); - -struct shm_du_buff * shm_rdrbuff_get(struct shm_rdrbuff * rdrb, - size_t idx); - -int shm_rdrbuff_remove(struct shm_rdrbuff * rdrb, - size_t idx); - -#endif /* OUROBOROS_SHM_RDRBUFF_H */ diff --git a/include/ouroboros/sockets.h.in b/include/ouroboros/sockets.h.in index f1162163..1a6974ac 100644 --- a/include/ouroboros/sockets.h.in +++ b/include/ouroboros/sockets.h.in @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * The sockets layer to communicate between daemons * @@ -20,52 +20,37 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_SOCKETS_H -#define OUROBOROS_SOCKETS_H +#ifndef OUROBOROS_LIB_SOCKETS_H +#define OUROBOROS_LIB_SOCKETS_H -#include <ouroboros/qos.h> +#include <ouroboros/protobuf.h> #include <sys/types.h> -#include "ipcp_config.pb-c.h" -typedef IpcpConfigMsg ipcp_config_msg_t; -typedef LayerInfoMsg layer_info_msg_t; - -#include "irmd_messages.pb-c.h" -typedef IrmMsg irm_msg_t; -typedef IpcpInfoMsg ipcp_info_msg_t; -typedef NameInfoMsg name_info_msg_t; - -#include "ipcpd_messages.pb-c.h" -typedef IpcpMsg ipcp_msg_t; - -#include "qosspec.pb-c.h" -typedef QosspecMsg qosspec_msg_t; - -#define SOCK_PATH "/var/run/ouroboros/" -#define SOCK_PATH_SUFFIX ".sock" +#ifndef OUROBOROS_TEST + #define SOCK_PATH "/var/run/ouroboros/" +#else + #define SOCK_PATH "/tmp/" +#endif +#define SOCK_PATH_SUFFIX ".sock" -#define IRM_SOCK_PATH SOCK_PATH "irm" SOCK_PATH_SUFFIX -#define IPCP_SOCK_PATH_PREFIX SOCK_PATH "ipcp" +#define IRM_SOCK_PATH SOCK_PATH "irm" SOCK_PATH_SUFFIX +#define IPCP_SOCK_PATH_PREFIX SOCK_PATH "ipcp." -#define SOCK_BUF_SIZE @SOCK_BUF_SIZE@ +#define SOCK_BUF_SIZE @SOCK_BUF_SIZE@ -/* Returns the full socket path of an IPCP */ -char * ipcp_sock_path(pid_t pid); +char * sock_path(pid_t pid, + const char * path); int server_socket_open(char * file_name); int client_socket_open(char * file_name); -irm_msg_t * send_recv_irm_msg(irm_msg_t * msg); - - -/* qos message conversion needed in different components */ -qosspec_msg_t spec_to_msg(const qosspec_t * qs); +int send_recv_msg(buffer_t * buf); -qosspec_t msg_to_spec(const qosspec_msg_t * msg); +irm_msg_t * send_recv_irm_msg(irm_msg_t * msg); /* cleanup socket when cancelling thread */ void __cleanup_close_ptr(void * o); -#endif +#endif /* OUROBOROS_LIB_SOCKETS_H */ diff --git a/include/ouroboros/shm_flow_set.h b/include/ouroboros/ssm_flow_set.h index ba085aef..02a5cb71 100644 --- a/include/ouroboros/shm_flow_set.h +++ b/include/ouroboros/ssm_flow_set.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Management of flow_sets for fqueue * @@ -20,45 +20,50 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_SHM_FLOW_SET_H -#define OUROBOROS_SHM_FLOW_SET_H +#ifndef OUROBOROS_LIB_SSM_FLOW_SET_H +#define OUROBOROS_LIB_SSM_FLOW_SET_H #include <ouroboros/fqueue.h> #include <sys/time.h> -struct shm_flow_set; +struct flowevent { + int flow_id; + int event; +}; -struct shm_flow_set * shm_flow_set_create(pid_t pid); +struct ssm_flow_set; -void shm_flow_set_destroy(struct shm_flow_set * set); +struct ssm_flow_set * ssm_flow_set_create(pid_t pid); -struct shm_flow_set * shm_flow_set_open(pid_t pid); +void ssm_flow_set_destroy(struct ssm_flow_set * set); -void shm_flow_set_close(struct shm_flow_set * set); +struct ssm_flow_set * ssm_flow_set_open(pid_t pid); -void shm_flow_set_zero(struct shm_flow_set * shm_set, +void ssm_flow_set_close(struct ssm_flow_set * set); + +void ssm_flow_set_zero(struct ssm_flow_set * set, size_t idx); -int shm_flow_set_add(struct shm_flow_set * shm_set, +int ssm_flow_set_add(struct ssm_flow_set * set, size_t idx, int flow_id); -int shm_flow_set_has(struct shm_flow_set * shm_set, +int ssm_flow_set_has(struct ssm_flow_set * set, size_t idx, int flow_id); -void shm_flow_set_del(struct shm_flow_set * shm_set, +void ssm_flow_set_del(struct ssm_flow_set * set, size_t idx, int flow_id); -void shm_flow_set_notify(struct shm_flow_set * set, +void ssm_flow_set_notify(struct ssm_flow_set * set, int flow_id, int event); -ssize_t shm_flow_set_wait(const struct shm_flow_set * shm_set, +ssize_t ssm_flow_set_wait(const struct ssm_flow_set * set, size_t idx, - int * fqueue, + struct flowevent * fqueue, const struct timespec * abstime); -#endif /* OUROBOROS_SHM_FLOW_SET_H */ +#endif /* OUROBOROS_LIB_SSM_FLOW_SET_H */ diff --git a/include/ouroboros/shm_du_buff.h b/include/ouroboros/ssm_pk_buff.h index da350055..9b82ede3 100644 --- a/include/ouroboros/shm_du_buff.h +++ b/include/ouroboros/ssm_pk_buff.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Data Buffer element in Random Deletion Ring Buffer * @@ -20,37 +20,39 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_SHM_DU_BUFF_H -#define OUROBOROS_SHM_DU_BUFF_H +#ifndef OUROBOROS_LIB_SSM_PK_BUFF_H +#define OUROBOROS_LIB_SSM_PK_BUFF_H #include <sys/types.h> #include <stdint.h> -struct shm_du_buff; +struct ssm_pk_buff; -size_t shm_du_buff_get_idx(struct shm_du_buff * sdb); +size_t ssm_pk_buff_get_idx(struct ssm_pk_buff * spb); -uint8_t * shm_du_buff_head(struct shm_du_buff * sdb); +uint8_t * ssm_pk_buff_head(struct ssm_pk_buff * spb); -uint8_t * shm_du_buff_tail(struct shm_du_buff * sdb); +uint8_t * ssm_pk_buff_tail(struct ssm_pk_buff * spb); -uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb, +size_t ssm_pk_buff_len(struct ssm_pk_buff * spb); + +uint8_t * ssm_pk_buff_head_alloc(struct ssm_pk_buff * spb, size_t size); -uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb, +uint8_t * ssm_pk_buff_tail_alloc(struct ssm_pk_buff * spb, size_t size); -uint8_t * shm_du_buff_head_release(struct shm_du_buff * sdb, +uint8_t * ssm_pk_buff_head_release(struct ssm_pk_buff * spb, size_t size); -uint8_t * shm_du_buff_tail_release(struct shm_du_buff * sdb, +uint8_t * ssm_pk_buff_tail_release(struct ssm_pk_buff * spb, size_t size); -void shm_du_buff_truncate(struct shm_du_buff * sdb, +void ssm_pk_buff_truncate(struct ssm_pk_buff * spb, size_t len); -int shm_du_buff_wait_ack(struct shm_du_buff * sdb); +int ssm_pk_buff_wait_ack(struct ssm_pk_buff * spb); -int shm_du_buff_ack(struct shm_du_buff * sdb); +int ssm_pk_buff_ack(struct ssm_pk_buff * spb); -#endif /* OUROBOROS_SHM_DU_BUFF_H */ +#endif /* OUROBOROS_LIB_SSM_PK_BUFF_H */ diff --git a/include/ouroboros/ssm_pool.h b/include/ouroboros/ssm_pool.h new file mode 100644 index 00000000..4becbdf5 --- /dev/null +++ b/include/ouroboros/ssm_pool.h @@ -0,0 +1,74 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Secure Shared Memory infrastructure (SSM) Packet Buffer + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_SSM_POOL_H +#define OUROBOROS_LIB_SSM_POOL_H + +#include <ouroboros/ssm_pk_buff.h> +#include <ouroboros/time.h> + +#include <pthread.h> +#include <stdint.h> +#include <sys/types.h> + +struct ssm_pool; + +/* Pool API: uid = 0 for GSPP (privileged), uid > 0 for PUP (per-user) */ +struct ssm_pool * ssm_pool_create(uid_t uid, + gid_t gid); + +struct ssm_pool * ssm_pool_open(uid_t uid); + +void ssm_pool_close(struct ssm_pool * pool); + +void ssm_pool_destroy(struct ssm_pool * pool); + +int ssm_pool_mlock(struct ssm_pool * pool); + +void ssm_pool_gspp_purge(void); + +/* Alloc count bytes, returns block index, a ptr and pk_buff. */ +ssize_t ssm_pool_alloc(struct ssm_pool * pool, + size_t count, + uint8_t ** ptr, + struct ssm_pk_buff ** spb); + +ssize_t ssm_pool_alloc_b(struct ssm_pool * pool, + size_t count, + uint8_t ** ptr, + struct ssm_pk_buff ** spb, + const struct timespec * abstime); + +ssize_t ssm_pool_read(uint8_t ** dst, + struct ssm_pool * pool, + size_t idx); + +struct ssm_pk_buff * ssm_pool_get(struct ssm_pool * pool, + size_t idx); + +int ssm_pool_remove(struct ssm_pool * pool, + size_t idx); + +void ssm_pool_reclaim_orphans(struct ssm_pool * pool, + pid_t pid); + +#endif /* OUROBOROS_LIB_SSM_POOL_H */ diff --git a/include/ouroboros/shm_rbuff.h b/include/ouroboros/ssm_rbuff.h index e853e487..791befa2 100644 --- a/include/ouroboros/shm_rbuff.h +++ b/include/ouroboros/ssm_rbuff.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Ring buffer for incoming packets * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_SHM_RBUFF_H -#define OUROBOROS_SHM_RBUFF_H +#ifndef OUROBOROS_LIB_SSM_RBUFF_H +#define OUROBOROS_LIB_SSM_RBUFF_H #include <sys/types.h> #include <sys/time.h> @@ -31,38 +31,41 @@ #define ACL_RDWR 0000 #define ACL_RDONLY 0001 #define ACL_FLOWDOWN 0002 +#define ACL_FLOWPEER 0004 -struct shm_rbuff; +struct ssm_rbuff; -struct shm_rbuff * shm_rbuff_create(pid_t pid, +struct ssm_rbuff * ssm_rbuff_create(pid_t pid, int flow_id); -struct shm_rbuff * shm_rbuff_open(pid_t pid, - int flow_id); +void ssm_rbuff_destroy(struct ssm_rbuff * rb); -void shm_rbuff_close(struct shm_rbuff * rb); +struct ssm_rbuff * ssm_rbuff_open(pid_t pid, + int flow_id); -void shm_rbuff_destroy(struct shm_rbuff * rb); +void ssm_rbuff_close(struct ssm_rbuff * rb); -void shm_rbuff_set_acl(struct shm_rbuff * rb, +void ssm_rbuff_set_acl(struct ssm_rbuff * rb, uint32_t flags); -uint32_t shm_rbuff_get_acl(struct shm_rbuff * rb); +uint32_t ssm_rbuff_get_acl(struct ssm_rbuff * rb); + +void ssm_rbuff_fini(struct ssm_rbuff * rb); -void shm_rbuff_fini(struct shm_rbuff * rb); +int ssm_rbuff_mlock(struct ssm_rbuff * rb); -int shm_rbuff_write(struct shm_rbuff * rb, +int ssm_rbuff_write(struct ssm_rbuff * rb, size_t idx); -int shm_rbuff_write_b(struct shm_rbuff * rb, +int ssm_rbuff_write_b(struct ssm_rbuff * rb, size_t idx, const struct timespec * abstime); -ssize_t shm_rbuff_read(struct shm_rbuff * rb); +ssize_t ssm_rbuff_read(struct ssm_rbuff * rb); -ssize_t shm_rbuff_read_b(struct shm_rbuff * rb, +ssize_t ssm_rbuff_read_b(struct ssm_rbuff * rb, const struct timespec * abstime); -size_t shm_rbuff_queued(struct shm_rbuff * rb); +size_t ssm_rbuff_queued(struct ssm_rbuff * rb); -#endif /* OUROBOROS_SHM_RBUFF_H */ +#endif /* OUROBOROS_LIB_SSM_RBUFF_H */ diff --git a/include/ouroboros/time_utils.h b/include/ouroboros/time.h index 6e51f305..3bd6a257 100644 --- a/include/ouroboros/time_utils.h +++ b/include/ouroboros/time.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Time utilities * @@ -20,8 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_TIME_UTILS_H -#define OUROBOROS_TIME_UTILS_H +#ifndef OUROBOROS_LIB_TIME_H +#define OUROBOROS_LIB_TIME_H #ifdef MILLION #undef MILLION @@ -31,25 +31,38 @@ #undef BILLION #endif -#define MILLION 1000000L -#define BILLION 1000000000L +#define MILLION 1000000LL +#define BILLION 1000000000LL #include <time.h> #include <sys/time.h> +#include <sys/types.h> + +#define TIMESPEC_INIT_S(s) {(s), 0} +#define TIMESPEC_INIT_MS(ms) {(ms) / 1000, ((ms) % 1000) * MILLION} +#define TIMESPEC_INIT_US(us) {(us) / MILLION, ((us) % MILLION) * 1000} +#define TIMESPEC_INIT_NS(ns) {(ns) / BILLION, ((ns) % BILLION)} + +#define TS_TO_UINT64(ts) \ + ((uint64_t)(ts).tv_sec * BILLION + (uint64_t)(ts).tv_nsec) + +#define TIMEVAL_INIT_S(s) {(s), 0} +#define TIMEVAL_INIT_MS(ms) {(ms) / 1000, ((ms) % 1000) * 1000} +#define TIMEVAL_INIT_US(us) {(us) / MILLION, ((us) % MILLION)} /* functions for timespecs */ -#define ts_diff_ns(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * BILLION \ +#define ts_diff_ns(tx, t0) (((tx)->tv_sec - (t0)->tv_sec) * BILLION \ + ((tx)->tv_nsec - (t0)->tv_nsec)) -#define ts_diff_us(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * MILLION \ +#define ts_diff_us(tx, t0) (((tx)->tv_sec - (t0)->tv_sec) * MILLION \ + ((tx)->tv_nsec - (t0)->tv_nsec) / 1000L) -#define ts_diff_ms(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * 1000L \ +#define ts_diff_ms(tx, t0) (((tx)->tv_sec - (t0)->tv_sec) * 1000L \ + ((tx)->tv_nsec - (t0)->tv_nsec) / MILLION) /* functions for timevals are the same */ -#define tv_diff_us(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * MILLION \ +#define tv_diff_us(tx, t0) (((tx)->tv_sec - (t0)->tv_sec) * MILLION \ + + ((tx)->tv_usec - (t0)->tv_usec)) +#define tv_diff_ms(tx, t0) (((tx)->tv_sec - (t0)->tv_sec) * 1000L \ + ((tx)->tv_usec - (t0)->tv_usec) / 1000L) -#define tv_diff_ms(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * 1000L \ - + ((tx)->tv_usec - (t0)->tv_usec) / MILLION) /* functions for timespecs */ @@ -118,4 +131,4 @@ (tv)->tv_usec = (ts)->tv_nsec / 1000L; \ } while (0); -#endif /* OUROBOROS_TIME_UTILS_H */ +#endif /* OUROBOROS_LIB_TIME_H */ diff --git a/include/ouroboros/tpm.h b/include/ouroboros/tpm.h index a69549d2..3fb49b88 100644 --- a/include/ouroboros/tpm.h +++ b/include/ouroboros/tpm.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Threadpool management * @@ -38,8 +38,10 @@ int tpm_start(struct tpm * tpm); void tpm_stop(struct tpm * tpm); -void tpm_dec(struct tpm * tpm); +void tpm_begin_work(struct tpm * tpm); -void tpm_inc(struct tpm * tpm); +void tpm_wait_work(struct tpm * tpm); + +void tpm_end_work(struct tpm * tpm); #endif /* OUROBOROS_LIB_TPM_H */ diff --git a/include/ouroboros/utils.h b/include/ouroboros/utils.h index 426a143c..f53361eb 100644 --- a/include/ouroboros/utils.h +++ b/include/ouroboros/utils.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Handy utilities * @@ -20,38 +20,67 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_UTILS_H -#define OUROBOROS_UTILS_H +#ifndef OUROBOROS_LIB_UTILS_H +#define OUROBOROS_LIB_UTILS_H +#include <stdbool.h> #include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> #include <unistd.h> #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define ABS(a) ((a) > 0 ? (a) : -(a)) +#define clrbuf(buf) do { memset(&(buf), 0, sizeof(buf)); } while (0) +#define freebuf(buf) do { free((buf).data); clrbuf(buf); } while (0) +#define BUF_INIT { 0, NULL } +#define BUF_IS_EMPTY(buf) ((buf)->data == NULL && (buf)->len == 0) typedef struct { - uint8_t * data; size_t len; + uint8_t * data; } buffer_t; +int bufcmp(const buffer_t * a, + const buffer_t * b); + /* * Returns the number of characters a uint would * need when represented as a string */ int n_digits(unsigned i); -/* gets the application name */ -char * path_strip(char * src); +char * path_strip(const char * src); + +char * trim_whitespace(char * str); + +bool is_ouroboros_member_uid(uid_t uid); + +bool is_ouroboros_member(void); + +/* functions for copying and destroying arguments list */ +size_t argvlen(const char ** argv); + +char ** argvdup(char ** argv); + +void argvfree(char ** argv); /* destroy a ** */ #define freepp(type, ptr, len) \ do { \ - if (len == 0) \ - break; \ - while (len > 0) \ - free(((type **) ptr)[--len]); \ + while (len-- > 0) \ + free(((type **) ptr)[len]); \ + free(ptr); \ + } while (0) + +/* destroys an array of buffers */ +#define freebufs(ptr, len) \ + do { \ + while ((len)-- > 0) \ + freebuf((ptr)[len]); \ free(ptr); \ - } while (0); + } while (0) -#endif /* OUROBOROS_UTILS_H */ +#endif /* OUROBOROS_LIB_UTILS_H */ diff --git a/include/ouroboros/version.h.in b/include/ouroboros/version.h.in index 4306b239..c006a095 100644 --- a/include/ouroboros/version.h.in +++ b/include/ouroboros/version.h.in @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Ouroboros version * diff --git a/include/test/certs.h b/include/test/certs.h new file mode 100644 index 00000000..1b847406 --- /dev/null +++ b/include/test/certs.h @@ -0,0 +1,125 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * Test certificates - ECDSA/P-256 signed certificates + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef TEST_CERTS_H +#define TEST_CERTS_H + +/* +* Certificates created following the guide +* Building an openssl certificate authority +* on +* https://community.f5.com/kb/technicalarticles/ +*/ + +/* Root certificate for CA ca.unittest.o7s */ +static const char * root_ca_crt_ec = \ +"-----BEGIN CERTIFICATE-----\n" +"MIICXTCCAgOgAwIBAgIURlENlCOy1OsA/AXFscPUQ2li8OYwCgYIKoZIzj0EAwIw\n" +"fDELMAkGA1UEBhMCQkUxDDAKBgNVBAgMA09WTDEOMAwGA1UEBwwFR2hlbnQxDDAK\n" +"BgNVBAoMA283czEVMBMGA1UECwwMdW5pdHRlc3QubzdzMRgwFgYDVQQDDA9jYS51\n" +"bml0dGVzdC5vN3MxEDAOBgkqhkiG9w0BCQEWASAwHhcNMjUwODAzMTg1MzE1WhcN\n" +"NDUwNzI5MTg1MzE1WjB8MQswCQYDVQQGEwJCRTEMMAoGA1UECAwDT1ZMMQ4wDAYD\n" +"VQQHDAVHaGVudDEMMAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3Mx\n" +"GDAWBgNVBAMMD2NhLnVuaXR0ZXN0Lm83czEQMA4GCSqGSIb3DQEJARYBIDBZMBMG\n" +"ByqGSM49AgEGCCqGSM49AwEHA0IABEPMseCScbd/d5TlHmyYVszn/YGVeNdUCnFR\n" +"naOr95WlTNo3MyKKBuoiEFwHhjPASgXr/VDVjJLSyM3JUPebAcGjYzBhMB0GA1Ud\n" +"DgQWBBQkxjMILHH6lZ+rnCMnD/63GO3y1zAfBgNVHSMEGDAWgBQkxjMILHH6lZ+r\n" +"nCMnD/63GO3y1zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAKBggq\n" +"hkjOPQQDAgNIADBFAiEA1jVJWW4idkCgAYv0m2LT9C33Dq42aLyRkJ+9YdzDqLwC\n" +"IHT6MS4I0k52YP/hxoqWVBbpOW79PKYMRLyXTk1r7+Fa\n" +"-----END CERTIFICATE-----\n"; + +/* Certificate for intermediary im.unittest.o7s used for signing */ +static const char * im_ca_crt_ec = \ +"-----BEGIN CERTIFICATE-----\n" +"MIICbTCCAhOgAwIBAgICEAMwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCQkUxDDAK\n" +"BgNVBAgMA09WTDEOMAwGA1UEBwwFR2hlbnQxDDAKBgNVBAoMA283czEVMBMGA1UE\n" +"CwwMdW5pdHRlc3QubzdzMRgwFgYDVQQDDA9jYS51bml0dGVzdC5vN3MxEDAOBgkq\n" +"hkiG9w0BCQEWASAwHhcNMjUwODAzMTkwMjU3WhcNNDUwNzI5MTkwMjU3WjBaMQsw\n" +"CQYDVQQGEwJCRTEMMAoGA1UECAwDT1ZMMQwwCgYDVQQKDANvN3MxFTATBgNVBAsM\n" +"DHVuaXR0ZXN0Lm83czEYMBYGA1UEAwwPaW0udW5pdHRlc3QubzdzMFkwEwYHKoZI\n" +"zj0CAQYIKoZIzj0DAQcDQgAEdlra08XItIPtVl5veaq4UF6LIcBXj2mZFqKNEXFh\n" +"l9uAz6UAbIc+FUPNfom6dwKbg/AjQ82a100eh6K/jCY7eKOBpjCBozAdBgNVHQ4E\n" +"FgQUy8Go8BIO6i0lJ+mgBr9lvh2L0eswHwYDVR0jBBgwFoAUJMYzCCxx+pWfq5wj\n" +"Jw/+txjt8tcwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEQYD\n" +"VR0fBAowCDAGoASgAoYAMCoGCCsGAQUFBwEBBB4wHDAMBggrBgEFBQcwAoYAMAwG\n" +"CCsGAQUFBzABhgAwCgYIKoZIzj0EAwIDSAAwRQIhAN3ZYhqu6mVLGidmONsbANk5\n" +"rzT6aHJcmvj19OxMusaXAiBKy0gBFCri/GLizi4wZo09wf31yZMqfr8IrApvPaLw\n" +"qA==\n" +"-----END CERTIFICATE-----\n"; + +/* Server test-1.unittest.o7s private-public key pair */ +static const char * server_pkp_ec = \ +"-----BEGIN EC PRIVATE KEY-----\n" +"MHcCAQEEIA4/bcmquVvGrY4+TtfnFSy1SpXs896r5xJjGuD6NmGRoAoGCCqGSM49\n" +"AwEHoUQDQgAE4BSOhv36q4bCMLSkJaCvzwZ3pPy2M0YzRKFKeV48tG5eD+MBaTrT\n" +"eoHUcRfpz0EO/inq3FVDzEoAQ2NWpnz0kA==\n" +"-----END EC PRIVATE KEY-----\n"; + +/* Public key for the Private key */ +static __attribute__((unused)) const char * server_pk_ec = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4BSOhv36q4bCMLSkJaCvzwZ3pPy2\n" +"M0YzRKFKeV48tG5eD+MBaTrTeoHUcRfpz0EO/inq3FVDzEoAQ2NWpnz0kA==\n" +"-----END PUBLIC KEY-----\n"; + +/* Valid signed server certificate for test-1.unittest.o7s */ +#define SSC_TEXT_SIZE 2295 /* size of cleartext certificate */ +static const char * signed_server_crt_ec = \ +"-----BEGIN CERTIFICATE-----\n" +"MIIDiTCCAy+gAwIBAgICEAUwCgYIKoZIzj0EAwIwWjELMAkGA1UEBhMCQkUxDDAK\n" +"BgNVBAgMA09WTDEMMAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3Mx\n" +"GDAWBgNVBAMMD2ltLnVuaXR0ZXN0Lm83czAeFw0yNTA4MDgxODQ4NTNaFw00NTA4\n" +"MDMxODQ4NTNaMG4xCzAJBgNVBAYTAkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcM\n" +"BUdoZW50MQwwCgYDVQQKDANvN3MxFTATBgNVBAsMDHVuaXR0ZXN0Lm83czEcMBoG\n" +"A1UEAwwTdGVzdC0xLnVuaXR0ZXN0Lm83czBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" +"A0IABOAUjob9+quGwjC0pCWgr88Gd6T8tjNGM0ShSnlePLRuXg/jAWk603qB1HEX\n" +"6c9BDv4p6txVQ8xKAENjVqZ89JCjggHPMIIByzAJBgNVHRMEAjAAMBEGCWCGSAGG\n" +"+EIBAQQEAwIGQDA4BglghkgBhvhCAQ0EKxYpbzdzIHVuaXR0ZXN0IEdlbmVyYXRl\n" +"ZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFI+htsK0xxy6e1CqCyxn7mqi\n" +"wRrpMIGoBgNVHSMEgaAwgZ2AFMvBqPASDuotJSfpoAa/Zb4di9HroYGApH4wfDEL\n" +"MAkGA1UEBhMCQkUxDDAKBgNVBAgMA09WTDEOMAwGA1UEBwwFR2hlbnQxDDAKBgNV\n" +"BAoMA283czEVMBMGA1UECwwMdW5pdHRlc3QubzdzMRgwFgYDVQQDDA9jYS51bml0\n" +"dGVzdC5vN3MxEDAOBgkqhkiG9w0BCQEWASCCAhADMA4GA1UdDwEB/wQEAwIFoDAT\n" +"BgNVHSUEDDAKBggrBgEFBQcDATAoBgNVHR8EITAfMB2gG6AZhhdodHRwczovL291\n" +"cm9ib3Jvcy5yb2NrczBYBggrBgEFBQcBAQRMMEowIwYIKwYBBQUHMAKGF2h0dHBz\n" +"Oi8vb3Vyb2Jvcm9zLnJvY2tzMCMGCCsGAQUFBzABhhdodHRwczovL291cm9ib3Jv\n" +"cy5yb2NrczAKBggqhkjOPQQDAgNIADBFAiBZuw/Yb2pq925H7pEiOXr4fMo0wknz\n" +"ktkxoHAFbjQEPQIhAMInHI7lvRmS0IMw1wBF/WlUZWKvhyU/TeMIZfk/JGCS\n" +"-----END CERTIFICATE-----\n"; + +/* Self-signed by server test-1.unittest.o7s using its key */ +static __attribute__((unused)) const char * server_crt_ec = \ +"-----BEGIN CERTIFICATE-----\n" +"MIIBfjCCASWgAwIBAgIUB5VYxp7i+sgYjvLiwfpf0W5NfqQwCgYIKoZIzj0EAwIw\n" +"HjEcMBoGA1UEAwwTdGVzdC0xLnVuaXR0ZXN0Lm83czAeFw0yNTA4MDMxOTI4MzVa\n" +"Fw00NTA3MjkxOTI4MzVaMB4xHDAaBgNVBAMME3Rlc3QtMS51bml0dGVzdC5vN3Mw\n" +"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATgFI6G/fqrhsIwtKQloK/PBnek/LYz\n" +"RjNEoUp5Xjy0bl4P4wFpOtN6gdRxF+nPQQ7+KercVUPMSgBDY1amfPSQo0EwPzAe\n" +"BgNVHREEFzAVghN0ZXN0LTEudW5pdHRlc3QubzdzMB0GA1UdDgQWBBSPobbCtMcc\n" +"untQqgssZ+5qosEa6TAKBggqhkjOPQQDAgNHADBEAiAoFC/rqgrRXmMUx4y5cPbv\n" +"jOKpoL3FpehRgGkPatmL/QIgMRHc2TSGo6q1SG22Xt1dHAIBsaN2AlSfhjKULMH5\n" +"gRo=\n" +"-----END CERTIFICATE-----\n"; + +#endif /* TEST_CERTS_H */ + diff --git a/include/test/certs_pqc.h b/include/test/certs_pqc.h new file mode 100644 index 00000000..b533ca60 --- /dev/null +++ b/include/test/certs_pqc.h @@ -0,0 +1,656 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * Test certificates - ML-DSA-65 (post-quantum) signed certificates + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef TEST_CERTS_PQC_H +#define TEST_CERTS_PQC_H + +/* + * ML-DSA-65 certificates for testing post-quantum cryptography + * Root CA: ca.unittest.o7s + * Intermediate CA: im.unittest.o7s (pathlen:0) + * Server: test-1.unittest.o7s + */ + +/* PEM certificate strings will go here */ +static const char * root_ca_crt_ml = \ +"-----BEGIN CERTIFICATE-----\n" +"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\n" +"-----END CERTIFICATE-----\n"; + +static const char * im_ca_crt_ml = \ +"-----BEGIN CERTIFICATE-----\n" +"MIIVyDCCCMWgAwIBAgICEAAwCwYJYIZIAWUDBAMSMFMxCzAJBgNVBAYTAkJFMQww\n" +"CgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQwwCgYDVQQKDANvN3MxGDAWBgNV\n" +"BAMMD2NhLnVuaXR0ZXN0Lm83czAeFw0yNjAxMDUxOTE1MjJaFw0zNjAxMDMxOTE1\n" +"MjJaMBoxGDAWBgNVBAMMD2ltLnVuaXR0ZXN0Lm83czCCB7IwCwYJYIZIAWUDBAMS\n" +"A4IHoQA5Wkc2Mz19rGlaczLiVz+WqRHexHpdzgKP/wXNiduzFZtYxbXVPJHPybkX\n" +"Jx8p18vxsTHBsUz1ST+nOqLKH0RAqqEQWBLmf2bg0To7aLkN53lg40xcZ8XszXBg\n" +"H0cjl/agLFSvPoSpLv5R25FeR5mK5pkpaCzY29Wg2xppeAFeMPL1YBUtsxiDoLWG\n" +"xnquhrDRWrFCHDcpcG+qFCrwSk30EJgIEFz8zAucZk++MWXINmm0rKzqAZHkh9zo\n" +"IXHTulI6zFGxFDP19eRoke4AzmC6xJyw9W+WIU84TyU9o4bSfQtJjLFn7qk410a2\n" +"/zm3mXS9fQiqqZm8M6mAk6UTFVHHr6/SzzwFutn652qz8xhSDkOlsd8jz9XixEpk\n" +"wXQiZZMaai9MTW9m5Hzi+8mFMcMmGwsIgTWo/G0os8d8hxPWcRXO4lXfuHa83dUP\n" +"KWHEcroEBjdN67R3qepCONhvq8VSHbw1/tkm8VjzTz2VCQUjFSkn/rxqJAi1cIoh\n" +"ZEBuDuJ2Ilx3DlFAQTrMl6L6HwIqetYYyYoMUSL09MtAA1EZTIJm6CHM+gxnef20\n" +"mLIvWDaXicm01FpBaxJwGqWD0fS+2Ii4+XwnxYh3kKLD1x1O4guIqPDPG3NVBdu5\n" +"pKxYLAgcE9OJc3I7SfgimQCweGuEUGwHSqMjcYKYWiAodlo2z4+GtAN08Np+Av0/\n" +"fVTOHW6aFMnvxfcpsZv0fBcwgOm+vvuxmKdIOTjJiQnLPqWWAykt3LM5AaoBT0v5\n" +"Pd3OU7z4p/XXwkYgQXFV58nOttFHHE0ANKiLUF7iBmu2Vz3+n8ewTW/nYABUEZlC\n" +"W+VfnhHwYhgmtg2krCBW9KNI1Vvfw9WutJxT/8+lAN3P/ZqyvF6vS9rECfn1zFIr\n" +"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\n" +"AAAAAAAABQoQFyIo\n" +"-----END CERTIFICATE-----\n"; + +static const char * server_pkp_ml = \ +"-----BEGIN PRIVATE KEY-----\n" +"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\n" +"DngTH/g89SEnGxqKXe7RxVof\n" +"-----END PRIVATE KEY-----\n"; + +static __attribute__((unused)) const char * server_pk_ml = \ +"-----BEGIN PUBLIC KEY-----\n" +"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\n" +"k1M8ksQo\n" +"-----END PUBLIC KEY-----\n"; + +static const char * signed_server_crt_ml = \ +"-----BEGIN CERTIFICATE-----\n" +"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\n" +"AAAAAAAAAAAAAAAABgkOExgc\n" +"-----END CERTIFICATE-----\n"; + +static __attribute__((unused)) const char * server_crt_ml = \ +"-----BEGIN CERTIFICATE-----\n" +"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\n" +"-----END CERTIFICATE-----\n"; + +#endif /* TEST_CERTS_PQC_H */ + diff --git a/include/test/test.h b/include/test/test.h new file mode 100644 index 00000000..306e737a --- /dev/null +++ b/include/test/test.h @@ -0,0 +1,109 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Test macros + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_TEST_H +#define OUROBOROS_LIB_TEST_H + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <sys/resource.h> + +#define TEST_RC_SUCCESS 0 +#define TEST_RC_SKIP 1 +#define TEST_RC_FAIL -1 + +#define TEST_START(...) \ + do { \ + printf("%s", __func__); \ + if (sizeof(#__VA_ARGS__) > 1) \ + printf(" " __VA_ARGS__); \ + printf(" started.\n"); \ + fflush(stdout); \ + } while (0) + +#define TEST_SUCCESS(...) \ + do { \ + printf("\x1b[32m%s", __func__); \ + if (sizeof(#__VA_ARGS__) > 1) \ + printf(" " __VA_ARGS__); \ + printf(" succeeded.\x1b[0m\n"); \ + fflush(stdout); \ + } while (0) + +#define TEST_SKIPPED() \ + do { \ + printf("\x1b[33m%s skipped.\x1b[0m\n", __func__); \ + fflush(stdout); \ + } while (0) + +#define TEST_FAIL(...) \ + do { \ + printf("\x1b[31m%s", __func__); \ + if (sizeof(#__VA_ARGS__) > 1) \ + printf(" " __VA_ARGS__); \ + printf(" failed.\x1b[0m\n"); \ + fflush(stdout); \ + } while (0) + +#define TEST_END(result) \ + do { if (result == 0) TEST_SUCCESS(); else TEST_FAIL(); } while (0) + +static int __attribute__((unused)) test_assert_fail(int(* testfunc)(void)) +{ + pid_t pid; + int wstatus; + + pid = fork(); + if (pid == -1) { + printf("Failed to fork: %s.\n", strerror(errno)); + return TEST_RC_FAIL; + } + + if (pid == 0) { +#ifdef DISABLE_TESTS_CORE_DUMPS + struct rlimit rl = { .rlim_cur = 0, .rlim_max = 0 }; + setrlimit(RLIMIT_CORE, &rl); +#endif + return testfunc(); /* should abort */ + } + + waitpid(pid, &wstatus, 0); +#ifdef CONFIG_OUROBOROS_DEBUG + if (WIFSIGNALED(wstatus) && (wstatus == 134 || wstatus == 6)) + return TEST_RC_SUCCESS; + + printf("Process did not abort, status: %d.\n", wstatus); +#else + if (WIFEXITED(wstatus) && wstatus == 0) + return TEST_RC_SUCCESS; + + printf("Process did not exit, status: %d.\n", wstatus); +#endif + + return TEST_RC_FAIL; +} + +#endif /* OUROBOROS_LIB_TEST_H */ |
