summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--idle.c2
-rw-r--r--main.h5
-rw-r--r--proxy.c2
-rw-r--r--rcon.c2
-rw-r--r--server.c21
-rw-r--r--utils.c27
-rw-r--r--utils.h2
7 files changed, 57 insertions, 4 deletions
diff --git a/idle.c b/idle.c
index 3fddf79..8f2530a 100644
--- a/idle.c
+++ b/idle.c
@@ -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);
}
diff --git a/main.h b/main.h
index d0cb41b..578c8d7 100644
--- a/main.h
+++ b/main.h
@@ -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 */
diff --git a/proxy.c b/proxy.c
index 9fda0c5..6b724f2 100644
--- a/proxy.c
+++ b/proxy.c
@@ -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);
diff --git a/rcon.c b/rcon.c
index a1fd90f..4229527 100644
--- a/rcon.c
+++ b/rcon.c
@@ -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);
}
diff --git a/server.c b/server.c
index 0298491..3cc2398 100644
--- a/server.c
+++ b/server.c
@@ -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");
diff --git a/utils.c b/utils.c
index 39f91f1..93bc0b8 100644
--- a/utils.c
+++ b/utils.c
@@ -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) {
diff --git a/utils.h b/utils.h
index 52a1078..8f8a153 100644
--- a/utils.h
+++ b/utils.h
@@ -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);