aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2020-06-09 13:47:44 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2020-06-09 13:47:44 +0100
commit488f72bad4fab719861b4641ff832f60729a5950 (patch)
treeefb6714cb551c7611dffe0f25116cbab20b36a78
parent4f69d50e5ef648c09b042d9bbca9a1b9106288b2 (diff)
downloadrspamd-488f72bad4fab719861b4641ff832f60729a5950.tar.gz
rspamd-488f72bad4fab719861b4641ff832f60729a5950.zip
[Minor] Add flags to listen socket creation
-rw-r--r--src/libserver/worker_util.c1
-rw-r--r--src/libutil/addr.c51
-rw-r--r--src/libutil/addr.h10
-rw-r--r--src/rspamadm/lua_repl.c4
-rw-r--r--src/rspamd.c6
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);