Files
utun2/tools/chatgui-android/headless/headless_main.c
T
evgeny 38c9f229bc stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll
- stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close
- utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP),
  add deferred drain in both Phase J and L
- stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39,
  exchange ed25519_pubkey in both handshake directions
- etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in
  etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb
- chat_sync.c: fix lk->conn NULL dereference for TCP links
- test_stcp.c: update stcp_server_create/stcp_client_connect callsites
- tools/chat_tcp_test: change transport udp→tcp
2026-08-07 00:48:27 +03:00

84 lines
2.3 KiB
C

/*
* headless_main.c — headless CLI entry point for chatgui-android
*
* Runs the uTun core without UI. Opens a JSON control socket for management.
* Used for debugging the network stack on Linux before Android integration.
*
* Usage:
* ./headless -p <control_port> -l <logfile>
*
* Config is read via callbacks (set by utun_config_set_provider before init).
* For headless, a stub config provider reads from environment variables.
*/
#include "../libutun_lite/utun_config_api.h"
#include "headless_control.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
/* ── Stub config provider (reads from ENV) ── */
static const char* env_get_string(const char* key, const char* def) {
const char* val = getenv(key);
return val ? val : def;
}
static int env_get_int(const char* key, int def) {
const char* val = getenv(key);
return val ? atoi(val) : def;
}
static const utun_config_provider_t g_env_provider = {
.get_string = env_get_string,
.get_int64 = NULL,
.get_int = env_get_int,
.get_bool = NULL,
};
/* ── Signal handling ── */
static volatile int g_stop = 0;
static void sig_handler(int sig) {
(void)sig;
g_stop = 1;
}
/* ─── main ─── */
int main(int argc, char** argv) {
int control_port = 9999;
const char* bind_ip = "127.0.0.1";
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) control_port = atoi(argv[++i]);
else if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) fprintf(stderr, "logfile: %s\n", argv[++i]);
}
utun_config_set_provider(&g_env_provider);
/* Init control socket (non-uasync for now — simple select-based poll) */
if (headless_control_init(NULL, bind_ip, control_port) < 0) {
fprintf(stderr, "headless: failed to init control socket\n");
return 1;
}
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
printf("headless: running. control socket on %s:%d\n", bind_ip, control_port);
printf("headless: connect with: nc %s %d\n", bind_ip, control_port);
/* Main loop */
while (!g_stop) {
headless_control_poll();
usleep(10000); /* 10ms to avoid busy-loop */
}
headless_control_destroy();
printf("headless: stopped.\n");
return 0;
}