diff options
-rw-r--r-- | idle.c | 2 | ||||
-rw-r--r-- | main.h | 5 | ||||
-rw-r--r-- | proxy.c | 2 | ||||
-rw-r--r-- | rcon.c | 2 | ||||
-rw-r--r-- | server.c | 21 | ||||
-rw-r--r-- | utils.c | 27 | ||||
-rw-r--r-- | utils.h | 2 |
7 files changed, 57 insertions, 4 deletions
@@ -361,6 +361,8 @@ again: goto again; } + socket_set_gaming_options(cfg, sfd); + uring_task_set_fd(&idle->idlecheck, sfd); uring_connect(cfg, &idle->idlecheck, &idle->remote, idle_check_remote_connected); } @@ -3,6 +3,9 @@ #include <sys/socket.h> #include <netinet/ip.h> + +struct cfg; + #include "utils.h" extern bool exiting; @@ -18,8 +21,6 @@ void die(const char *fmt, ...); #define perrordie(msg) die("%s: %m\n", msg) -struct cfg; - struct uring_task; /* To save typing in all the function definitions below */ @@ -236,6 +236,8 @@ again: goto again; } + socket_set_gaming_options(cfg, sfd); + proxy->sfd = sfd; uring_task_set_fd(&proxy->servertask, sfd); uring_connect(cfg, &proxy->servertask, &proxy->server, proxy_server_connected); @@ -372,6 +372,8 @@ again: goto again; } + socket_set_gaming_options(cfg, sfd); + uring_task_set_fd(&rcon->task, sfd); uring_connect(cfg, &rcon->task, &rcon->rcon, rcon_connected); } @@ -10,6 +10,9 @@ #include <poll.h> #include <errno.h> #include <sched.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> #include "main.h" #include "uring.h" @@ -212,7 +215,7 @@ static bool server_local_open(struct cfg *cfg, struct server *scfg, struct server_local *local) { int sfd; - int enable = 1; + int option; int r; sfd = socket(local->addr.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); @@ -221,11 +224,25 @@ server_local_open(struct cfg *cfg, struct server *scfg, struct server_local *loc goto out; } - if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) { + option = true; + if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { perror("setsockopt"); goto out; } + /* The MC protocol expects the client to send data first */ + /* FIXME: could make this configurable */ + option = true; + if (setsockopt(sfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &option, sizeof(option)) < 0) + perror("setsockopt"); + + /* FIXME: could make this configurable */ + option = true; + if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0) + perror("setsockopt"); + + socket_set_gaming_options(cfg, sfd); + r = bind(sfd, (struct sockaddr *)&local->addr.storage, local->addr.addrlen); if (r < 0) { perror("bind"); @@ -8,6 +8,9 @@ #include <dirent.h> #include <fcntl.h> #include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> #include "main.h" #include "utils.h" @@ -155,6 +158,30 @@ debug_resource_usage() } } +void +socket_set_gaming_options(struct cfg *cfg, int sfd) +{ + int option; + + if (sfd <= 0) + return; + + /* FIXME: could make this configurable */ + option = true; + if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)) < 0) + perror("setsockopt"); + + /* Doubtful if it has much effect, but can't hurt */ + option = IPTOS_LOWDELAY; + if (setsockopt(sfd, IPPROTO_IP, IP_TOS, &option, sizeof(option)) < 0) + perror("setsockopt"); + + /* Nagle's algorithm is a poor fit for gaming */ + option = true; + if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) < 0) + perror("setsockopt"); +} + uint16_t sockaddr_port(struct sockaddr_in46 *addr) { switch (addr->storage.ss_family) { @@ -104,6 +104,8 @@ struct sockaddr_in46 { struct list_head list; }; +void socket_set_gaming_options(struct cfg *cfg, int sfd); + uint16_t sockaddr_port(struct sockaddr_in46 *addr); char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen); |