From b1b94e828f477b384eb36a8cee9e511069ee77a5 Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Tue, 28 Apr 2026 00:06:58 +0200 Subject: Adds native server and client (WIP) --- core/client.c | 28 ++++++++++++++++ core/server.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 core/client.c create mode 100644 core/server.c (limited to 'core') diff --git a/core/client.c b/core/client.c new file mode 100644 index 0000000..220a90c --- /dev/null +++ b/core/client.c @@ -0,0 +1,28 @@ +#include +#include + +#include "logger.c" + +int main(void) { + log_info("Initializing salis data client"); + int client_fd = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in server_addr = { 0 }; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(IP); + server_addr.sin_port = htons(PORT); + + log_info("Attempting to connect to salis data server at: %s:%d", IP, PORT); + if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in))) { + log_warn("Could not connect to salis data server!"); + return 1; + } + + log_info("Fetching simulation info"); + write(client_fd, "o", sizeof(char)); + struct json_object *response = json_object_from_fd(client_fd); + const char *str_rep = json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY); + printf("resp: %s\n", str_rep); + + close(client_fd); + return 0; +} diff --git a/core/server.c b/core/server.c new file mode 100644 index 0000000..388776d --- /dev/null +++ b/core/server.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include + +#include "logger.c" + +#define BACKLOG 10 +#define REQUEST_OPTS 'o' + +struct Client { + int fd; + struct sockaddr_in addr; +}; + +void sig_handler(int signo) { + log_warn("Signal %d received, shutting down server", signo); + exit(0); +} + +void respond_opts(int client_fd) { + log_info("Client requested simulator options"); + + struct json_object *response = json_object_new_object(); + json_object_object_add(response, "anc", json_object_new_string(ANC)); + json_object_object_add(response, "arch", json_object_new_string(ARCH)); + json_object_object_add(response, "auto-save-interval", json_object_new_int64(AUTOSAVE_INTERVAL)); + json_object_object_add(response, "clones", json_object_new_int64(CLONES)); + json_object_object_add(response, "compress", json_object_new_boolean(COMPRESS)); + json_object_object_add(response, "cores", json_object_new_int64(CORES)); + json_object_object_add(response, "data-push", json_object_new_boolean(DATA_PUSH)); + json_object_object_add(response, "data-push-interval", json_object_new_int64(DATA_PUSH_INTERVAL)); + json_object_object_add(response, "muta-flip", json_object_new_boolean(MUTA_FLIP)); + json_object_object_add(response, "muta-range", json_object_new_int64(MUTA_RANGE)); + json_object_object_add(response, "mvec-loop", json_object_new_boolean(MVEC_LOOP)); + json_object_object_add(response, "mvec-size", json_object_new_int64(MVEC_SIZE)); + json_object_object_add(response, "name", json_object_new_string(NAME)); + json_object_object_add(response, "seed", json_object_new_int64(SEED)); + json_object_object_add(response, "sync-interval", json_object_new_int64(SYNC_INTERVAL)); + + const char *str_rep = json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY); + send(client_fd, str_rep, strlen(str_rep), 0); + json_object_put(response); +} + +int handle_client(struct Client *client) { + assert(client); + + char client_ip[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &client->addr.sin_addr, client_ip, INET_ADDRSTRLEN); + log_info("Client connected: %s:%d", client_ip, ntohs(client->addr.sin_port)); + + char request = '\0'; + recv(client->fd, &request, 1, 0); + + switch (request) { + case REQUEST_OPTS: respond_opts(client->fd); break; + default: log_warn("Client made invalid request"); + } + + log_info("Client disconnected: %s:%d", client_ip, ntohs(client->addr.sin_port)); + close(client->fd); + + free(client); + return 0; +} + +int main(void) { + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + + log_info("Initializing salis data server"); + int opt = 1; + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + log_info("Binding to port: %d", PORT); + struct sockaddr_in server_addr = { 0 }; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(PORT); + bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)); + + log_info("Listening..."); + listen(server_fd, BACKLOG); + + while (true) { + struct Client *client = calloc(1, sizeof(struct Client)); + socklen_t client_len = sizeof(struct sockaddr_in); + client->fd = accept(server_fd, (struct sockaddr *)&client->addr, &client_len); + + thrd_t thrd; + thrd_create(&thrd, (thrd_start_t)handle_client, client); + thrd_detach(thrd); + } + + close(server_fd); + return 0; +} -- cgit v1.3