/*************************************************
*************************************************/
+#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
+static void
+unlink_notifier_socket(void)
+{
+uschar * s = expand_string(notifier_socket);
+DEBUG(D_any) debug_printf("unlinking notifier socket %s\n", s);
+Uunlink(s);
+}
+#endif
+
+
static void
close_daemon_sockets(int daemon_notifier_fd,
int * listen_sockets, int listen_socket_count)
{
-if (daemon_notifier_fd >= 0) (void) close(daemon_notifier_fd);
+if (daemon_notifier_fd >= 0)
+ {
+ (void) close(daemon_notifier_fd);
+ daemon_notifier_fd = -1;
+#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
+ unlink_notifier_socket();
+#endif
+ }
+
for (int i = 0; i < listen_socket_count; i++) (void) close(listen_sockets[i]);
}
{
int pid;
-#ifndef DISABLE_TLS
-if (tls_watch_fd >= 0)
- { close(tls_watch_fd); tls_watch_fd = -1; }
+DEBUG(D_any) debug_printf("SIGTERM seen\n");
+#if !defined(DISABLE_TLS) && (defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT))
+tls_watch_invalidate();
#endif
if (daemon_notifier_fd >= 0)
close(daemon_notifier_fd);
daemon_notifier_fd = -1;
#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
- {
- uschar * s = expand_string(notifier_socket);
- DEBUG(D_any) debug_printf("unlinking notifier socket %s\n", s);
- Uunlink(s);
- }
+ unlink_notifier_socket();
#endif
}
list = tls_in.on_connect_ports;
sep = 0;
+ /* the list isn't expanded so cannot be tainted. If it ever is we will trap here */
while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
if (!isdigit(*s))
{
if (f.daemon_listen)
{
- int lcount, select_errno;
+ int lcount;
int max_socket = 0;
BOOL select_failed = FALSE;
fd_set select_listen;
old one had just finished. Preserve the errno from any select() failure for
the use of the common select/accept error processing below. */
- select_errno = errno;
- handle_ending_processes();
- errno = select_errno;
+ {
+ int select_errno = errno;
+ handle_ending_processes();
#ifndef DISABLE_TLS
- /* Create or rotate any required keys; handle (delayed) filewatch event */
- tls_daemon_tick();
+ /* Create or rotate any required keys; handle (delayed) filewatch event */
+ tls_daemon_tick();
#endif
+ errno = select_errno;
+ }
/* Loop for all the sockets that are currently ready to go. If select
actually failed, we have set the count to 1 and select_failed=TRUE, so as
if (!select_failed)
{
-#if defined(EXIM_HAVE_INOTIFY) && !defined(DISABLE_TLS)
+#if !defined(DISABLE_TLS) && (defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT))
if (tls_watch_fd >= 0 && FD_ISSET(tls_watch_fd, &select_listen))
{
FD_CLR(tls_watch_fd, &select_listen);
tls_watch_trigger_time = time(NULL); /* Set up delayed event */
- (void) read(tls_watch_fd, big_buffer, big_buffer_size);
+ tls_watch_discard_event(tls_watch_fd);
break; /* to top of daemon loop */
}
#endif
accept_retry_errno = errno;
accept_retry_select_failed = select_failed;
}
- else
- {
- if (errno != accept_retry_errno ||
- select_failed != accept_retry_select_failed ||
- accept_retry_count >= 50)
+ else if ( errno != accept_retry_errno
+ || select_failed != accept_retry_select_failed
+ || accept_retry_count >= 50)
{
- log_write(0, LOG_MAIN | ((accept_retry_count >= 50)? LOG_PANIC : 0),
+ log_write(0, LOG_MAIN | (accept_retry_count >= 50 ? LOG_PANIC : 0),
"%d %s() failure%s: %s",
accept_retry_count,
- accept_retry_select_failed? "select" : "accept",
- (accept_retry_count == 1)? "" : "s",
+ accept_retry_select_failed ? "select" : "accept",
+ accept_retry_count == 1 ? "" : "s",
strerror(accept_retry_errno));
log_close_all();
accept_retry_count = 0;
accept_retry_errno = errno;
accept_retry_select_failed = select_failed;
}
- }
accept_retry_count++;
}
-
- else
- {
- if (accept_retry_count > 0)
- {
- log_write(0, LOG_MAIN, "%d %s() failure%s: %s",
- accept_retry_count,
- accept_retry_select_failed? "select" : "accept",
- (accept_retry_count == 1)? "" : "s",
- strerror(accept_retry_errno));
- log_close_all();
- accept_retry_count = 0;
- }
- }
+ else if (accept_retry_count > 0)
+ {
+ log_write(0, LOG_MAIN, "%d %s() failure%s: %s",
+ accept_retry_count,
+ accept_retry_select_failed ? "select" : "accept",
+ accept_retry_count == 1 ? "" : "s",
+ strerror(accept_retry_errno));
+ log_close_all();
+ accept_retry_count = 0;
+ }
/* If select/accept succeeded, deal with the connection. */
if (accept_socket >= 0)
{
+#ifdef TCP_QUICKACK /* Avoid pure-ACKs while in tls protocol pingpong phase */
+ /* Unfortunately we cannot be certain to do this before a TLS-on-connect
+ Client Hello arrives and is acked. We do it as early as possible. */
+ (void) setsockopt(accept_socket, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
+#endif
if (inetd_wait_timeout)
last_connection_time = time(NULL);
handle_smtp_call(listen_sockets, listen_socket_count, accept_socket,