diff options
| author | David Härdeman <david@hardeman.nu> | 2020-06-30 08:10:04 +0200 | 
|---|---|---|
| committer | David Härdeman <david@hardeman.nu> | 2020-06-30 08:10:04 +0200 | 
| commit | a89a0f918925a662503c1bcb28bdb06ab9b7ef25 (patch) | |
| tree | 733b4c1ff841f99eeb3840c5948fef6c5bf76109 /minecproxy/server-config.c | |
| parent | 8f29a4d23dd13a80aa26951b17e2a71f4e651cb1 (diff) | |
Share config parsing fully between server and cmdline tool
Diffstat (limited to 'minecproxy/server-config.c')
| -rw-r--r-- | minecproxy/server-config.c | 268 | 
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); | 
