X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/1e835086d1592bdfbcd8577133965b78470840ac..107077d7fd6736711bf5cd980221723401d37c51:/src/src/daemon.c diff --git a/src/src/daemon.c b/src/src/daemon.c index b0533c28f..9709845e5 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -2,8 +2,8 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2020 - 2022 */ -/* Copyright (c) University of Cambridge 1995 - 2023 */ +/* Copyright (c) The Exim Maintainers 2020 - 2023 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -181,7 +181,7 @@ Returns: nothing */ static void -handle_smtp_call(struct pollfd *fd_polls, int listen_socket_count, +handle_smtp_call(struct pollfd * fd_polls, int listen_socket_count, int accept_socket, struct sockaddr *accepted) { pid_t pid; @@ -254,8 +254,6 @@ if (LOGGING(incoming_interface)) whofrom = string_fmt_append(whofrom, " I=[%s]:%d", interface_address, interface_port); -(void) string_from_gstring(whofrom); /* Terminate the newly-built string */ - /* Check maximum number of connections. We do not check for reserved connections or unacceptable hosts here. That is done in the subprocess because it might take some time. */ @@ -267,8 +265,8 @@ if (smtp_accept_max > 0 && smtp_accept_count >= smtp_accept_max) smtp_printf("421 Too many concurrent SMTP connections; " "please try again later.\r\n", FALSE); log_write(L_connection_reject, - LOG_MAIN, "Connection from %s refused: too many connections", - whofrom->s); + LOG_MAIN, "Connection from %Y refused: too many connections", + whofrom); goto ERROR_RETURN; } @@ -286,8 +284,8 @@ if (smtp_load_reserve >= 0) (double)load_average/1000.0); smtp_printf("421 Too much load; please try again later.\r\n", FALSE); log_write(L_connection_reject, - LOG_MAIN, "Connection from %s refused: load average = %.2f", - whofrom->s, (double)load_average/1000.0); + LOG_MAIN, "Connection from %Y refused: load average = %.2f", + whofrom, (double)load_average/1000.0); goto ERROR_RETURN; } } @@ -307,7 +305,7 @@ if (smtp_accept_max_per_host) { if (!f.expand_string_forcedfail) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host " - "failed for %s: %s", whofrom->s, expand_string_message); + "failed for %Y: %s", whofrom, expand_string_message); } /* For speed, interpret a decimal number inline here */ else @@ -317,7 +315,7 @@ if (smtp_accept_max_per_host) max_for_this_host = max_for_this_host * 10 + *s++ - '0'; if (*s) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host " - "for %s contains non-digit: %s", whofrom->s, expanded); + "for %Y contains non-digit: %s", whofrom, expanded); } } @@ -355,38 +353,15 @@ if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host) smtp_printf("421 Too many concurrent SMTP connections " "from this IP address; please try again later.\r\n", FALSE); log_write(L_connection_reject, - LOG_MAIN, "Connection from %s refused: too many connections " - "from that IP address", whofrom->s); + LOG_MAIN, "Connection from %Y refused: too many connections " + "from that IP address", whofrom); search_tidyup(); goto ERROR_RETURN; } } -/* OK, the connection count checks have been passed. Before we can fork the -accepting process, we must first log the connection if requested. This logging -used to happen in the subprocess, but doing that means that the value of -smtp_accept_count can be out of step by the time it is logged. So we have to do -the logging here and accept the performance cost. Note that smtp_accept_count -hasn't yet been incremented to take account of this connection. - -In order to minimize the cost (because this is going to happen for every -connection), do a preliminary selector test here. This saves ploughing through -the generalized logging code each time when the selector is false. If the -selector is set, check whether the host is on the list for logging. If not, -arrange to unset the selector in the subprocess. */ - -if (LOGGING(smtp_connection)) - { - uschar *list = hosts_connection_nolog; - memset(sender_host_cache, 0, sizeof(sender_host_cache)); - if (list && verify_check_host(&list) == OK) - save_log_selector &= ~L_smtp_connection; - else - log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %s " - "(TCP/IP connection count = %d)", whofrom->s, smtp_accept_count + 1); - } - -/* Now we can fork the accepting process; do a lookup tidy, just in case any +/* OK, the connection count checks have been passed. +Now we can fork the accepting process; do a lookup tidy, just in case any expansion above did a lookup. */ search_tidyup(); @@ -406,6 +381,33 @@ if (pid == 0) #endif smtp_accept_count++; /* So that it includes this process */ + connection_id = getpid(); + + /* Log the connection if requested. + In order to minimize the cost (because this is going to happen for every + connection), do a preliminary selector test here. This saves ploughing through + the generalized logging code each time when the selector is false. If the + selector is set, check whether the host is on the list for logging. If not, + arrange to unset the selector in the subprocess. + + jgh 2023/08/08 :- moved this logging in from the parent process, just + pre-fork. There was a claim back from 2004 that smtp_accept_count could have + become out-of-date by the time the child could log it, and I can't see how + that could happen. */ + + if (LOGGING(smtp_connection)) + { + uschar * list = hosts_connection_nolog; + memset(sender_host_cache, 0, sizeof(sender_host_cache)); + if (list && verify_check_host(&list) == OK) + save_log_selector &= ~L_smtp_connection; + else if (LOGGING(connection_id)) + log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %Y " + "Ci=%lu (TCP/IP connection count = %d)", whofrom, connection_id, smtp_accept_count); + else + log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %Y " + "(TCP/IP connection count = %d)", whofrom, smtp_accept_count); + } /* If the listen backlog was over the monitoring level, log it. */ @@ -564,7 +566,7 @@ if (pid == 0) smtp_log_no_mail(); /* Log no mail if configured */ exim_underbar_exit(EXIT_SUCCESS); } - if (message_id[0] == 0) continue; /* No message was accepted */ + if (!message_id[0]) continue; /* No message was accepted */ } else /* bad smtp_setup_msg() */ { @@ -1344,7 +1346,10 @@ switch (buf[0]) memcpy(queuerun_msgid, buf+1, MESSAGE_ID_LENGTH+1); for (qrunner * q = qrunners; q; q = q->next) - if (Ustrcmp(q->name, buf+1+MESSAGE_ID_LENGTH+1) == 0) + if (q->name + ? Ustrcmp(q->name, buf+1+MESSAGE_ID_LENGTH+1) == 0 + : !buf[1+MESSAGE_ID_LENGTH+1] + ) { queuerun_msg_qname = q->name; break; } return TRUE; #endif @@ -1688,7 +1693,6 @@ int listen_socket_count = 0, poll_fd_count; ip_address_item * addresses = NULL; time_t last_connection_time = (time_t)0; int local_queue_run_max = 0; -BOOL queue_run_max_has_dollar; if (is_multiple_qrun())