summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-06-22 11:29:11 +0200
committerDavid Härdeman <david@hardeman.nu>2020-06-22 11:29:11 +0200
commitf2489c89e95c07495768b5401b63ba31ec39d72d (patch)
tree214d29dffaa20c2fff2fd6672168da83508b1f39
parent4f9bedb603c772880248914617cee0b44f848290 (diff)
Move local handling from server to proxy
-rw-r--r--proxy.c166
-rw-r--r--proxy.h17
-rw-r--r--server.c134
3 files changed, 179 insertions, 138 deletions
diff --git a/proxy.c b/proxy.c
index 28a207d..7edfffd 100644
--- a/proxy.c
+++ b/proxy.c
@@ -1,5 +1,9 @@
#include <stdio.h>
+#include <unistd.h>
#include <time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
#include "main.h"
#include "uring.h"
@@ -7,16 +11,6 @@
#include "proxy.h"
#include "utils.h"
-void
-proxy_refdump(struct server_proxy *proxy)
-{
- assert_return(proxy);
-
- uring_task_refdump(&proxy->task);
- uring_task_refdump(&proxy->clienttask);
- uring_task_refdump(&proxy->servertask);
-}
-
static void
format_bytes(char *buf, size_t len, uint64_t val)
{
@@ -239,6 +233,16 @@ proxy_connected_cb(struct connection *conn, bool connected)
uring_tbuf_read(&proxy->servertask, proxy_server_data_in);
}
+void
+proxy_refdump(struct server_proxy *proxy)
+{
+ assert_return(proxy);
+
+ uring_task_refdump(&proxy->task);
+ uring_task_refdump(&proxy->clienttask);
+ uring_task_refdump(&proxy->servertask);
+}
+
struct server_proxy *
proxy_new(struct server *server, struct saddr *client, int fd)
{
@@ -276,3 +280,145 @@ proxy_new(struct server *server, struct saddr *client, int fd)
return proxy;
}
+static void
+local_accept(struct uring_task *task, int res)
+{
+ struct server_local *local = container_of(task, struct server_local, task);
+ struct server *server = container_of(task->parent, struct server, task);
+ struct server_proxy *proxy;
+
+ assert_return(task);
+ assert_task_alive(DBG_PROXY, task);
+
+ debug(DBG_PROXY, "task %p, res %i, server %s", task, res, server->name);
+
+ if (res < 0) {
+ error("result was %i", res);
+ goto out;
+ }
+
+ saddr_set_addrstr(&local->client);
+
+ verbose("%s: incoming proxy connection: %s -> %s",
+ server->name, local->client.addrstr, local->local.addrstr);
+
+ if (list_empty(&server->remotes)) {
+ /* This shouldn't be possible, checked before opening local */
+ error("server->remotes empty!");
+ uring_close(&local->task, res);
+ goto out;
+ }
+
+ proxy = proxy_new(server, &local->client, res);
+ if (!proxy)
+ uring_close(&local->task, res);
+
+out:
+ uring_accept(&local->task, &local->client, local_accept);
+}
+
+bool
+local_open(struct server_local *local)
+{
+ int sfd;
+ int option;
+ int r;
+
+ assert_return(local && local->server, false);
+
+ sfd = socket(local->local.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (sfd < 0) {
+ error("socket: %m");
+ goto error;
+ }
+
+ option = true;
+ if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) {
+ error("setsockopt: %m");
+ goto error;
+ }
+
+ /* 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");
+
+ /* FIXME: could make this configurable */
+ option = true;
+ if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0)
+ error("setsockopt: %m");
+
+ socket_set_low_latency(sfd);
+
+ r = bind(sfd, (struct sockaddr *)&local->local.storage, local->local.addrlen);
+ if (r < 0) {
+ error("bind: %m");
+ goto error;
+ }
+
+ r = listen(sfd, 100);
+ if (r < 0) {
+ error("listen: %m");
+ goto error;
+ }
+
+ uring_task_set_fd(&local->task, sfd);
+ uring_accept(&local->task, &local->client, local_accept);
+ return true;
+
+error:
+ if (sfd >= 0)
+ uring_close(&local->task, sfd);
+ return false;
+}
+
+void
+local_refdump(struct server_local *local)
+{
+ assert_return(local);
+
+ uring_task_refdump(&local->task);
+}
+
+static void
+local_free(struct uring_task *task)
+{
+ struct server_local *local = container_of(task, struct server_local, task);
+
+ assert_return(task);
+
+ debug(DBG_PROXY, "task %p, local %p", task, local);
+ list_del(&local->list);
+ xfree(local);
+}
+
+void
+local_delete(struct server_local *local)
+{
+ assert_return(local);
+
+ uring_task_destroy(&local->task);
+}
+
+struct server_local *
+local_new(struct server *server, struct saddr *saddr)
+{
+ struct server_local *local;
+
+ assert_return(server && saddr, NULL);
+
+ local = zmalloc(sizeof(*local));
+ if (!local) {
+ error("malloc: %m");
+ return NULL;
+ }
+
+ debug(DBG_PROXY, "%s adding local: %s", server->name, saddr->addrstr);
+ local->local = *saddr;
+ local->server = server;
+ uring_task_init(&local->task, "local", &server->task, local_free);
+ xfree(saddr);
+ return local;
+}
+
diff --git a/proxy.h b/proxy.h
index 0726351..75c078d 100644
--- a/proxy.h
+++ b/proxy.h
@@ -28,4 +28,21 @@ void proxy_delete(struct server_proxy *proxy);
struct server_proxy *proxy_new(struct server *server, struct saddr *client,
int fd);
+struct server_local {
+ struct saddr local;
+ struct saddr client;
+ struct uring_task task;
+
+ struct server *server;
+ struct list_head list;
+};
+
+bool local_open(struct server_local *local);
+
+void local_refdump(struct server_local *local);
+
+void local_delete(struct server_local *local);
+
+struct server_local *local_new(struct server *server, struct saddr *saddr);
+
#endif
diff --git a/server.c b/server.c
index ddd4ad4..9290a96 100644
--- a/server.c
+++ b/server.c
@@ -10,9 +10,6 @@
#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"
@@ -24,13 +21,6 @@
#include "rcon.h"
#include "systemd.h"
-struct server_local {
- struct saddr local;
- struct saddr client;
- struct uring_task task;
- struct list_head list;
-};
-
static bool
set_property(struct server *server, char **property, const char *value)
{
@@ -58,7 +48,7 @@ server_refdump(struct server *server)
uring_task_refdump(&server->ann_task);
uring_task_refdump(&server->idle_task);
list_for_each_entry(local, &server->locals, list)
- uring_task_refdump(&local->task);
+ local_refdump(local);
list_for_each_entry(proxy, &server->proxys, list)
proxy_refdump(proxy);
rcon_refdump(server->rcon);
@@ -101,7 +91,7 @@ server_delete(struct server *server)
rcon_delete(server);
list_for_each_entry_safe(local, ltmp, &server->locals, list)
- uring_task_destroy(&local->task);
+ local_delete(local);
list_for_each_entry_safe(proxy, ptmp, &server->proxys, list)
proxy_delete(proxy);
@@ -187,111 +177,6 @@ server_dump(struct server *server)
}
static void
-server_local_free(struct uring_task *task)
-{
- struct server_local *local = container_of(task, struct server_local, task);
-
- assert_return(task);
-
- debug(DBG_SRV, "task %p, local %p", task, local);
- list_del(&local->list);
- xfree(local);
-}
-
-static void
-server_local_accept(struct uring_task *task, int res)
-{
- struct server_local *local = container_of(task, struct server_local, task);
- struct server *server = container_of(task->parent, struct server, task);
- struct server_proxy *proxy;
-
- assert_return(task);
- assert_task_alive(DBG_SRV, task);
-
- debug(DBG_SRV, "task %p, res %i, server %s", task, res, server->name);
-
- if (res < 0) {
- error("result was %i", res);
- goto out;
- }
-
- saddr_set_addrstr(&local->client);
-
- verbose("%s: incoming proxy connection: %s -> %s",
- server->name, local->client.addrstr, local->local.addrstr);
-
- if (list_empty(&server->remotes)) {
- /* This shouldn't be possible, checked before opening local */
- error("server->remotes empty!");
- uring_close(&local->task, res);
- goto out;
- }
-
- proxy = proxy_new(server, &local->client, res);
- if (!proxy)
- uring_close(&local->task, res);
-
-out:
- uring_accept(&local->task, &local->client, server_local_accept);
-}
-
-static bool
-server_local_open(struct server *server, struct server_local *local)
-{
- int sfd;
- int option;
- int r;
-
- assert_return(server && local, false);
-
- sfd = socket(local->local.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (sfd < 0) {
- error("socket: %m");
- goto error;
- }
-
- option = true;
- if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) {
- error("setsockopt: %m");
- goto error;
- }
-
- /* 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");
-
- /* FIXME: could make this configurable */
- option = true;
- if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
-
- socket_set_low_latency(sfd);
-
- r = bind(sfd, (struct sockaddr *)&local->local.storage, local->local.addrlen);
- if (r < 0) {
- error("bind: %m");
- goto error;
- }
-
- r = listen(sfd, 100);
- if (r < 0) {
- error("listen: %m");
- goto error;
- }
-
- uring_task_set_fd(&local->task, sfd);
- uring_accept(&local->task, &local->client, server_local_accept);
- return true;
-
-error:
- if (sfd >= 0)
- close(sfd);
- return false;
-}
-
-static void
server_exec_free(struct uring_task *task)
{
assert_return(task);
@@ -731,9 +616,8 @@ server_commit(struct server *server)
/* FIXME: config, dont reread config if server running, make sure fd is available before this is called */
server_dump(server);
- list_for_each_entry(local, &server->locals, list) {
- server_local_open(server, local);
- }
+ list_for_each_entry(local, &server->locals, list)
+ local_open(local);
server->state = SERVER_STATE_CFG_OK;
@@ -762,17 +646,11 @@ server_add_local(struct server *server, struct saddr *saddr)
assert_return(server && saddr, false);
assert_task_alive_or(DBG_SRV, &server->task, return false);
- local = zmalloc(sizeof(*local));
- if (!local) {
- error("malloc: %m");
+ local = local_new(server, saddr);
+ if (!local)
return false;
- }
- debug(DBG_SRV, "adding local: %s", saddr->addrstr);
- local->local = *saddr;
- uring_task_init(&local->task, "local", &server->task, server_local_free);
list_add(&local->list, &server->locals);
- xfree(saddr);
return true;
}