diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2021-06-06 19:58:48 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2021-06-06 21:13:15 +0100 |
commit | 9d783bb9f39bca59e720d0c543499b372c412441 (patch) | |
tree | 2b399a4fbff5f66445397a8f4bb63dba62b79765 /src | |
parent | 936fcb6fc957910826dc7f2fc349cdc0c3a456d6 (diff) |
Observability: listen queue backlog
Diffstat (limited to 'src')
-rw-r--r-- | src/src/daemon.c | 40 | ||||
-rw-r--r-- | src/src/globals.c | 2 | ||||
-rw-r--r-- | src/src/globals.h | 2 | ||||
-rw-r--r-- | src/src/readconf.c | 1 |
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} }, |