summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2021-06-06 19:58:48 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2021-06-06 21:13:15 +0100
commit9d783bb9f39bca59e720d0c543499b372c412441 (patch)
tree2b399a4fbff5f66445397a8f4bb63dba62b79765 /src
parent936fcb6fc957910826dc7f2fc349cdc0c3a456d6 (diff)
Observability: listen queue backlog
Diffstat (limited to 'src')
-rw-r--r--src/src/daemon.c40
-rw-r--r--src/src/globals.c2
-rw-r--r--src/src/globals.h2
-rw-r--r--src/src/readconf.c1
4 files changed, 38 insertions, 7 deletions
diff --git a/src/src/daemon.c b/src/src/daemon.c
index 626b43538..2d8b223c4 100644
--- a/src/src/daemon.c
+++ b/src/src/daemon.c
@@ -396,12 +396,18 @@ if (pid == 0)
int save_debug_selector = debug_selector;
BOOL local_queue_only;
BOOL session_local_queue_only;
- #ifdef SA_NOCLDWAIT
+#ifdef SA_NOCLDWAIT
struct sigaction act;
- #endif
+#endif
smtp_accept_count++; /* So that it includes this process */
+ /* If the listen backlog was over the monitoring level, log it. */
+
+ if (smtp_listen_backlog > smtp_backlog_monitor)
+ log_write(0, LOG_MAIN, "listen backlog %d I=[%s]:%d",
+ smtp_listen_backlog, interface_address, interface_port);
+
/* May have been modified for the subprocess */
*log_selector = save_log_selector;
@@ -685,6 +691,7 @@ if (pid == 0)
(void)fclose(smtp_in);
(void)close(fileno(smtp_out));
(void)fclose(smtp_out);
+ smtp_in = smtp_out = NULL;
/* Don't ever molest the parent's SSL connection, but do clean up
the data structures if necessary. */
@@ -2493,12 +2500,31 @@ for (;;)
}
while (check_lsk < listen_socket_count)
{
- int sk = check_lsk++;
- if (FD_ISSET(listen_sockets[sk], &fds))
+ int lfd = listen_sockets[check_lsk++];
+ if (FD_ISSET(lfd, &fds))
{
- EXIM_SOCKLEN_T len = sizeof(accepted);
- accept_socket = accept(listen_sockets[sk],
- (struct sockaddr *)&accepted, &len);
+ EXIM_SOCKLEN_T alen = sizeof(accepted);
+ struct tcp_info ti;
+ socklen_t tlen = sizeof(ti);
+
+ /* If monitoring the backlog is wanted, grab for later logging */
+
+ smtp_listen_backlog = 0;
+#if defined(TCP_INFO)
+ if ( smtp_backlog_monitor > 0
+ && getsockopt(lfd, IPPROTO_TCP, TCP_INFO, &ti, &tlen) == 0)
+ {
+ DEBUG(D_interface) debug_printf("listen fd %d queue max %u curr %u\n",
+# ifdef EXIM_HAVE_TCPI_UNACKED
+ lfd, ti.tcpi_sacked, ti.tcpi_unacked);
+ smtp_listen_backlog = ti.tcpi_unacked;
+# elif defined(__FreeBSD__) /* This does not work. Investigate kernel sourcecode. */
+ lfd, ti.__tcpi_sacked, ti.__tcpi_unacked);
+ smtp_listen_backlog = ti.__tcpi_unacked;
+# endif
+ }
+#endif
+ accept_socket = accept(lfd, (struct sockaddr *)&accepted, &alen);
break;
}
}
diff --git a/src/src/globals.c b/src/src/globals.c
index e1837b67d..ef7063ddd 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1471,6 +1471,7 @@ int smtp_accept_queue = 0;
int smtp_accept_queue_per_connection = 10;
int smtp_accept_reserve = 0;
uschar *smtp_active_hostname = NULL;
+int smtp_backlog_monitor = 0;
uschar *smtp_banner = US"$smtp_active_hostname ESMTP "
"Exim $version_number $tod_full"
"\0<---------------Space to patch smtp_banner->";
@@ -1483,6 +1484,7 @@ int smtp_connect_backlog = 20;
double smtp_delay_mail = 0.0;
double smtp_delay_rcpt = 0.0;
FILE *smtp_in = NULL;
+int smtp_listen_backlog = 0;
int smtp_load_reserve = -1;
int smtp_mailcmd_count = 0;
FILE *smtp_out = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index 4beb9d07e..c7a2635af 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -945,6 +945,7 @@ extern int smtp_accept_queue; /* Queue after so many connections */
extern int smtp_accept_queue_per_connection; /* Queue after so many msgs */
extern int smtp_accept_reserve; /* Reserve these SMTP connections */
extern uschar *smtp_active_hostname; /* Hostname for this message */
+extern int smtp_backlog_monitor; /* listen backlog level to log */
extern uschar *smtp_banner; /* Banner string (to be expanded) */
extern BOOL smtp_check_spool_space; /* TRUE to check SMTP SIZE value */
extern int smtp_ch_index; /* Index in smtp_connection_had */
@@ -959,6 +960,7 @@ extern BOOL smtp_enforce_sync; /* Enforce sync rules */
extern uschar *smtp_etrn_command; /* Command to run */
extern BOOL smtp_etrn_serialize; /* Only one at once */
extern FILE *smtp_in; /* Incoming SMTP input file */
+extern int smtp_listen_backlog; /* Current listener socket backlog, if monitored */
extern int smtp_load_reserve; /* Only from reserved if load > this */
extern int smtp_mailcmd_count; /* Count of MAIL commands */
extern int smtp_max_synprot_errors;/* Max syntax/protocol errors */
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 816133329..6d7e7a19e 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -309,6 +309,7 @@ static optionlist optionlist_config[] = {
{ "smtp_accept_queue_per_connection", opt_int, {&smtp_accept_queue_per_connection} },
{ "smtp_accept_reserve", opt_int, {&smtp_accept_reserve} },
{ "smtp_active_hostname", opt_stringptr, {&raw_active_hostname} },
+ { "smtp_backlog_monitor", opt_int, {&smtp_backlog_monitor} },
{ "smtp_banner", opt_stringptr, {&smtp_banner} },
{ "smtp_check_spool_space", opt_bool, {&smtp_check_spool_space} },
{ "smtp_connect_backlog", opt_int, {&smtp_connect_backlog} },