Add unix socket listening mode
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <stdexcept>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern std::atomic<int> activeConnections;
|
||||
@@ -145,9 +146,64 @@ void Server::setup_shutdown_pipe() {
|
||||
}
|
||||
|
||||
int Server::create_listen_socket() {
|
||||
int sfd;
|
||||
|
||||
// Check if unix socket path is specified
|
||||
if (!config_.server.unix_socket_path.empty()) {
|
||||
// Create unix socket
|
||||
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sfd == -1) {
|
||||
perror("socket");
|
||||
throw std::runtime_error("Failed to create unix socket");
|
||||
}
|
||||
|
||||
// Remove existing socket file if it exists
|
||||
unlink(config_.server.unix_socket_path.c_str());
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
if (config_.server.unix_socket_path.length() >= sizeof(addr.sun_path)) {
|
||||
close(sfd);
|
||||
throw std::runtime_error("Unix socket path too long");
|
||||
}
|
||||
|
||||
strncpy(addr.sun_path, config_.server.unix_socket_path.c_str(),
|
||||
sizeof(addr.sun_path) - 1);
|
||||
|
||||
// Set socket to non-blocking for graceful shutdown
|
||||
int flags = fcntl(sfd, F_GETFL, 0);
|
||||
if (flags == -1) {
|
||||
perror("fcntl F_GETFL");
|
||||
close(sfd);
|
||||
throw std::runtime_error("Failed to get socket flags");
|
||||
}
|
||||
if (fcntl(sfd, F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
perror("fcntl F_SETFL");
|
||||
close(sfd);
|
||||
throw std::runtime_error("Failed to set socket non-blocking");
|
||||
}
|
||||
|
||||
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
perror("bind");
|
||||
close(sfd);
|
||||
throw std::runtime_error("Failed to bind unix socket");
|
||||
}
|
||||
|
||||
if (listen(sfd, SOMAXCONN) == -1) {
|
||||
perror("listen");
|
||||
close(sfd);
|
||||
throw std::runtime_error("Failed to listen on unix socket");
|
||||
}
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
// TCP socket creation (original code)
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int sfd, s;
|
||||
int s;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
@@ -178,11 +234,13 @@ int Server::create_listen_socket() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Enable TCP_NODELAY for low latency
|
||||
if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) {
|
||||
perror("setsockopt TCP_NODELAY");
|
||||
close(sfd);
|
||||
continue;
|
||||
// Enable TCP_NODELAY for low latency (only for TCP sockets)
|
||||
if (rp->ai_family == AF_INET || rp->ai_family == AF_INET6) {
|
||||
if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) {
|
||||
perror("setsockopt TCP_NODELAY");
|
||||
close(sfd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Set socket to non-blocking for graceful shutdown
|
||||
@@ -438,4 +496,9 @@ void Server::cleanup_resources() {
|
||||
close(listen_sockfd_);
|
||||
listen_sockfd_ = -1;
|
||||
}
|
||||
|
||||
// Clean up unix socket file if it exists
|
||||
if (!config_.server.unix_socket_path.empty()) {
|
||||
unlink(config_.server.unix_socket_path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user