feat: remove nonce/bootstrap from remote process IPC, use PID-only naming

Shared memory names simplified to Local\RCX_SHM_<pid>, no bootstrap
handshake needed. Payload uses CreateTimerQueueTimer (10ms poll) instead
of a dedicated server thread.
This commit is contained in:
IChooseYou
2026-02-22 11:36:24 -07:00
parent 25aaace382
commit f651edd740
6 changed files with 124 additions and 292 deletions

View File

@@ -4,7 +4,7 @@
*
* Usage:
* test_rpc_client (auto-spawn host)
* test_rpc_client <pid> <nonce> [testbuf_hex testlen]
* test_rpc_client <pid> [testbuf_hex testlen]
*/
#include "../rcx_rpc_protocol.h"
@@ -45,12 +45,12 @@ struct TestIpcClient {
void* view = nullptr;
bool ok = false;
bool connect(uint32_t pid, const char* nonce, int timeoutMs = 5000)
bool connect(uint32_t pid, int timeoutMs = 5000)
{
char shmName[128], reqName[128], rspName[128];
rcx_rpc_shm_name(shmName, sizeof(shmName), pid, nonce);
rcx_rpc_req_name(reqName, sizeof(reqName), pid, nonce);
rcx_rpc_rsp_name(rspName, sizeof(rspName), pid, nonce);
rcx_rpc_shm_name(shmName, sizeof(shmName), pid);
rcx_rpc_req_name(reqName, sizeof(reqName), pid);
rcx_rpc_rsp_name(rspName, sizeof(rspName), pid);
#ifdef _WIN32
ULONGLONG deadline = GetTickCount64() + (ULONGLONG)timeoutMs;
@@ -268,7 +268,7 @@ static pid_t g_hostPid = 0;
#endif
static FILE* g_hostPipe = nullptr;
static bool spawn_host(uint32_t* outPid, char* outNonce,
static bool spawn_host(uint32_t* outPid,
uint64_t* outTestBuf, uint32_t* outTestLen)
{
/* resolve path to test_rpc_host next to ourselves */
@@ -302,11 +302,11 @@ static bool spawn_host(uint32_t* outPid, char* outNonce,
return false;
}
/* parse: READY pid=X nonce=Y testbuf=0xZ testlen=N */
/* parse: READY pid=X testbuf=0xZ testlen=N */
unsigned long long tbuf = 0;
unsigned tlen = 0;
if (sscanf(line, "READY pid=%u nonce=%63s testbuf=0x%llx testlen=%u",
outPid, outNonce, &tbuf, &tlen) < 2) {
if (sscanf(line, "READY pid=%u testbuf=0x%llx testlen=%u",
outPid, &tbuf, &tlen) < 1) {
fprintf(stderr, "ERROR: cannot parse host output: %s\n", line);
return false;
}
@@ -341,30 +341,28 @@ static void print_fail(const char* name) { printf(" [FAIL] %s\n", name); exit(1
int main(int argc, char** argv)
{
uint32_t pid = 0;
char nonce[64] = {};
uint64_t testBuf = 0;
uint32_t testLen = 0;
bool autoMode = false;
if (argc >= 3) {
if (argc >= 2) {
pid = (uint32_t)atoi(argv[1]);
strncpy(nonce, argv[2], 63);
if (argc >= 5) {
testBuf = (uint64_t)strtoull(argv[3], nullptr, 0);
testLen = (uint32_t)atoi(argv[4]);
if (argc >= 4) {
testBuf = (uint64_t)strtoull(argv[2], nullptr, 0);
testLen = (uint32_t)atoi(argv[3]);
}
} else {
autoMode = true;
printf("Auto-spawning test_rpc_host...\n");
if (!spawn_host(&pid, nonce, &testBuf, &testLen)) return 1;
if (!spawn_host(&pid, &testBuf, &testLen)) return 1;
}
printf("Connecting to PID=%u nonce=%s testbuf=0x%llx testlen=%u\n\n",
pid, nonce, (unsigned long long)testBuf, testLen);
printf("Connecting to PID=%u testbuf=0x%llx testlen=%u\n\n",
pid, (unsigned long long)testBuf, testLen);
/* ── connect ── */
TestIpcClient ipc;
if (!ipc.connect(pid, nonce)) {
if (!ipc.connect(pid)) {
fprintf(stderr, "ERROR: IPC connect failed\n");
if (autoMode) cleanup_host();
return 1;

View File

@@ -1,7 +1,7 @@
/*
* test_rpc_host -- loads rcx_payload in-process, acts as the "target".
*
* Usage: test_rpc_host [nonce]
* Usage: test_rpc_host
*
* Prints a READY line (machine-parseable), then waits for the payload
* to shut down (RPC_CMD_SHUTDOWN from the client).
@@ -68,50 +68,11 @@ static int payload_path(char* out, int outLen)
return 0;
}
/* Create bootstrap shared memory with the nonce */
static int create_bootstrap(uint32_t pid, const char* nonce)
{
char bootName[128];
rcx_rpc_boot_name(bootName, sizeof(bootName), pid);
#ifdef _WIN32
HANDLE h = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, 0, RCX_RPC_BOOT_SIZE, bootName);
if (!h) return -1;
void* v = MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, RCX_RPC_BOOT_SIZE);
if (!v) { CloseHandle(h); return -1; }
RcxRpcBootHeader* boot = (RcxRpcBootHeader*)v;
memset(boot, 0, RCX_RPC_BOOT_SIZE);
boot->nonceLength = (uint32_t)strlen(nonce);
strncpy(boot->nonce, nonce, 59);
UnmapViewOfFile(v);
/* keep h open for payload to read */
return 0;
#else
int fd = shm_open(bootName, O_CREAT | O_RDWR, 0600);
if (fd < 0) return -1;
if (ftruncate(fd, RCX_RPC_BOOT_SIZE) != 0) { close(fd); return -1; }
void* v = mmap(nullptr, RCX_RPC_BOOT_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
close(fd);
if (v == MAP_FAILED) return -1;
RcxRpcBootHeader* boot = (RcxRpcBootHeader*)v;
memset(boot, 0, RCX_RPC_BOOT_SIZE);
boot->nonceLength = (uint32_t)strlen(nonce);
strncpy(boot->nonce, nonce, 59);
munmap(v, RCX_RPC_BOOT_SIZE);
return 0;
#endif
}
/* Open the main shared memory (read-only, just to monitor payloadReady) */
static void* open_main_shm(uint32_t pid, const char* nonce)
static void* open_main_shm(uint32_t pid)
{
char shmName[128];
rcx_rpc_shm_name(shmName, sizeof(shmName), pid, nonce);
rcx_rpc_shm_name(shmName, sizeof(shmName), pid);
#ifdef _WIN32
HANDLE h = nullptr;
@@ -142,21 +103,14 @@ static uint8_t g_testBuf[65536];
/* ── main ─────────────────────────────────────────────────────────── */
int main(int argc, char** argv)
int main(int, char**)
{
const char* nonce = (argc > 1) ? argv[1] : "test0001";
uint32_t pid = current_pid();
/* fill test buffer with known pattern */
for (int i = 0; i < (int)sizeof(g_testBuf); ++i)
g_testBuf[i] = (uint8_t)(i & 0xFF);
/* create bootstrap shm */
if (create_bootstrap(pid, nonce) != 0) {
fprintf(stderr, "ERROR: failed to create bootstrap shm\n");
return 1;
}
/* load payload */
char plPath[1024];
if (payload_path(plPath, sizeof(plPath)) != 0) {
@@ -180,7 +134,7 @@ int main(int argc, char** argv)
#endif
/* open main shm and wait for payloadReady */
void* shmView = open_main_shm(pid, nonce);
void* shmView = open_main_shm(pid);
if (!shmView) {
fprintf(stderr, "ERROR: failed to open main shared memory\n");
return 1;
@@ -197,8 +151,8 @@ int main(int argc, char** argv)
}
/* print READY line for the client to parse */
printf("READY pid=%u nonce=%s testbuf=0x%llx testlen=%u\n",
pid, nonce,
printf("READY pid=%u testbuf=0x%llx testlen=%u\n",
pid,
(unsigned long long)(uintptr_t)g_testBuf,
(unsigned)sizeof(g_testBuf));
fflush(stdout);
@@ -210,7 +164,7 @@ int main(int argc, char** argv)
printf("Payload shut down, exiting.\n");
#ifdef _WIN32
/* give the server thread a moment to exit */
/* give the timer queue a moment to drain */
Sleep(200);
FreeLibrary(hPayload);
if (shmView) UnmapViewOfFile(shmView);