#include #include #include #include #include #include #include #include #include #define LOG_MODULE "server" #include "logger/logger.h" #define PORT 3456 #include "server/base64.c" #include "server/ws_key.c" #include "server/comms.c" #include "ipc.c" int main(void) { mqd_t logging = mq_open("/logs", O_WRONLY); mqd_t tx = mq_open("/server_to_engine", O_WRONLY); mqd_t rx = mq_open("/engine_to_server", O_RDONLY); int server_fd = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(PORT) }; if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } if (listen(server_fd, 16) < 0) { perror("listen"); return 1; } log_infof("Listening on %d", PORT); for (;;) { int client = accept(server_fd, NULL, NULL); if (client < 0) continue; char req[4096]; int n = recv(client, req, sizeof(req) - 1, 0); if (n <= 0) { log_infof("Client close"); close(client); continue; } req[n] = 0; char *key = find_websocket_key(req); if (!key) { close(client); continue; } char accept_key[128]; websocket_accept_key(key, accept_key); char response[512]; snprintf( response, sizeof(response), "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n" "\r\n", accept_key ); send(client, response, strlen(response), 0); log_infof("WebSocket connected"); for (;;) { unsigned char hdr[2]; if (recv(client, hdr, 2, MSG_WAITALL) != 2) break; unsigned opcode = hdr[0] & 0x0F; unsigned len = hdr[1] & 0x7F; if (opcode == 0x8) { unsigned char close_frame[2] = {0x88, 0x00}; send(client, close_frame, 2, 0); break; } if (opcode == 0x9) { unsigned char pong[2] = {0x8A, 0x00}; send(client, pong, 2, 0); continue; } if (len >= 126) break; unsigned char mask[4]; recv(client, mask, 4, MSG_WAITALL); unsigned char payload[126]; recv(client, payload, len, MSG_WAITALL); for (unsigned i = 0; i < len; i++) payload[i] ^= mask[i % 4]; char* payload_ptr = (char*)payload; struct strs response = handle_input(logging, tx, rx, payload_ptr, len); unsigned char out[128]; out[0] = 0x81; for (int i = 0; i < response.count; i++) { struct str item = response.data[i]; out[1] = item.len; assert(item.len <= 125); memcpy(out + 2, item.msg, item.len); send(client, out, item.len + 2, 0); } char end_transmission[] = "END-TRANSMISSION"; int n = strlen(end_transmission); out[1] = n; memcpy(out + 2, end_transmission, n); send(client, out, n + 2, 0); } close(client); } }