From 5e5175ef1f0e0b6df12aa698e2add3ce5f089077 Mon Sep 17 00:00:00 2001 From: midipix Date: Jun 08 2020 01:00:09 +0000 Subject: internals: added the daemon loop and related interfaces. --- diff --git a/include/toksvc/toksvc.h b/include/toksvc/toksvc.h index 982446a..0725ed7 100644 --- a/include/toksvc/toksvc.h +++ b/include/toksvc/toksvc.h @@ -39,6 +39,9 @@ extern "C" { #define TOKS_DRIVER_VERSION 0x0010 #define TOKS_DRIVER_DRY_RUN 0x0020 +#define TOKS_DRIVER_DAEMON_ALWAYS 0x0040 +#define TOKS_DRIVER_DAEMON_NEVER 0x0080 + #define TOKS_DRIVER_ANNOTATE_ALWAYS 0x1000 #define TOKS_DRIVER_ANNOTATE_NEVER 0x2000 #define TOKS_DRIVER_ANNOTATE_FULL 0x4000 diff --git a/project/common.mk b/project/common.mk index e41c495..adb5eb2 100644 --- a/project/common.mk +++ b/project/common.mk @@ -1,6 +1,10 @@ API_SRCS = \ INTERNAL_SRCS = \ + src/daemon/toks_daemon_connect.c \ + src/daemon/toks_daemon_init.c \ + src/daemon/toks_daemon_loop.c \ + src/daemon/toks_daemon_signal.c \ src/internal/nolibc/toksvc_compiler.c \ src/internal/toksvc_dprintf_impl.c \ src/internal/toksvc_memfn_impl.c \ diff --git a/project/headers.mk b/project/headers.mk index 34ab9b7..9ea381f 100644 --- a/project/headers.mk +++ b/project/headers.mk @@ -11,6 +11,7 @@ INTERNAL_HEADERS = \ $(SOURCE_DIR)/src/internal/nolibc/stdlib.h \ $(SOURCE_DIR)/src/internal/nolibc/string.h \ $(SOURCE_DIR)/src/internal/nolibc/unistd.h \ + $(SOURCE_DIR)/src/internal/toksvc_daemon_impl.h \ $(SOURCE_DIR)/src/internal/toksvc_dprintf_impl.h \ $(SOURCE_DIR)/src/internal/toksvc_init_impl.h \ $(SOURCE_DIR)/src/internal/toksvc_memfn_impl.h \ diff --git a/project/tree.mk b/project/tree.mk index e593d53..2d04bf6 100644 --- a/project/tree.mk +++ b/project/tree.mk @@ -1,4 +1,5 @@ TREE_DIRS = bin src lib \ + src/daemon \ src/internal \ src/internal/nolibc \ diff --git a/src/daemon/toks_daemon_connect.c b/src/daemon/toks_daemon_connect.c new file mode 100644 index 0000000..66595db --- /dev/null +++ b/src/daemon/toks_daemon_connect.c @@ -0,0 +1,27 @@ +/*********************************************************/ +/* toksvc: a framework-native token broker service */ +/* Copyright (C) 2020 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */ +/*********************************************************/ + +#include +#include + +#include +#include "toksvc_daemon_impl.h" +#include "toksvc_driver_impl.h" + +int32_t __stdcall toks_daemon_connect(nt_tty_port_msg * msg) +{ + void * hport = 0; + + msg->ttyinfo.exarg = 0; + + ntapi->zw_accept_connect_port( + &hport, + msg->header.client_id.process_id, + &msg->header, + NT_LPC_ACCEPT_CONNECTION,0,0); + + return ntapi->zw_complete_connect_port(hport); +} diff --git a/src/daemon/toks_daemon_init.c b/src/daemon/toks_daemon_init.c new file mode 100644 index 0000000..d11d347 --- /dev/null +++ b/src/daemon/toks_daemon_init.c @@ -0,0 +1,128 @@ +/*********************************************************/ +/* toksvc: a framework-native token broker service */ +/* Copyright (C) 2020 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */ +/*********************************************************/ + +#include +#include +#include + +#include +#include "toksvc_daemon_impl.h" +#include "toksvc_driver_impl.h" + +static const nt_guid toks_daemon_guid = TOKS_PORT_GUID_DAEMON; + +static int32_t toks_daemon_init_impl(struct toks_daemon_ctx * dctx, void * htty) +{ + int32_t status; + nt_daemon_params dparams; + wchar16_t * port_name; + nt_port_name_keys * port_name_keys; + + /* daemon attributes */ + dctx->daemon_attr.type = NT_PORT_TYPE_DAEMON; + dctx->daemon_attr.subtype = NT_PORT_SUBTYPE_DEFAULT; + + /* port guid */ + ntapi->tt_guid_copy( + &dctx->daemon_attr.guid, + &toks_daemon_guid); + + /* port keys */ + if ((status = ntapi->tt_port_generate_keys(&dctx->daemon_attr.keys))) + return status; + + /* port name */ + ntapi->tt_port_name_from_attr( + &dctx->daemon_name, + &dctx->daemon_attr); + + /* dparams */ + ntapi->tt_aligned_block_memset( + &dparams,0,sizeof(dparams)); + + port_name = (wchar16_t *)&dctx->daemon_name; + port_name_keys = (nt_port_name_keys *)&dctx->daemon_name.port_name_keys; + + dparams.port_keys = &dctx->daemon_keys; + dparams.port_name = port_name; + dparams.port_name_keys = port_name_keys; + + dparams.port_msg_size = sizeof(nt_tty_port_msg); + dparams.flags = NT_DSR_INIT_DEFAULT; + + dparams.daemon_once_routine = 0; + dparams.daemon_loop_routine = toks_daemon_loop; + dparams.daemon_loop_context = dctx; + + dparams.pport_daemon = &dctx->hport_daemon; + dparams.pport_internal_client = &dctx->hport_internal_client; + + dparams.pevent_daemon_ready = &dctx->hevent_daemon_ready; + dparams.pevent_internal_client_ready = &dctx->hevent_internal_client_ready; + + dparams.stack_size_commit = 8192; + dparams.stack_size_reserve = 8192; + + if ((status = ntapi->dsr_init(&dparams))) + return status; + + return ntapi->tty_request_peer( + htty, + TOKS_DAEMON_TTYSIGNAL, + 0,&(nt_guid)TTY_PTS_GUID, + &dctx->daemon_attr); +} + +static int32_t toks_daemon_once = 0; + +int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, uint64_t drvflags) +{ + int32_t status; + nt_timeout timeout; + nt_runtime_data * rtdata; + + /* rtdata */ + if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) + return status; + + /* needed? */ + if (drvflags & TOKS_DRIVER_DAEMON_NEVER) + return 0; + + if (!(drvflags & TOKS_DRIVER_DAEMON_ALWAYS)) + if (ntapi->tt_guid_compare(&rtdata->srv_guid,&toks_daemon_guid)) + return 0; + + /* once */ + switch (at_locked_cas_32(&toks_daemon_once,0,1)) { + case 0: + if ((status = toks_daemon_init_impl(dctx,rtdata->hsession))) { + at_locked_add_32(&toks_daemon_once,2); + return status; + } + + at_locked_inc_32(&toks_daemon_once); + return 0; + + case 1: + timeout.quad = -10; + + for (; (at_locked_cas_32(&toks_daemon_once,0,1) == 1); ) + ntapi->zw_delay_execution( + NT_SYNC_ALERTABLE, + &timeout); + + return (toks_daemon_once == 2) + ? 0 : -1; + + case 2: + return 0; + + case 3: + default: + return -1; + } +} diff --git a/src/daemon/toks_daemon_loop.c b/src/daemon/toks_daemon_loop.c new file mode 100644 index 0000000..fb151ec --- /dev/null +++ b/src/daemon/toks_daemon_loop.c @@ -0,0 +1,125 @@ +/*********************************************************/ +/* toksvc: a framework-native token broker service */ +/* Copyright (C) 2020 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */ +/*********************************************************/ + +#include +#include + +#include +#include "toksvc_daemon_impl.h" +#include "toksvc_driver_impl.h" + +#define TOKS_VTBL_ELEMENTS TOKS_DAEMON_OPCODE_CAP - TOKS_DAEMON_OPCODE_BASE + +static toks_daemon_routine * toks_daemon_vtbl[TOKS_VTBL_ELEMENTS] = { + toks_daemon_connect, + 0, + toks_daemon_signal, + 0, + 0, + 0 +}; + +int32_t __stdcall toks_daemon_loop(void * ctx) +{ + struct toks_daemon_ctx * dctx; + nt_rtdata * rtdata; + + nt_tty_port_msg inbuf; + nt_tty_port_msg outbuf; + + nt_tty_port_msg * request; + nt_tty_port_msg * reply; + + intptr_t port_id; + int32_t opcode; + + if (ntapi->tt_get_runtime_data(&rtdata,0)) + return NT_STATUS_INTERNAL_ERROR; + + dctx = (struct toks_daemon_ctx *)ctx; + + /* init */ + request = &inbuf; + ntapi->tt_aligned_block_memset( + request,0,sizeof(*request)); + + /* get first message */ + ntapi->zw_reply_wait_receive_port( + dctx->hport_daemon, + &port_id, + 0,(nt_port_message *)request); + + /* message loop */ + do { + switch (request->header.msg_type) { + case NT_LPC_REQUEST: + case NT_LPC_DATAGRAM: + opcode = request->ttyinfo.opcode; + break; + + case NT_LPC_CONNECTION_REQUEST: + opcode = TOKS_DAEMON_CONNECT; + break; + + default: + opcode = -1; + break; + } + + /* dispatch */ + reply = &outbuf; + + ntapi->tt_aligned_block_memcpy( + (uintptr_t *)reply, + (uintptr_t *)request, + sizeof(*reply)); + + reply->header.msg_type = NT_LPC_REPLY; + + if ((opcode >= TOKS_DAEMON_OPCODE_BASE) && (opcode < TOKS_DAEMON_OPCODE_CAP)) { + reply->ttyinfo.exarg = (void *)request->header.client_id.process_id; + opcode -= TOKS_DAEMON_OPCODE_BASE; + + if (toks_daemon_vtbl[opcode]) + reply->ttyinfo.status = toks_daemon_vtbl[opcode](reply); + else + reply->ttyinfo.status = NT_STATUS_NOT_IMPLEMENTED; + } else { + reply->ttyinfo.exarg = NT_INVALID_HANDLE_VALUE; + reply->ttyinfo.status = NT_STATUS_LPC_INVALID_CONNECTION_USAGE; + } + + ntapi->tt_aligned_block_memset( + request,0,sizeof(*request)); + + reply = reply->ttyinfo.exarg + ? &outbuf : 0; + + if (!reply) + ntapi->zw_reply_wait_receive_port( + dctx->hport_daemon, + &port_id, + 0,&request->header); + else if (reply->header.client_id.process_id == rtdata->cid_self.process_id) + ntapi->zw_reply_wait_receive_port( + dctx->hport_daemon, + &port_id, + &reply->header, + &request->header); + else { + ntapi->zw_reply_port( + dctx->hport_daemon, + &reply->header); + + ntapi->zw_reply_wait_receive_port( + dctx->hport_daemon, + &port_id, + 0,&request->header); + } + } while (request->header.msg_id); + + return NT_STATUS_INTERNAL_ERROR; +} diff --git a/src/daemon/toks_daemon_signal.c b/src/daemon/toks_daemon_signal.c new file mode 100644 index 0000000..1c7454a --- /dev/null +++ b/src/daemon/toks_daemon_signal.c @@ -0,0 +1,27 @@ +/*********************************************************/ +/* toksvc: a framework-native token broker service */ +/* Copyright (C) 2020 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */ +/*********************************************************/ + +#include +#include +#include + +#include "toksvc_daemon_impl.h" +#include "toksvc_driver_impl.h" + +int32_t __stdcall toks_daemon_signal(nt_tty_port_msg * msg) +{ + /* [not a] ctty signal? */ + if (msg->ctlinfo.ctxarg[0]) + return NT_STATUS_SUCCESS; + + /* ctty sigint */ + if (msg->ctlinfo.ctlcode == TTY_TCSBRK) + ntapi->zw_terminate_process( + NT_CURRENT_PROCESS_HANDLE, + NT_STATUS_WAIT_1); + + return NT_STATUS_NOT_SUPPORTED; +} diff --git a/src/internal/toksvc_daemon_impl.h b/src/internal/toksvc_daemon_impl.h new file mode 100644 index 0000000..d5ed546 --- /dev/null +++ b/src/internal/toksvc_daemon_impl.h @@ -0,0 +1,37 @@ +#ifndef TOKSVC_DAEMON_IMPL_H +#define TOKSVC_DAEMON_IMPL_H + +#include +#include + +enum toks_daemon_opcodes { + TOKS_DAEMON_OPCODE_BASE = 0x20000, + TOKS_DAEMON_CONNECT = TOKS_DAEMON_OPCODE_BASE, + TOKS_DAEMON_DISCONNECT, + TOKS_DAEMON_TTYSIGNAL, + TOKS_DAEMON_IPCSIGNAL, + TOKS_DAEMON_SIGCHLD, + TOKS_DAEMON_THREADEXIT, + TOKS_DAEMON_OPCODE_CAP +}; + +typedef int32_t __stdcall toks_daemon_routine(nt_tty_port_msg *); + +struct toks_daemon_ctx { + nt_port_keys daemon_keys; + nt_port_attr daemon_attr; + nt_port_name daemon_name; + + void * hport_daemon; + void * hevent_daemon_ready; + + void * hport_internal_client; + void * hevent_internal_client_ready; +}; + +int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx *, uint64_t); +int32_t __stdcall toks_daemon_loop(void *); +int32_t __stdcall toks_daemon_connect(nt_tty_port_msg *); +int32_t __stdcall toks_daemon_signal(nt_tty_port_msg *); + +#endif