summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-06-22 22:42:57 +0200
committerDavid Härdeman <david@hardeman.nu>2020-06-22 22:42:57 +0200
commitfa25599e90a7535a02641ef03ccfc138cf5c8fd3 (patch)
tree684306c00290324a6b6141bf699292487a267039
parentc66ab06124fd757056817b38a9c16f8c8444bf0a (diff)
Add some more config options
-rw-r--r--main.c87
-rw-r--r--main.h11
-rw-r--r--server-proxy.c34
-rw-r--r--utils.c26
4 files changed, 131 insertions, 27 deletions
diff --git a/main.c b/main.c
index fd6b2aa..2cdf5d6 100644
--- a/main.c
+++ b/main.c
@@ -32,6 +32,14 @@
#define DEFAULT_HOMEDIR_PATH "/home/david/intest"
#define DEFAULT_MAIN_CONFIG_FILE_PATH "./mcproxy.conf"
#define DEFAULT_ANNOUNCE_INTERVAL 3
+#define DEFAULT_PROXY_CONN_INTERVAL 3
+#define DEFAULT_PROXY_CONN_ATTEMPTS 20
+#define DEFAULT_SOCKET_DEFER true
+#define DEFAULT_SOCKET_FREEBIND true
+#define DEFAULT_SOCKET_KEEPALIVE true
+#define DEFAULT_SOCKET_IPTOS true
+#define DEFAULT_SOCKET_NODELAY true
+
/* Global */
struct cfg *cfg = NULL;
@@ -199,6 +207,13 @@ enum mcfg_keys {
MCFG_KEY_IGMP,
MCFG_KEY_IGMP_IFACE,
MCFG_KEY_ANN_INTERVAL,
+ MCFG_KEY_PROXY_CONN_INTERVAL,
+ MCFG_KEY_PROXY_CONN_ATTEMPTS,
+ MCFG_KEY_SOCKET_DEFER,
+ MCFG_KEY_SOCKET_FREEBIND,
+ MCFG_KEY_SOCKET_KEEPALIVE,
+ MCFG_KEY_SOCKET_IPTOS,
+ MCFG_KEY_SOCKET_NODELAY,
};
struct cfg_key_value_map mcfg_key_map[] = {
@@ -215,6 +230,34 @@ struct cfg_key_value_map mcfg_key_map[] = {
.key_value = MCFG_KEY_ANN_INTERVAL,
.value_type = CFG_VAL_TYPE_UINT16,
}, {
+ .key_name = "proxy_connection_interval",
+ .key_value = MCFG_KEY_PROXY_CONN_INTERVAL,
+ .value_type = CFG_VAL_TYPE_UINT16,
+ }, {
+ .key_name = "proxy_connection_attempts",
+ .key_value = MCFG_KEY_PROXY_CONN_ATTEMPTS,
+ .value_type = CFG_VAL_TYPE_UINT16,
+ }, {
+ .key_name = "socket_defer",
+ .key_value = MCFG_KEY_SOCKET_DEFER,
+ .value_type = CFG_VAL_TYPE_BOOL,
+ }, {
+ .key_name = "socket_freebind",
+ .key_value = MCFG_KEY_SOCKET_FREEBIND,
+ .value_type = CFG_VAL_TYPE_BOOL,
+ }, {
+ .key_name = "socket_keepalive",
+ .key_value = MCFG_KEY_SOCKET_KEEPALIVE,
+ .value_type = CFG_VAL_TYPE_BOOL,
+ }, {
+ .key_name = "socket_iptos",
+ .key_value = MCFG_KEY_SOCKET_IPTOS,
+ .value_type = CFG_VAL_TYPE_BOOL,
+ }, {
+ .key_name = "socket_nodelay",
+ .key_value = MCFG_KEY_SOCKET_NODELAY,
+ .value_type = CFG_VAL_TYPE_BOOL,
+ }, {
.key_name = NULL,
.key_value = MCFG_KEY_INVALID,
.value_type = CFG_VAL_TYPE_INVALID,
@@ -303,6 +346,34 @@ cfg_read()
cfg->announce_interval = value.uint16;
break;
+ case MCFG_KEY_PROXY_CONN_INTERVAL:
+ cfg->proxy_connection_interval = value.uint16;
+ break;
+
+ case MCFG_KEY_PROXY_CONN_ATTEMPTS:
+ cfg->proxy_connection_attempts = value.uint16;
+ break;
+
+ case MCFG_KEY_SOCKET_DEFER:
+ cfg->socket_defer = value.boolean;
+ break;
+
+ case MCFG_KEY_SOCKET_FREEBIND:
+ cfg->socket_freebind = value.boolean;
+ break;
+
+ case MCFG_KEY_SOCKET_KEEPALIVE:
+ cfg->socket_keepalive = value.boolean;
+ break;
+
+ case MCFG_KEY_SOCKET_IPTOS:
+ cfg->socket_iptos = value.boolean;
+ break;
+
+ case MCFG_KEY_SOCKET_NODELAY:
+ cfg->socket_nodelay = value.boolean;
+ break;
+
case MCFG_KEY_INVALID:
default:
die("main config file (%s) invalid", path);
@@ -397,11 +468,20 @@ cfg_init(int argc, char **argv)
if (!cfg)
die("malloc: %m");
+ uring_task_init(&cfg->task, "main", NULL, cfg_free);
+ list_init(&cfg->servers);
+
+ cfg->homedir = DEFAULT_HOMEDIR_PATH;
cfg->announce_interval = DEFAULT_ANNOUNCE_INTERVAL;
+ cfg->proxy_connection_interval = DEFAULT_PROXY_CONN_INTERVAL;
+ cfg->proxy_connection_attempts = DEFAULT_PROXY_CONN_ATTEMPTS;
+ cfg->socket_defer = DEFAULT_SOCKET_DEFER;
+ cfg->socket_freebind = DEFAULT_SOCKET_FREEBIND;
+ cfg->socket_keepalive = DEFAULT_SOCKET_KEEPALIVE;
+ cfg->socket_iptos = DEFAULT_SOCKET_IPTOS;
+ cfg->socket_nodelay = DEFAULT_SOCKET_NODELAY;
cfg->uid = geteuid();
cfg->gid = getegid();
- uring_task_init(&cfg->task, "main", NULL, cfg_free);
- list_init(&cfg->servers);
while (true) {
int option_index = 0;
@@ -495,9 +575,6 @@ cfg_init(int argc, char **argv)
if (optind < argc)
usage(argc, argv, true);
-
- if (!cfg->homedir)
- cfg->homedir = DEFAULT_HOMEDIR_PATH;
}
static void
diff --git a/main.h b/main.h
index 8c265ca..d405e84 100644
--- a/main.h
+++ b/main.h
@@ -141,6 +141,7 @@ struct uring_task {
};
struct cfg {
+ /* Options */
uid_t uid;
gid_t gid;
const char *homedir;
@@ -149,7 +150,15 @@ struct cfg {
char *igmp_iface;
bool splice_supported;
uint16_t announce_interval;
-
+ uint16_t proxy_connection_interval;
+ uint16_t proxy_connection_attempts;
+ bool socket_defer;
+ bool socket_freebind;
+ bool socket_keepalive;
+ bool socket_iptos;
+ bool socket_nodelay;
+
+ /* Bookkeeping */
struct uring_ev *uring;
struct server_cfg_monitor *server_cfg_monitor;
struct signal_ev *signal;
diff --git a/server-proxy.c b/server-proxy.c
index f897aa2..4cbbb87 100644
--- a/server-proxy.c
+++ b/server-proxy.c
@@ -402,9 +402,15 @@ proxy_new(struct server *server, struct saddr *client, int fd)
list_add(&proxy->list, &server->proxys);
if (server->state != SERVER_STATE_RUNNING) {
- server_start(server);
- ptask_init(&proxy->ptask, 3, 20, proxy_connect_timer_cb);
- ptimer_add_task(&proxy->ptask);
+ if (server_start(server) &&
+ cfg->proxy_connection_interval > 0 &&
+ cfg->proxy_connection_attempts > 0) {
+ ptask_init(&proxy->ptask,
+ cfg->proxy_connection_interval,
+ cfg->proxy_connection_attempts,
+ proxy_connect_timer_cb);
+ ptimer_add_task(&proxy->ptask);
+ }
}
proxy->connecting = true;
@@ -481,15 +487,21 @@ local_open(struct server_local *local)
}
/* 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)
- error("setsockopt: %m");
+ if (cfg->socket_defer) {
+ option = true;
+ if (setsockopt(sfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+ }
- /* FIXME: could make this configurable */
- option = true;
- if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
+ /*
+ * This has the advantage that interfaces don't need to be up but
+ * it means that cfg errors will not be caught.
+ */
+ if (cfg->socket_freebind) {
+ option = true;
+ if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+ }
socket_set_low_latency(sfd);
diff --git a/utils.c b/utils.c
index 49b8537..eacc586 100644
--- a/utils.c
+++ b/utils.c
@@ -175,20 +175,26 @@ socket_set_low_latency(int sfd)
assert_return(sfd >= 0);
- /* FIXME: could make this configurable */
- option = true;
- if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
+ /* Probably not necessary, but can't hurt */
+ if (cfg->socket_defer) {
+ option = true;
+ if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+ }
/* Doubtful if it has much effect, but can't hurt */
- option = IPTOS_LOWDELAY;
- if (setsockopt(sfd, IPPROTO_IP, IP_TOS, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
+ if (cfg->socket_iptos) {
+ option = IPTOS_LOWDELAY;
+ if (setsockopt(sfd, IPPROTO_IP, IP_TOS, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+ }
/* Nagle's algorithm is a poor fit for gaming */
- option = true;
- if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
+ if (cfg->socket_nodelay) {
+ option = true;
+ if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+ }
}
void