// // libsyd: Rust-based C library for syd interaction via /dev/syd // lib/examples/echo_server.c: syd API C Library Echo Server Example // // Copyright (c) 2023 Ali Polatel // // SPDX-License-Identifier: GPL-3.0 /* * Compile this with: * cc -fPIC -fPIE echo_server.c -oecho_server -static-pie -lsyd * Run with: * syd -pcontainer ./echo_server * This binds to port 127.0.0.1:65432 */ #include #include #include #include #include #include #include #include #include #define PORT 65432 // Port number for the server #define BUFFER_SIZE 1024 // Size of the buffer for incoming messages int main() { int server_fd, new_socket; struct sockaddr_in address; int r, opt = 1; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; bool should_quit = false; // Flag to indicate if the server should quit // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { err(1, "socket failed"); } // Forcefully attaching socket to the port 65432 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { err(1, "setsockopt"); } address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); address.sin_port = htons(PORT); if ((r = syd_check()) != 0) { errno = -r; err(1, "Not running under syd"); } if ((r = syd_allow_net_bind_add("LOOPBACK!65432")) != 0) { errno = -r; err(1, "Failed to allow LOOPBACK!65432"); } // Binding the socket to the port 65432 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { err(1, "bind failed"); } if ((r = syd_allow_net_bind_del("LOOPBACK!65432")) != 0) { errno = -r; err(1, "Failed to allow LOOPBACK!65432"); } if ((r = syd_lock(LOCK_ON)) != 0) { errno = -r; err(1, "Failed to lock syd"); } // Listening for incoming connections if (listen(server_fd, 3) < 0) { err(1, "listen"); } for (;;) { printf("*** Waiting for a connection...\n"); // Accepting an incoming connection if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { err(1, "accept"); } printf("*** Connection established\n"); // Read data from the client, echo it back ssize_t read_bytes; while ((read_bytes = read(new_socket, buffer, BUFFER_SIZE)) > 0) { if (strncmp(buffer, "QUIT", 4) == 0) { printf("*** Received 'QUIT', exiting.\n"); should_quit = true; // Set the flag to break out of the outer loop break; } write(new_socket, buffer, read_bytes); memset(buffer, 0, BUFFER_SIZE); // Clear the buffer } if (read_bytes < 0) { err(1, "read"); } close(new_socket); printf("*** Connection closed\n"); if (should_quit) { break; // Exit the outer loop if "QUIT" was received } } printf("*** Shutting down server.\n"); close(server_fd); return 0; }