summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/config-parser.c196
-rw-r--r--shared/config-parser.h8
-rw-r--r--shared/utils.c10
-rw-r--r--shared/utils.h2
4 files changed, 113 insertions, 103 deletions
diff --git a/shared/config-parser.c b/shared/config-parser.c
index b8abecb..3309b96 100644
--- a/shared/config-parser.c
+++ b/shared/config-parser.c
@@ -57,7 +57,7 @@ static bool handle_addrinfo_results(struct addrinfo *results,
return rv;
}
-void scfg_async_dns_result(struct server_config *scfg)
+void scfg_async_dns_update(struct server_config *scfg)
{
struct dns_async *dns, *tmp;
unsigned naddrs = 0;
@@ -114,53 +114,65 @@ void scfg_async_dns_result(struct server_config *scfg)
scfg->gcbs = NULL;
}
-static inline char tohex(uint8_t val)
+bool scfg_async_dns_start(struct server_config *scfg)
{
- static const char hex[] = "0123456789abcdef";
+ struct dns_async *dns;
+ unsigned ndns = 0;
+ int r;
- return hex[val & 0x0f];
-}
+ assert_return(scfg, false);
-/*
- * Creates an escaped D-Bus object path for a given systemd service
- *
- * Escaping rules are documented here:
- * https://dbus.freedesktop.org/doc/dbus-specification.html
- *
- * Essentially, everyting but a-z, A-Z, 0-9 is replaced by _xx where xx is
- * the hexadecimal value of the character.
- *
- * Example: minecraft@world1.service -> minecraft_40world1_2eservice
- */
-static char *systemd_object_path(const char *service)
-{
- char *r;
- char *d;
- const char *s;
+ list_for_each_entry(dns, &scfg->dnslookups, list)
+ ndns++;
- assert_return(service && !empty_str(service), NULL);
+ scfg->gcbs = zmalloc(sizeof(struct gaicb) * ndns);
+ if (!scfg->gcbs) {
+ error("failed to allocate gcbs: %m");
+ return false;
+ }
- r = zmalloc(STRLEN(SYSTEMD_DBUS_PATH_PREFIX) + strlen(service) * 3 + 1);
- if (!r)
- return NULL;
+ ndns = 0;
+ list_for_each_entry(dns, &scfg->dnslookups, list) {
+ scfg->gcbs[ndns++] = &dns->gcb;
+ dns->pending = true;
+ }
- memcpy(r, SYSTEMD_DBUS_PATH_PREFIX, STRLEN(SYSTEMD_DBUS_PATH_PREFIX));
- d = r + STRLEN(SYSTEMD_DBUS_PATH_PREFIX);
+ r = getaddrinfo_a(GAI_NOWAIT, scfg->gcbs, ndns, &scfg->dns_sev);
+ if (r != 0) {
+ error("getaddrinfo_a(%u): %s", ndns, gai_strerror(r));
+ /* FIXME: More error handling */
+ }
- for (s = service; *s; s++) {
- if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
- (*s >= '0' && *s <= '9')) {
- *(d++) = *s;
- continue;
+ return true;
+}
+
+static void scfg_queue_dns(struct server_config *scfg, struct cfg_value *value,
+ struct list_head *target_list)
+{
+ struct saddr *saddr, *tmp;
+ struct dns_async *dns;
+
+ switch (value->type) {
+ case CFG_VAL_TYPE_ADDRS:
+ debug(DBG_DNS, "got sync results");
+ list_for_each_entry_safe(saddr, tmp, &value->saddrs, list) {
+ list_del(&saddr->list);
+ list_add(&saddr->list, target_list);
}
+ break;
- *(d++) = '_';
- *(d++) = tohex(*s >> 4);
- *(d++) = tohex(*s);
- }
+ case CFG_VAL_TYPE_ASYNC_ADDRS:
+ dns = value->dns_async;
+ debug(DBG_DNS, "enqueing async lookup of %s:%s (%p)",
+ dns->name, dns->port, dns);
+ dns->target_list = target_list;
+ list_add(&dns->list, &scfg->dnslookups);
+ break;
- *d = '\0';
- return r;
+ default:
+ error("Unexpected value type");
+ break;
+ }
}
#define ERROR(msg) do { *error = (msg); return false; } while (0)
@@ -255,65 +267,53 @@ bool scfg_validate(struct server_config *scfg, const char **error)
return true;
}
-bool scfg_async_dns_start(struct server_config *scfg)
+static inline char tohex(uint8_t val)
{
- struct dns_async *dns;
- unsigned ndns = 0;
- int r;
-
- assert_return(scfg, false);
-
- list_for_each_entry(dns, &scfg->dnslookups, list)
- ndns++;
+ static const char hex[] = "0123456789abcdef";
- scfg->gcbs = zmalloc(sizeof(struct gaicb) * ndns);
- if (!scfg->gcbs) {
- error("failed to allocate gcbs: %m");
- return false;
- }
+ return hex[val & 0x0f];
+}
- ndns = 0;
- list_for_each_entry(dns, &scfg->dnslookups, list) {
- scfg->gcbs[ndns++] = &dns->gcb;
- dns->pending = true;
- }
+/*
+ * Creates an escaped D-Bus object path for a given systemd service
+ *
+ * Escaping rules are documented here:
+ * https://dbus.freedesktop.org/doc/dbus-specification.html
+ *
+ * Essentially, everyting but a-z, A-Z, 0-9 is replaced by _xx where xx is
+ * the hexadecimal value of the character.
+ *
+ * Example: minecraft@world1.service -> minecraft_40world1_2eservice
+ */
+static char *systemd_object_path(const char *service)
+{
+ char *r;
+ char *d;
+ const char *s;
- r = getaddrinfo_a(GAI_NOWAIT, scfg->gcbs, ndns, &scfg->dns_sev);
- if (r != 0) {
- error("getaddrinfo_a(%u): %s", ndns, gai_strerror(r));
- /* FIXME: More error handling */
- }
+ assert_return(service && !empty_str(service), NULL);
- return true;
-}
+ r = zmalloc(STRLEN(SYSTEMD_DBUS_PATH_PREFIX) + strlen(service) * 3 + 1);
+ if (!r)
+ return NULL;
-static void scfg_handle_dns(struct server_config *scfg, struct cfg_value *value,
- struct list_head *target_list)
-{
- struct saddr *saddr, *tmp;
- struct dns_async *dns;
+ memcpy(r, SYSTEMD_DBUS_PATH_PREFIX, STRLEN(SYSTEMD_DBUS_PATH_PREFIX));
+ d = r + STRLEN(SYSTEMD_DBUS_PATH_PREFIX);
- switch (value->type) {
- case CFG_VAL_TYPE_ADDRS:
- debug(DBG_DNS, "got sync results");
- list_for_each_entry_safe(saddr, tmp, &value->saddrs, list) {
- list_del(&saddr->list);
- list_add(&saddr->list, target_list);
+ for (s = service; *s; s++) {
+ if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
+ (*s >= '0' && *s <= '9')) {
+ *(d++) = *s;
+ continue;
}
- break;
-
- case CFG_VAL_TYPE_ASYNC_ADDRS:
- dns = value->dns_async;
- debug(DBG_DNS, "enqueing async lookup of %s:%s (%p)",
- dns->name, dns->port, dns);
- dns->target_list = target_list;
- list_add(&dns->list, &scfg->dnslookups);
- break;
- default:
- error("Unexpected value type");
- break;
+ *(d++) = '_';
+ *(d++) = tohex(*s >> 4);
+ *(d++) = tohex(*s);
}
+
+ *d = '\0';
+ return r;
}
bool scfg_parse(struct server_config *scfg, char *buf, bool async,
@@ -373,11 +373,11 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async,
break;
case SCFG_KEY_LOCAL:
- scfg_handle_dns(scfg, &value, &scfg->locals);
+ scfg_queue_dns(scfg, &value, &scfg->locals);
break;
case SCFG_KEY_REMOTE:
- scfg_handle_dns(scfg, &value, &scfg->remotes);
+ scfg_queue_dns(scfg, &value, &scfg->remotes);
break;
case SCFG_KEY_IDLE_TIMEOUT:
@@ -426,7 +426,7 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async,
break;
case SCFG_KEY_RCON:
- scfg_handle_dns(scfg, &value, &scfg->rcons);
+ scfg_queue_dns(scfg, &value, &scfg->rcons);
break;
case SCFG_KEY_RCON_PASSWORD:
@@ -485,8 +485,7 @@ void scfg_delete(struct server_config *scfg)
xfree(scfg->pretty_name);
xfree(scfg->stop_exec);
xfree(scfg->start_exec);
- /* FIXME: use free_password */
- xfree(scfg->rcon_password);
+ free_password(&scfg->rcon_password);
xfree(scfg->systemd_service);
xfree(scfg->systemd_obj);
@@ -606,9 +605,9 @@ static char *get_line(char **pos, unsigned *lineno)
return begin;
}
-/* FIXME: we should gather these up and do all in one go */
-static bool cfg_dnslookup(const char *name, uint16_t port, struct cfg_value *rvalue,
- unsigned *naddrs, bool async)
+static bool cfg_dns_lookup(const char *name, uint16_t port,
+ struct cfg_value *rvalue,
+ unsigned *naddrs, bool async)
{
struct dns_async tmp;
struct dns_async *dns;
@@ -616,8 +615,7 @@ static bool cfg_dnslookup(const char *name, uint16_t port, struct cfg_value *rva
int r;
assert_return(!empty_str(name) && strlen(name) < sizeof(dns->name) &&
- port > 0 && rvalue,
- false);
+ port > 0 && rvalue, false);
if (async) {
rvalue->type = CFG_VAL_TYPE_ASYNC_ADDRS;
@@ -757,7 +755,7 @@ bool strtosockaddrs(const char *str, struct cfg_value *rvalue, bool async)
xfree(saddr);
debug(DBG_CFG, "maybe got a hostname:port (%s:%" PRIu16 ")",
str, port);
- if (!cfg_dnslookup(str, port, rvalue, &naddrs, async))
+ if (!cfg_dns_lookup(str, port, rvalue, &naddrs, async))
goto error;
} else if (strtou16_strict(tmp, &port) == 0) {
@@ -974,7 +972,7 @@ bool config_parse_header(const char *title, char **buf, unsigned *lineno)
return false;
}
-bool is_valid_server_config_filename(struct dirent *dent, const char *filename)
+bool config_valid_server_filename(struct dirent *dent, const char *filename)
{
const char *suffix;
diff --git a/shared/config-parser.h b/shared/config-parser.h
index d84f9fe..e1d73d2 100644
--- a/shared/config-parser.h
+++ b/shared/config-parser.h
@@ -84,12 +84,12 @@ struct cfg_value {
};
};
-void scfg_async_dns_result(struct server_config *scfg);
-
-bool scfg_validate(struct server_config *scfg, const char **error);
+void scfg_async_dns_update(struct server_config *scfg);
bool scfg_async_dns_start(struct server_config *scfg);
+bool scfg_validate(struct server_config *scfg, const char **error);
+
bool scfg_parse(struct server_config *scfg, char *buf, bool async,
unsigned *lineno, const char **error);
@@ -106,6 +106,6 @@ bool config_parse_line(const char *filename, char **buf,
bool config_parse_header(const char *title, char **buf, unsigned *lineno);
-bool is_valid_server_config_filename(struct dirent *dent, const char *filename);
+bool config_valid_server_filename(struct dirent *dent, const char *filename);
#endif
diff --git a/shared/utils.c b/shared/utils.c
index 13cacac..b870716 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -36,6 +36,16 @@ void enable_colors()
ansi_normal = ANSI_NORMAL;
}
+void free_password(char **password)
+{
+ if (!password || !*password)
+ return;
+
+ explicit_bzero(*password, strlen(*password));
+ xfree(*password);
+ *password = NULL;
+}
+
void socket_set_low_latency(int sfd, bool keepalive, bool iptos, bool nodelay)
{
int option;
diff --git a/shared/utils.h b/shared/utils.h
index f5af292..36c642c 100644
--- a/shared/utils.h
+++ b/shared/utils.h
@@ -68,6 +68,8 @@ struct saddr {
void enable_colors();
+void free_password(char **password);
+
void socket_set_low_latency(int sfd, bool keepalive, bool iptos, bool nodelay);
char *saddr_addr(struct saddr *saddr, char *buf, size_t len);