commit 488f72b: [Minor] Add flags to listen socket creation

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Jun 9 13:49:09 UTC 2020


Author: Vsevolod Stakhov
Date: 2020-06-09 13:47:44 +0100
URL: https://github.com/rspamd/rspamd/commit/488f72bad4fab719861b4641ff832f60729a5950

[Minor] Add flags to listen socket creation

---
 src/libserver/worker_util.c |  1 +
 src/libutil/addr.c          | 51 ++++++++++++++++++++++++++++++++++++---------
 src/libutil/addr.h          | 10 +++++++--
 src/rspamadm/lua_repl.c     |  4 +++-
 src/rspamd.c                |  6 +++---
 5 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c
index 50f81fd7b..639fc9480 100644
--- a/src/libserver/worker_util.c
+++ b/src/libserver/worker_util.c
@@ -933,6 +933,7 @@ rspamd_main_heartbeat_start (struct rspamd_worker *wrk, struct ev_loop *event_lo
 	ev_timer_start (event_loop, &wrk->hb.heartbeat_ev);
 }
 
+
 /**
  * Handles worker after fork returned zero
  * @param wrk
diff --git a/src/libutil/addr.c b/src/libutil/addr.c
index 52c0dbf97..b43f7cf03 100644
--- a/src/libutil/addr.c
+++ b/src/libutil/addr.c
@@ -1042,10 +1042,11 @@ rspamd_inet_address_connect (const rspamd_inet_addr_t *addr, gint type,
 
 int
 rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
-		gboolean async)
+							enum rspamd_inet_address_listen_opts opts,
+							gint listen_queue)
 {
 	gint fd, r;
-	gint on = 1;
+	gint on = 1, serrno;
 	const struct sockaddr *sa;
 	const char *path;
 
@@ -1053,7 +1054,8 @@ rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
 		return -1;
 	}
 
-	fd = rspamd_socket_create (addr->af, type, 0, async);
+	fd = rspamd_socket_create (addr->af, type, 0,
+			(opts & RSPAMD_INET_ADDRESS_LISTEN_ASYNC));
 	if (fd == -1) {
 		return -1;
 	}
@@ -1070,7 +1072,23 @@ rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
 		sa = &addr->u.in.addr.sa;
 	}
 
-	(void)setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint));
+#if defined(SO_REUSEADDR)
+	if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint)) == -1) {
+		msg_err ("cannot set SO_REUSEADDR on %d: %d", fd, strerror (errno));
+		goto err;
+	}
+#endif
+
+#if defined(SO_REUSEPORT)
+	if (opts & RSPAMD_INET_ADDRESS_LISTEN_REUSEPORT) {
+		on = 1;
+
+		if (setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (const void *)&on, sizeof (gint)) == -1) {
+			msg_err ("cannot set SO_REUSEPORT on %d: %d", fd, strerror (errno));
+			goto err;
+		}
+	}
+#endif
 
 #ifdef HAVE_IPV6_V6ONLY
 	if (addr->af == AF_INET6) {
@@ -1086,13 +1104,13 @@ rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
 
 	r = bind (fd, sa, addr->slen);
 	if (r == -1) {
-		if (!async || errno != EINPROGRESS) {
-			close (fd);
+		if (!(opts & RSPAMD_INET_ADDRESS_LISTEN_ASYNC) || errno != EINPROGRESS) {
 			msg_warn ("bind %s failed: %d, '%s'",
 					rspamd_inet_address_to_string_pretty (addr),
 					errno,
 					strerror (errno));
-			return -1;
+
+			goto err;
 		}
 	}
 
@@ -1115,18 +1133,31 @@ rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
 						path, addr->u.un->mode, strerror (errno));
 			}
 		}
-		r = listen (fd, -1);
+
+		r = listen (fd, listen_queue);
 
 		if (r == -1) {
 			msg_warn ("listen %s failed: %d, '%s'",
 					rspamd_inet_address_to_string_pretty (addr),
 					errno, strerror (errno));
-			close (fd);
-			return -1;
+
+			goto err;
 		}
 	}
 
 	return fd;
+
+err:
+	/* Error path */
+	serrno = errno;
+
+	if (fd != -1) {
+		close (fd);
+	}
+
+	errno = serrno;
+
+	return -1;
 }
 
 gssize
diff --git a/src/libutil/addr.h b/src/libutil/addr.h
index e17a4031c..852e43b60 100644
--- a/src/libutil/addr.h
+++ b/src/libutil/addr.h
@@ -228,15 +228,21 @@ void rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port);
 int rspamd_inet_address_connect (const rspamd_inet_addr_t *addr, gint type,
 								 gboolean async);
 
+enum rspamd_inet_address_listen_opts {
+	RSPAMD_INET_ADDRESS_LISTEN_DEFAULT = 0,
+	RSPAMD_INET_ADDRESS_LISTEN_ASYNC = (1u << 0u),
+	RSPAMD_INET_ADDRESS_LISTEN_REUSEPORT = (1u << 1u),
+};
 /**
  * Listen on a specified inet address
  * @param addr
  * @param type
- * @param async
+ * @param opts
  * @return
  */
 int rspamd_inet_address_listen (const rspamd_inet_addr_t *addr, gint type,
-								gboolean async);
+								enum rspamd_inet_address_listen_opts opts,
+								gint listen_queue);
 
 /**
  * Check whether specified ip is valid (not INADDR_ANY or INADDR_NONE) for ipv4 or ipv6
diff --git a/src/rspamadm/lua_repl.c b/src/rspamadm/lua_repl.c
index df970fd01..945b5635c 100644
--- a/src/rspamadm/lua_repl.c
+++ b/src/rspamadm/lua_repl.c
@@ -946,7 +946,9 @@ rspamadm_lua (gint argc, gchar **argv, const struct rspamadm_command *cmd)
 		for (i = 0; i < addrs->len; i ++) {
 			rspamd_inet_addr_t *addr = g_ptr_array_index (addrs, i);
 
-			fd = rspamd_inet_address_listen (addr, SOCK_STREAM, TRUE);
+			fd = rspamd_inet_address_listen (addr, SOCK_STREAM,
+					RSPAMD_INET_ADDRESS_LISTEN_ASYNC, -1);
+
 			if (fd != -1) {
 				static ev_io ev;
 
diff --git a/src/rspamd.c b/src/rspamd.c
index 5aff3078c..5748fa7ff 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -412,7 +412,7 @@ create_listen_socket (GPtrArray *addrs, guint cnt,
 		 */
 		if (listen_type & RSPAMD_WORKER_SOCKET_TCP) {
 			fd = rspamd_inet_address_listen (g_ptr_array_index (addrs, i),
-					SOCK_STREAM, TRUE);
+					SOCK_STREAM, RSPAMD_INET_ADDRESS_LISTEN_ASYNC, -1);
 			if (fd != -1) {
 				ls = g_malloc0 (sizeof (*ls));
 				ls->addr = rspamd_inet_address_copy (g_ptr_array_index (addrs, i));
@@ -423,7 +423,7 @@ create_listen_socket (GPtrArray *addrs, guint cnt,
 		}
 		if (listen_type & RSPAMD_WORKER_SOCKET_UDP) {
 			fd = rspamd_inet_address_listen (g_ptr_array_index (addrs, i),
-					SOCK_DGRAM, TRUE);
+					SOCK_DGRAM, RSPAMD_INET_ADDRESS_LISTEN_ASYNC, -1);
 			if (fd != -1) {
 				ls = g_malloc0 (sizeof (*ls));
 				ls->addr = rspamd_inet_address_copy (g_ptr_array_index (addrs, i));
@@ -1438,7 +1438,7 @@ main (gint argc, gchar **argv, gchar **env)
 		}
 		else {
 			control_fd = rspamd_inet_address_listen (control_addr, SOCK_STREAM,
-					TRUE);
+					RSPAMD_INET_ADDRESS_LISTEN_ASYNC, -1);
 			if (control_fd == -1) {
 				msg_err_main ("cannot open control socket at path: %s",
 						rspamd_main->cfg->control_socket_path);


More information about the Commits mailing list