aboutsummaryrefslogtreecommitdiffstats
path: root/src/cfg_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cfg_utils.c')
-rw-r--r--src/cfg_utils.c180
1 files changed, 116 insertions, 64 deletions
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
index 282f72b7a..56310669e 100644
--- a/src/cfg_utils.c
+++ b/src/cfg_utils.c
@@ -49,11 +49,13 @@ struct rspamd_ucl_map_cbdata {
static gchar* rspamd_ucl_read_cb (memory_pool_t * pool, gchar * chunk, gint len, struct map_cb_data *data);
static void rspamd_ucl_fin_cb (memory_pool_t * pool, struct map_cb_data *data);
-gboolean
-parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority)
+static gboolean
+parse_host_port_priority_strv (memory_pool_t *pool, gchar **tokens,
+ gchar **addr, guint16 *port, guint *priority, guint default_port)
{
- gchar **tokens, *err_str, *cur_tok;
- struct addrinfo hints, *res;
+ gchar *err_str, portbuf[8];
+ const gchar *cur_tok, *cur_port;
+ struct addrinfo hints, *res;
guint port_parsed, priority_parsed, saved_errno = errno;
gint r;
union {
@@ -61,70 +63,46 @@ parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, g
struct sockaddr_in6 v6;
} addr_holder;
- tokens = g_strsplit_set (str, ":", 0);
- if (!tokens || !tokens[0]) {
- return FALSE;
- }
-
/* Now try to parse host and write address to ina */
memset (&hints, 0, sizeof (hints));
- hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Type of the socket */
- hints.ai_flags = 0;
- hints.ai_protocol = 0; /* Any protocol */
- hints.ai_canonname = NULL;
- hints.ai_addr = NULL;
- hints.ai_next = NULL;
-
- if (strcmp (tokens[0], "*") == 0) {
- /* XXX: actually we still cannot listen on multiply protocols */
- if (pool != NULL) {
- *addr = memory_pool_alloc (pool, INET_ADDRSTRLEN + 1);
- }
- rspamd_strlcpy (*addr, "0.0.0.0", INET_ADDRSTRLEN + 1);
- goto port_parse;
- }
- else {
- cur_tok = tokens[0];
- }
+ hints.ai_flags = AI_NUMERICSERV;
- if ((r = getaddrinfo (cur_tok, NULL, &hints, &res)) == 0) {
- memcpy (&addr_holder, res->ai_addr, MIN (sizeof (addr_holder), res->ai_addrlen));
- if (res->ai_family == AF_INET) {
- if (pool != NULL) {
- *addr = memory_pool_alloc (pool, INET_ADDRSTRLEN + 1);
- }
- inet_ntop (res->ai_family, &addr_holder.v4.sin_addr, *addr, INET_ADDRSTRLEN + 1);
- }
- else {
- if (pool != NULL) {
- *addr = memory_pool_alloc (pool, INET6_ADDRSTRLEN + 1);
- }
- inet_ntop (res->ai_family, &addr_holder.v6.sin6_addr, *addr, INET6_ADDRSTRLEN + 1);
- }
- freeaddrinfo (res);
+ cur_tok = tokens[0];
+
+ if (strcmp (cur_tok, "*v6") == 0) {
+ hints.ai_family = AF_INET6;
+ hints.ai_flags |= AI_PASSIVE;
+ cur_tok = NULL;
+ }
+ else if (strcmp (cur_tok, "*v4") == 0) {
+ hints.ai_family = AF_INET;
+ hints.ai_flags |= AI_PASSIVE;
+ cur_tok = NULL;
}
else {
- msg_err ("address resolution for %s failed: %s", tokens[0], gai_strerror (r));
- goto err;
+ hints.ai_family = AF_UNSPEC;
}
-port_parse:
if (tokens[1] != NULL) {
/* Port part */
+ rspamd_strlcpy (portbuf, tokens[1], sizeof (portbuf));
+ cur_port = portbuf;
if (port != NULL) {
errno = 0;
port_parsed = strtoul (tokens[1], &err_str, 10);
if (*err_str != '\0' || errno != 0) {
msg_warn ("cannot parse port: %s, at symbol %c, error: %s", tokens[1], *err_str, strerror (errno));
- goto err;
+ hints.ai_flags ^= AI_NUMERICSERV;
}
- if (port_parsed > G_MAXUINT16) {
+ else if (port_parsed > G_MAXUINT16) {
errno = ERANGE;
msg_warn ("cannot parse port: %s, error: %s", tokens[1], *err_str, strerror (errno));
- goto err;
+ hints.ai_flags ^= AI_NUMERICSERV;
+ }
+ else {
+ *port = port_parsed;
}
- *port = port_parsed;
}
if (priority != NULL) {
if (port != NULL) {
@@ -139,25 +117,70 @@ port_parse:
priority_parsed = strtoul (cur_tok, &err_str, 10);
if (*err_str != '\0' || errno != 0) {
msg_warn ("cannot parse priority: %s, at symbol %c, error: %s", tokens[1], *err_str, strerror (errno));
- goto err;
}
- *priority = priority_parsed;
+ else {
+ *priority = priority_parsed;
+ }
}
}
}
-
+ else if (default_port != 0) {
+ rspamd_snprintf (portbuf, sizeof (portbuf), "%u", default_port);
+ cur_port = portbuf;
+ }
+ else {
+ cur_port = NULL;
+ }
+
+ if ((r = getaddrinfo (cur_tok, cur_port, &hints, &res)) == 0) {
+ memcpy (&addr_holder, res->ai_addr, MIN (sizeof (addr_holder), res->ai_addrlen));
+ if (res->ai_family == AF_INET) {
+ if (pool != NULL) {
+ *addr = memory_pool_alloc (pool, INET_ADDRSTRLEN + 1);
+ }
+ inet_ntop (res->ai_family, &addr_holder.v4.sin_addr, *addr, INET_ADDRSTRLEN + 1);
+ }
+ else {
+ if (pool != NULL) {
+ *addr = memory_pool_alloc (pool, INET6_ADDRSTRLEN + 1);
+ }
+ inet_ntop (res->ai_family, &addr_holder.v6.sin6_addr, *addr, INET6_ADDRSTRLEN + 1);
+ }
+ freeaddrinfo (res);
+ }
+ else {
+ msg_err ("address resolution for %s failed: %s", tokens[0], gai_strerror (r));
+ goto err;
+ }
+
/* Restore errno */
errno = saved_errno;
- g_strfreev (tokens);
return TRUE;
err:
errno = saved_errno;
- g_strfreev (tokens);
return FALSE;
}
gboolean
+parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority)
+{
+ gchar **tokens;
+ gboolean ret;
+
+ tokens = g_strsplit_set (str, ":", 0);
+ if (!tokens || !tokens[0]) {
+ return FALSE;
+ }
+
+ ret = parse_host_port_priority_strv (pool, tokens, addr, port, priority, 0);
+
+ g_strfreev (tokens);
+
+ return ret;
+}
+
+gboolean
parse_host_port (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port)
{
return parse_host_port_priority (pool, str, addr, port, NULL);
@@ -173,28 +196,58 @@ gboolean
parse_bind_line (struct config_file *cfg, struct worker_conf *cf, const gchar *str)
{
struct rspamd_worker_bind_conf *cnf;
+ gchar **tokens, *tmp;
+ gboolean ret;
- if (str == NULL)
- return 0;
+ if (str == NULL) {
+ return FALSE;
+ }
+
+ tokens = g_strsplit_set (str, ":", 0);
+ if (!tokens || !tokens[0]) {
+ return FALSE;
+ }
cnf = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_worker_bind_conf));
cnf->bind_port = DEFAULT_BIND_PORT;
+ cnf->bind_host = memory_pool_strdup (cfg->cfg_pool, str);
+ cnf->ai = AF_UNSPEC;
- if (str[0] == '/' || str[0] == '.') {
- cnf->bind_host = memory_pool_strdup (cfg->cfg_pool, str);
- cnf->is_unix = TRUE;
+ if (*tokens[0] == '/' || *tokens[0] == '.') {
+ cnf->ai = AF_UNIX;
LL_PREPEND (cf->bind_conf, cnf);
return TRUE;
}
- else {
+ else if (strcmp (tokens[0], "*") == 0) {
+ /* We need to add two listen entries: one for ipv4 and one for ipv6 */
+ tmp = tokens[0];
+ tokens[0] = "*v4";
+ cnf->ai = AF_INET;
+ if ((ret = parse_host_port_priority_strv (cfg->cfg_pool, tokens,
+ &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
+ LL_PREPEND (cf->bind_conf, cnf);
+ }
+ cnf = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_worker_bind_conf));
+ cnf->bind_port = DEFAULT_BIND_PORT;
cnf->bind_host = memory_pool_strdup (cfg->cfg_pool, str);
- if (parse_host_port (cfg->cfg_pool, str, &cnf->bind_host, &cnf->bind_port)) {
+ cnf->ai = AF_INET6;
+ tokens[0] = "*v6";
+ if ((ret &= parse_host_port_priority_strv (cfg->cfg_pool, tokens,
+ &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
+ LL_PREPEND (cf->bind_conf, cnf);
+ }
+ tokens[0] = tmp;
+ }
+ else {
+ if ((ret = parse_host_port_priority_strv (cfg->cfg_pool, tokens,
+ &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
LL_PREPEND (cf->bind_conf, cnf);
- return TRUE;
}
}
- return FALSE;
+ g_strfreev (tokens);
+
+ return ret;
}
void
@@ -220,7 +273,6 @@ init_defaults (struct config_file *cfg)
/* 20 Kb */
cfg->max_diff = 20480;
- cfg->max_statfile_size = DEFAULT_STATFILE_SIZE;
cfg->metrics = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
cfg->c_modules = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
cfg->composite_symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);