X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fdaemon.c;h=2efaeba95aab273ef6f5f49e17cbdddb4ed8bc59;hb=fb05276aaee4c27b6f20fb1f32290ee40a929064;hp=b73f76fcf1ddb2ad5c0b7a09fd0c70feabd802b5;hpb=9094b84b4cce2eb862394b752eda93124d96d655;p=exim.git diff --git a/src/src/daemon.c b/src/src/daemon.c index b73f76fcf..2efaeba95 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -523,9 +523,17 @@ if (pid == 0) } else { + int i; + uschar * buf[128]; mac_smtp_fflush(); + /* drain socket, for clean TCP FINs */ + for(i = 16; read(fileno(smtp_in), buf, sizeof(buf)) > 0 && i > 0; ) i--; search_tidyup(); smtp_log_no_mail(); /* Log no mail if configured */ + + /*XXX should we pause briefly, hoping that the client will be the + active TCP closer hence get the TCP_WAIT endpoint? */ + DEBUG(D_receive) debug_printf("SMTP>>(close on process exit)\n"); _exit((rc == 0)? EXIT_SUCCESS : EXIT_FAILURE); } @@ -651,8 +659,8 @@ if (pid == 0) if (geteuid() != root_uid && !deliver_drop_privilege) { signal(SIGALRM, SIG_DFL); - (void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, FALSE, 2, US"-Mc", - message_id); + (void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, FALSE, + 2, US"-Mc", message_id); /* Control does not return here. */ } @@ -866,10 +874,10 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) /* If it wasn't an accepting process, see if it was a queue-runner process that we are tracking. */ - if (queue_pid_slots != NULL) + if (queue_pid_slots) { - for (i = 0; i < queue_run_max; i++) - { + int max = atoi(CS expand_string(queue_run_max)); + for (i = 0; i < max; i++) if (queue_pid_slots[i] == pid) { queue_pid_slots[i] = 0; @@ -878,7 +886,6 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) queue_run_count, (queue_run_count == 1)? "" : "es"); break; } - } } } } @@ -916,6 +923,7 @@ int *listen_sockets = NULL; int listen_socket_count = 0; ip_address_item *addresses = NULL; time_t last_connection_time = (time_t)0; +int local_queue_run_max = atoi(CS expand_string(queue_run_max)); /* If any debugging options are set, turn on the D_pid bit so that all debugging lines get the pid added. */ @@ -924,8 +932,6 @@ DEBUG(D_any|D_v) debug_selector |= D_pid; if (inetd_wait_mode) { - int on = 1; - listen_socket_count = 1; listen_sockets = store_get(sizeof(int)); (void) close(3); @@ -1098,11 +1104,11 @@ if (daemon_listen && !inetd_wait_mode) { joinstr[0] = sep; joinstr[1] = ' '; - *ptr = string_cat(*ptr, sizeptr, ptrptr, US"<", 1); + *ptr = string_catn(*ptr, sizeptr, ptrptr, US"<", 1); } - *ptr = string_cat(*ptr, sizeptr, ptrptr, joinstr, 2); - *ptr = string_cat(*ptr, sizeptr, ptrptr, s, Ustrlen(s)); + *ptr = string_catn(*ptr, sizeptr, ptrptr, joinstr, 2); + *ptr = string_cat (*ptr, sizeptr, ptrptr, s); } if (new_smtp_port != NULL) @@ -1356,7 +1362,6 @@ the listening sockets if required. */ if (daemon_listen && !inetd_wait_mode) { int sk; - int on = 1; ip_address_item *ipa; /* For each IP address, create a socket, bind it to the appropriate port, and @@ -1458,13 +1463,18 @@ if (daemon_listen && !inetd_wait_mode) } DEBUG(D_any) - { if (wildcard) debug_printf("listening on all interfaces (IPv%c) port %d\n", - (af == AF_INET6)? '6' : '4', ipa->port); + af == AF_INET6 ? '6' : '4', ipa->port); else debug_printf("listening on %s port %d\n", ipa->address, ipa->port); - } + +#ifdef TCP_FASTOPEN + if (setsockopt(listen_sockets[sk], SOL_TCP, TCP_FASTOPEN, &smtp_connect_backlog, + sizeof(smtp_connect_backlog))) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to set socket FASTOPEN: %s", + strerror(errno)); +#endif /* Start listening on the bound socket, establishing the maximum backlog of connections that is allowed. On success, continue to the next address. */ @@ -1479,8 +1489,8 @@ if (daemon_listen && !inetd_wait_mode) if (!check_special_case(errno, addresses, ipa, TRUE)) log_write(0, LOG_PANIC_DIE, "listen() failed on interface %s: %s", - wildcard? ((af == AF_INET6)? US"(any IPv6)" : US"(any IPv4)") : - ipa->address, + wildcard + ? af == AF_INET6 ? US"(any IPv6)" : US"(any IPv4)" : ipa->address, strerror(errno)); DEBUG(D_any) debug_printf("wildcard IPv4 listen() failed after IPv6 " @@ -1572,11 +1582,11 @@ originator_login = ((pw = getpwuid(exim_uid)) != NULL)? /* Get somewhere to keep the list of queue-runner pids if we are keeping track of them (and also if we are doing queue runs). */ -if (queue_interval > 0 && queue_run_max > 0) +if (queue_interval > 0 && local_queue_run_max > 0) { int i; - queue_pid_slots = store_get(queue_run_max * sizeof(pid_t)); - for (i = 0; i < queue_run_max; i++) queue_pid_slots[i] = 0; + queue_pid_slots = store_get(local_queue_run_max * sizeof(pid_t)); + for (i = 0; i < local_queue_run_max; i++) queue_pid_slots[i] = 0; } /* Set up the handler for termination of child processes. */ @@ -1615,12 +1625,11 @@ else if (daemon_listen) int i, j; int smtp_ports = 0; int smtps_ports = 0; - ip_address_item *ipa; - uschar *p = big_buffer; - uschar *qinfo = (queue_interval > 0)? - string_sprintf("-q%s", readconf_printtime(queue_interval)) - : - US"no queue runs"; + ip_address_item * ipa; + uschar * p = big_buffer; + uschar * qinfo = queue_interval > 0 + ? string_sprintf("-q%s", readconf_printtime(queue_interval)) + : US"no queue runs"; /* Build a list of listening addresses in big_buffer, but limit it to 10 items. The style is for backwards compatibility. @@ -1631,30 +1640,30 @@ else if (daemon_listen) for (j = 0; j < 2; j++) { - for (i = 0, ipa = addresses; i < 10 && ipa != NULL; i++, ipa = ipa->next) + for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next) { /* First time round, look for SMTP ports; second time round, look for SMTPS ports. For the first one of each, insert leading text. */ if (host_is_tls_on_connect_port(ipa->port) == (j > 0)) { - if (j == 0) - { - if (smtp_ports++ == 0) + if (j == 0) + { + if (smtp_ports++ == 0) { memcpy(p, "SMTP on", 8); p += 7; } - } - else - { - if (smtps_ports++ == 0) + } + else + { + if (smtps_ports++ == 0) { (void)sprintf(CS p, "%sSMTPS on", - (smtp_ports == 0)? "":" and for "); - while (*p != 0) p++; + smtp_ports == 0 ? "" : " and for "); + while (*p) p++; } - } + } /* Now the information about the port (and sometimes interface) */ @@ -1679,7 +1688,7 @@ else if (daemon_listen) } } - if (ipa != NULL) + if (ipa) { memcpy(p, " ...", 5); p += 4; @@ -1689,17 +1698,19 @@ else if (daemon_listen) log_write(0, LOG_MAIN, "exim %s daemon started: pid=%d, %s, listening for %s", version_string, getpid(), qinfo, big_buffer); - set_process_info("daemon(%s): %s, listening for %s", version_string, qinfo, big_buffer); + set_process_info("daemon(%s): %s, listening for %s", + version_string, qinfo, big_buffer); } else { + uschar * s = *queue_name + ? string_sprintf("-qG%s/%s", queue_name, readconf_printtime(queue_interval)) + : string_sprintf("-q%s", readconf_printtime(queue_interval)); log_write(0, LOG_MAIN, - "exim %s daemon started: pid=%d, -q%s, not listening for SMTP", - version_string, getpid(), readconf_printtime(queue_interval)); - set_process_info("daemon(%s): -q%s, not listening", - version_string, - readconf_printtime(queue_interval)); + "exim %s daemon started: pid=%d, %s, not listening for SMTP", + version_string, getpid(), s); + set_process_info("daemon(%s): %s, not listening", version_string, s); } /* Do any work it might be useful to amortize over our children @@ -1791,7 +1802,7 @@ for (;;) re-exec is required. */ if (queue_interval > 0 && - (queue_run_max <= 0 || queue_run_count < queue_run_max)) + (local_queue_run_max <= 0 || queue_run_count < local_queue_run_max)) { if ((pid = fork()) == 0) { @@ -1835,21 +1846,22 @@ for (;;) if (deliver_force_thaw) *p++ = 'f'; if (queue_run_local) *p++ = 'l'; *p = 0; - extra[0] = opt; + extra[0] = queue_name + ? string_sprintf("%sG%s", opt, queue_name) : opt; /* If -R or -S were on the original command line, ensure they get passed on. */ - if (deliver_selectstring != NULL) + if (deliver_selectstring) { - extra[extracount++] = deliver_selectstring_regex? US"-Rr" : US"-R"; + extra[extracount++] = deliver_selectstring_regex ? US"-Rr" : US"-R"; extra[extracount++] = deliver_selectstring; } - if (deliver_selectstring_sender != NULL) + if (deliver_selectstring_sender) { - extra[extracount++] = deliver_selectstring_sender_regex? - US"-Sr" : US"-S"; + extra[extracount++] = deliver_selectstring_sender_regex + ? US"-Sr" : US"-S"; extra[extracount++] = deliver_selectstring_sender; } @@ -1876,15 +1888,13 @@ for (;;) else { int i; - for (i = 0; i < queue_run_max; ++i) - { + for (i = 0; i < local_queue_run_max; ++i) if (queue_pid_slots[i] <= 0) { queue_pid_slots[i] = pid; queue_run_count++; break; } - } DEBUG(D_any) debug_printf("%d queue-runner process%s running\n", queue_run_count, (queue_run_count == 1)? "" : "es"); }