commit 80bb541: [Fix] Fix listen socket parsing

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Feb 25 19:42:08 UTC 2020


Author: Vsevolod Stakhov
Date: 2020-02-25 19:40:16 +0000
URL: https://github.com/rspamd/rspamd/commit/80bb5413db189bee40e39b6572110af565339e03 (HEAD -> master)

[Fix] Fix listen socket parsing
Issue: #3254

---
 src/libserver/cfg_utils.c |  2 +-
 src/libutil/addr.c        | 59 +++++++++++++++++++++++++++++++++++++++++------
 src/libutil/addr.h        |  4 +++-
 src/libutil/upstream.c    |  1 +
 src/rspamadm/lua_repl.c   |  2 +-
 5 files changed, 58 insertions(+), 10 deletions(-)

diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 6a076e673..9a308a8a4 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -129,7 +129,7 @@ rspamd_parse_bind_line (struct rspamd_config *cfg,
 	}
 	else {
 		if (rspamd_parse_host_port_priority (str, &cnf->addrs,
-				NULL, &cnf->name, DEFAULT_BIND_PORT, NULL) == RSPAMD_PARSE_ADDR_FAIL) {
+				NULL, &cnf->name, DEFAULT_BIND_PORT, TRUE, NULL) == RSPAMD_PARSE_ADDR_FAIL) {
 			msg_err_config ("cannot parse bind line: %s", str);
 			ret = FALSE;
 		}
diff --git a/src/libutil/addr.c b/src/libutil/addr.c
index 1beeb421e..52c0dbf97 100644
--- a/src/libutil/addr.c
+++ b/src/libutil/addr.c
@@ -1345,6 +1345,7 @@ rspamd_parse_host_port_priority (const gchar *str,
 								 guint *priority,
 								 gchar **name_ptr,
 								 guint default_port,
+								 gboolean allow_listen,
 								 rspamd_mempool_t *pool)
 {
 	gchar portbuf[8];
@@ -1352,6 +1353,7 @@ rspamd_parse_host_port_priority (const gchar *str,
 	gsize namelen;
 	rspamd_inet_addr_t *cur_addr = NULL;
 	enum rspamd_parse_host_port_result ret = RSPAMD_PARSE_ADDR_FAIL;
+	union sa_union su;
 
 	/*
 	 * In this function, we can have several possibilities:
@@ -1361,19 +1363,62 @@ rspamd_parse_host_port_priority (const gchar *str,
 	 * 4) ip|host[:port[:priority]]
 	 */
 
-	if (str[0] == '*') {
-		if (!rspamd_check_port_priority (str + 1, default_port, priority,
+	if (allow_listen && str[0] == '*') {
+		bool v4_any = true, v6_any = true;
+
+		p = &str[1];
+
+		if (g_ascii_strncasecmp (p, "v4", 2) == 0) {
+			p += 2;
+			name = "*v4";
+			v6_any = false;
+		}
+		else if (g_ascii_strncasecmp (p, "v6", 2) == 0) {
+			p += 2;
+			name = "*v6";
+			v4_any = false;
+		}
+		else {
+			name = "*";
+		}
+
+		if (!rspamd_check_port_priority (p, default_port, priority,
 				portbuf, sizeof (portbuf), pool)) {
 			return ret;
 		}
 
-		if (rspamd_resolve_addrs (str, 0, addrs, portbuf, AI_PASSIVE, pool)
-				== RSPAMD_PARSE_ADDR_FAIL) {
-			return ret;
+		if (*addrs == NULL) {
+			*addrs = g_ptr_array_new_full (1,
+					(GDestroyNotify) rspamd_inet_address_free);
+
+			if (pool != NULL) {
+				rspamd_mempool_add_destructor (pool,
+						rspamd_ptr_array_free_hard, *addrs);
+			}
+		}
+
+		if (v4_any) {
+			cur_addr = rspamd_inet_addr_create (AF_INET, pool);
+			rspamd_parse_inet_address_ip4 ("0.0.0.0",
+					sizeof ("0.0.0.0") - 1, &su.s4.sin_addr);
+			memcpy (&cur_addr->u.in.addr.s4.sin_addr, &su.s4.sin_addr,
+					sizeof (struct in_addr));
+			rspamd_inet_address_set_port (cur_addr,
+					strtoul (portbuf, NULL, 10));
+			g_ptr_array_add (*addrs, cur_addr);
+		}
+		if (v6_any) {
+			cur_addr = rspamd_inet_addr_create (AF_INET6, pool);
+			rspamd_parse_inet_address_ip6 ("::",
+					sizeof ("::") - 1, &su.s6.sin6_addr);
+			memcpy (&cur_addr->u.in.addr.s6.sin6_addr, &su.s6.sin6_addr,
+					sizeof (struct in6_addr));
+			rspamd_inet_address_set_port (cur_addr,
+					strtoul (portbuf, NULL, 10));
+			g_ptr_array_add (*addrs, cur_addr);
 		}
 
-		name = "*";
-		namelen = 1;
+		namelen = strlen (name);
 		ret = RSPAMD_PARSE_ADDR_NUMERIC; /* No resolution here */
 	}
 	else if (str[0] == '[') {
diff --git a/src/libutil/addr.h b/src/libutil/addr.h
index c0910ad03..e17a4031c 100644
--- a/src/libutil/addr.h
+++ b/src/libutil/addr.h
@@ -274,7 +274,9 @@ enum rspamd_parse_host_port_result {
 enum rspamd_parse_host_port_result
 rspamd_parse_host_port_priority (const gchar *str,
 								 GPtrArray **addrs,
-								 guint *priority, gchar **name, guint default_port,
+								 guint *priority, gchar **name,
+								 guint default_port,
+								 gboolean allow_listen,
 								 rspamd_mempool_t *pool);
 
 /**
diff --git a/src/libutil/upstream.c b/src/libutil/upstream.c
index 196d9cde8..65cbca105 100644
--- a/src/libutil/upstream.c
+++ b/src/libutil/upstream.c
@@ -1049,6 +1049,7 @@ rspamd_upstreams_add_upstream (struct upstream_list *ups, const gchar *str,
 			ret = rspamd_parse_host_port_priority (str, &addrs,
 					&upstream->weight,
 					&upstream->name, def_port,
+					FALSE,
 					ups->ctx ? ups->ctx->pool : NULL);
 		}
 		break;
diff --git a/src/rspamadm/lua_repl.c b/src/rspamadm/lua_repl.c
index 31e06626e..df970fd01 100644
--- a/src/rspamadm/lua_repl.c
+++ b/src/rspamadm/lua_repl.c
@@ -925,7 +925,7 @@ rspamadm_lua (gint argc, gchar **argv, const struct rspamadm_command *cmd)
 		struct rspamadm_lua_repl_context *ctx;
 
 		if (rspamd_parse_host_port_priority (serve, &addrs, NULL, &name,
-				10000, NULL) == RSPAMD_PARSE_ADDR_FAIL) {
+				10000, TRUE, NULL) == RSPAMD_PARSE_ADDR_FAIL) {
 			fprintf (stderr, "cannot listen on %s", serve);
 			exit (EXIT_FAILURE);
 		}


More information about the Commits mailing list