summaryrefslogtreecommitdiff
path: root/minecproxy/server-config.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-06-30 08:10:04 +0200
committerDavid Härdeman <david@hardeman.nu>2020-06-30 08:10:04 +0200
commita89a0f918925a662503c1bcb28bdb06ab9b7ef25 (patch)
tree733b4c1ff841f99eeb3840c5948fef6c5bf76109 /minecproxy/server-config.c
parent8f29a4d23dd13a80aa26951b17e2a71f4e651cb1 (diff)
Share config parsing fully between server and cmdline tool
Diffstat (limited to 'minecproxy/server-config.c')
-rw-r--r--minecproxy/server-config.c268
1 files changed, 10 insertions, 258 deletions
diff --git a/minecproxy/server-config.c b/minecproxy/server-config.c
index 71463ee..6fdd73a 100644
--- a/minecproxy/server-config.c
+++ b/minecproxy/server-config.c
@@ -14,262 +14,7 @@
#include "config-parser.h"
#include "server.h"
#include "server-config.h"
-#include "server-config-options.h"
-
-static void scfg_dns_cb(struct dns_async *dns,
- bool (*server_cb)(struct server *, struct saddr *))
-{
- struct server *server;
- struct sockaddr_in *in4;
- struct sockaddr_in6 *in6;
- struct saddr *saddr;
- struct addrinfo *results = NULL, *ai;
- int r;
-
- assert_return(dns && dns->priv && server_cb);
-
- server = dns->priv;
- debug(DBG_DNS,
- "called, dns: %p, name: %s, server: %p, server->name: %s", dns,
- dns->name, server, server->name);
-
- r = gai_error(&dns->gcb);
- if (r == EAI_INPROGRESS) {
- /* This shouldn't happen, assume we'll get called again */
- error("called with request in progress");
- return;
- } else if (r == EAI_CANCELED) {
- /* The server must be in the process of going away */
- goto out;
- } else if (r < 0) {
- error("DNS lookup of %s:%s failed: %s", dns->name, dns->port,
- gai_strerror(r));
- goto out;
- }
-
- results = dns->gcb.ar_result;
-
- for (ai = results; ai; ai = ai->ai_next) {
- saddr = zmalloc(sizeof(*saddr));
- if (!saddr) {
- error("DNS lookup of %s:%s failed: %m", dns->name,
- dns->port);
- goto out;
- }
-
- switch (ai->ai_family) {
- case AF_INET:
- in4 = (struct sockaddr_in *)ai->ai_addr;
- saddr_set_ipv4(saddr, in4->sin_addr.s_addr,
- in4->sin_port);
- server_cb(server, saddr);
- break;
-
- case AF_INET6:
- in6 = (struct sockaddr_in6 *)ai->ai_addr;
- saddr_set_ipv6(saddr, &in6->sin6_addr, in6->sin6_port);
- server_cb(server, saddr);
- break;
-
- default:
- error("getaddrinfo(%s:%s): unknown address family (%i)",
- dns->name, dns->port, ai->ai_family);
- xfree(saddr);
- break;
- }
- }
-
-out:
- freeaddrinfo(results);
- list_del(&dns->list);
- xfree(dns);
- uring_task_put(&server->task);
- server_commit(server);
-}
-
-static void scfg_local_dns_cb(struct dns_async *dns)
-{
- assert_return(dns);
-
- scfg_dns_cb(dns, server_add_local);
-}
-
-static void scfg_remote_dns_cb(struct dns_async *dns)
-{
- assert_return(dns);
-
- scfg_dns_cb(dns, server_add_remote);
-}
-
-static void scfg_rcon_dns_cb(struct dns_async *dns)
-{
- assert_return(dns);
-
- scfg_dns_cb(dns, server_add_rcon);
-}
-
-static bool handle_dns(struct server *server, const char *type,
- struct cfg_value *value, dns_cb_t *async_cb,
- bool (*sync_cb)(struct server *, struct saddr *))
-{
- struct saddr *saddr, *tmp;
- struct dns_async *dns;
-
- assert_return(server && type && value && async_cb && sync_cb, false);
-
- switch (value->type) {
- case CFG_VAL_TYPE_ADDRS:
- debug(DBG_DNS, "%s: got immediate addrs", type);
-
- list_for_each_entry_safe(saddr, tmp, &value->saddrs, list) {
- list_del(&saddr->list);
- sync_cb(server, saddr);
- }
- return true;
-
- case CFG_VAL_TYPE_ASYNC_ADDRS:
- debug(DBG_DNS, "%s: doing async lookup of DNS record: %p", type,
- value->dns_async);
-
- dns = value->dns_async;
- dns->cb = async_cb;
- dns->priv = server;
- list_add(&dns->list, &server->dnslookups);
- uring_task_get(&server->task);
- return true;
-
- default:
- return false;
- }
-}
-
-static void scfg_parse(struct server *server)
-{
- char *pos;
-
- assert_return(server);
-
- pos = server->tbuf.buf;
-
- if (!config_parse_header(SERVER_CFG_HEADER, &pos)) {
- verbose("%s: missing/invalid header", server->name);
- return;
- }
-
- while (true) {
- int key;
- const char *keyname;
- struct cfg_value value;
-
- if (!config_parse_line(server->name, &pos, scfg_key_map, &key,
- &keyname, &value, true))
- break;
-
- if (key == SCFG_KEY_INVALID)
- break;
-
- debug(DBG_CFG, "%s: key %s", server->name, keyname);
-
- switch (key) {
- case SCFG_KEY_TYPE:
- if (streq(value.str, "proxy")) {
- if (!server_set_type(server, SERVER_TYPE_PROXY))
- return;
- } else if (streq(value.str, "announce")) {
- if (!server_set_type(server,
- SERVER_TYPE_ANNOUNCE))
- return;
- }
- break;
-
- case SCFG_KEY_NAME:
- if (!server_set_pretty_name(server, value.str))
- return;
- break;
-
- case SCFG_KEY_PORT:
- if (!server_set_port(server, value.uint16))
- return;
- break;
-
- case SCFG_KEY_LOCAL:
- if (!handle_dns(server, "local", &value,
- scfg_local_dns_cb, server_add_local))
- return;
- break;
-
- case SCFG_KEY_REMOTE:
- if (!handle_dns(server, "remote", &value,
- scfg_remote_dns_cb, server_add_remote))
- return;
- break;
-
- case SCFG_KEY_IDLE_TIMEOUT:
- if (!server_set_idle_timeout(server, value.uint16))
- return;
- break;
-
- case SCFG_KEY_STOP_METHOD:
- if (streq(value.str, "exec")) {
- if (server_set_stop_method(
- server, SERVER_STOP_METHOD_EXEC))
- break;
- } else if (streq(value.str, "rcon")) {
- if (server_set_stop_method(
- server, SERVER_STOP_METHOD_RCON))
- break;
- } else if (streq(value.str, "systemd")) {
- if (server_set_stop_method(
- server, SERVER_STOP_METHOD_SYSTEMD))
- break;
- }
- return;
-
- case SCFG_KEY_START_METHOD:
- if (streq(value.str, "exec")) {
- if (server_set_start_method(
- server, SERVER_START_METHOD_EXEC))
- break;
- } else if (streq(value.str, "systemd")) {
- if (server_set_start_method(
- server,
- SERVER_START_METHOD_SYSTEMD))
- break;
- }
- return;
-
- case SCFG_KEY_STOP_EXEC:
- if (!server_set_stop_exec(server, value.str))
- return;
- break;
-
- case SCFG_KEY_START_EXEC:
- if (!server_set_start_exec(server, value.str))
- return;
- break;
-
- case SCFG_KEY_RCON:
- if (!handle_dns(server, "rcon", &value,
- scfg_rcon_dns_cb, server_add_rcon))
- return;
- break;
-
- case SCFG_KEY_RCON_PASSWORD:
- if (!server_set_rcon_password(server, value.str))
- return;
- break;
-
- case SCFG_KEY_SYSTEMD_SERVICE:
- if (!server_set_systemd_service(server, value.str))
- return;
- break;
-
- case SCFG_KEY_INVALID:
- default:
- break;
- }
- }
-}
+#include "config.h"
static void scfg_read_cb(struct uring_task *task, int res)
{
@@ -286,7 +31,14 @@ static void scfg_read_cb(struct uring_task *task, int res)
debug(DBG_CFG, "%s: parsing cfg (%i bytes)", server->name, res);
uring_task_close_fd(&server->task);
- scfg_parse(server);
+
+ if (!scfg_parse(&server->scfg, server->tbuf.buf,
+ server_async_dns_update)) {
+ error("%s: failed to parse config file", server->name);
+ server_delete(server);
+ return;
+ }
+
server_commit(server);
}
@@ -403,7 +155,7 @@ static void inotify_cb(struct uring_task *task, int res)
continue;
if (event->mask & (IN_MOVED_FROM | IN_DELETE))
- server_delete_by_name(event->name);
+ server_delete_by_filename(event->name);
else if (event->mask &
(IN_MOVED_TO | IN_CREATE | IN_CLOSE_WRITE)) {
server = server_new(event->name);