Commit | Line | Data |
---|---|---|
01e60269 AM |
1 | From e5be948a65fe601024e5d4256f64efbfed3dd72e Mon Sep 17 00:00:00 2001 |
2 | From: Jeremy Harris <jgh146exb@wizmail.org> | |
3 | Date: Mon, 18 Mar 2019 00:31:43 +0000 | |
4 | Subject: [PATCH 4/5] Logging: fix initial listening-on log line | |
5 | ||
6 | (cherry picked from commit 254f38d1c5ada5e4df0bccb385dc466549620c71) | |
7 | --- | |
8 | doc/ChangeLog | 4 +++ | |
9 | src/daemon.c | 73 +++++++++++++++++++++++++++---------------- | |
10 | src/host.c | 1 + | |
11 | src/structs.h | 1 + | |
12 | test/confs/0282 | 2 +- | |
13 | test/log/0282 | 2 +- | |
14 | 6 files changed, 54 insertions(+), 29 deletions(-) | |
15 | ||
16 | diff --git a/doc/ChangeLog b/doc/ChangeLog | |
17 | index 0f8d05b2..3c0ffbf0 100644 | |
18 | --- a/doc/ChangeLog | |
19 | +++ b/doc/ChangeLog | |
20 | @@ -23,10 +23,14 @@ JB/01 Bug 2375: fix expansions of 822 addresses having comments in local-part | |
21 | ||
22 | JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid | |
23 | configuration). If a CNAME target was not a wellformed name pattern, a | |
24 | crash could result. | |
25 | ||
26 | +JH/09 Logging: Fix initial listening-on line for multiple ports for an IP when | |
27 | + the OS reports them interleaved with other addresses. | |
28 | + | |
29 | + | |
30 | ||
31 | Exim version 4.92 | |
32 | ----------------- | |
33 | ||
34 | JH/01 Remove code calling the customisable local_scan function, unless a new | |
35 | diff --git a/src/daemon.c b/src/daemon.c | |
36 | index a852192e..01da3936 100644 | |
37 | --- a/src/daemon.c | |
38 | +++ b/src/daemon.c | |
39 | @@ -1625,12 +1625,12 @@ if (f.inetd_wait_mode) | |
40 | else if (f.daemon_listen) | |
41 | { | |
42 | int i, j; | |
43 | int smtp_ports = 0; | |
44 | int smtps_ports = 0; | |
45 | - ip_address_item * ipa, * i2; | |
46 | - uschar * p = big_buffer; | |
47 | + ip_address_item * ipa; | |
48 | + uschar * p; | |
49 | uschar * qinfo = queue_interval > 0 | |
50 | ? string_sprintf("-q%s", readconf_printtime(queue_interval)) | |
51 | : US"no queue runs"; | |
52 | ||
53 | /* Build a list of listening addresses in big_buffer, but limit it to 10 | |
54 | @@ -1638,73 +1638,92 @@ else if (f.daemon_listen) | |
55 | ||
56 | It is now possible to have some ports listening for SMTPS (the old, | |
57 | deprecated protocol that starts TLS without using STARTTLS), and others | |
58 | listening for standard SMTP. Keep their listings separate. */ | |
59 | ||
60 | - for (j = 0; j < 2; j++) | |
61 | + for (int j = 0, i; j < 2; j++) | |
62 | { | |
63 | for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next) | |
64 | { | |
65 | /* First time round, look for SMTP ports; second time round, look for | |
66 | - SMTPS ports. For the first one of each, insert leading text. */ | |
67 | + SMTPS ports. Build IP+port strings. */ | |
68 | ||
69 | if (host_is_tls_on_connect_port(ipa->port) == (j > 0)) | |
70 | { | |
71 | if (j == 0) | |
72 | - { | |
73 | - if (smtp_ports++ == 0) | |
74 | - { | |
75 | - memcpy(p, "SMTP on", 8); | |
76 | - p += 7; | |
77 | - } | |
78 | - } | |
79 | + smtp_ports++; | |
80 | else | |
81 | - if (smtps_ports++ == 0) | |
82 | - p += sprintf(CS p, "%sSMTPS on", | |
83 | - smtp_ports == 0 ? "" : " and for "); | |
84 | + smtps_ports++; | |
85 | ||
86 | /* Now the information about the port (and sometimes interface) */ | |
87 | ||
88 | if (ipa->address[0] == ':' && ipa->address[1] == 0) | |
89 | { /* v6 wildcard */ | |
90 | if (ipa->next && ipa->next->address[0] == 0 && | |
91 | ipa->next->port == ipa->port) | |
92 | { | |
93 | - p += sprintf(CS p, " port %d (IPv6 and IPv4)", ipa->port); | |
94 | - ipa = ipa->next; | |
95 | + ipa->log = string_sprintf(" port %d (IPv6 and IPv4)", ipa->port); | |
96 | + (ipa = ipa->next)->log = NULL; | |
97 | } | |
98 | else if (ipa->v6_include_v4) | |
99 | - p += sprintf(CS p, " port %d (IPv6 with IPv4)", ipa->port); | |
100 | + ipa->log = string_sprintf(" port %d (IPv6 with IPv4)", ipa->port); | |
101 | else | |
102 | - p += sprintf(CS p, " port %d (IPv6)", ipa->port); | |
103 | + ipa->log = string_sprintf(" port %d (IPv6)", ipa->port); | |
104 | } | |
105 | else if (ipa->address[0] == 0) /* v4 wildcard */ | |
106 | - p += sprintf(CS p, " port %d (IPv4)", ipa->port); | |
107 | + ipa->log = string_sprintf(" port %d (IPv4)", ipa->port); | |
108 | else /* check for previously-seen IP */ | |
109 | { | |
110 | + ip_address_item * i2; | |
111 | for (i2 = addresses; i2 != ipa; i2 = i2->next) | |
112 | if ( host_is_tls_on_connect_port(i2->port) == (j > 0) | |
113 | && Ustrcmp(ipa->address, i2->address) == 0 | |
114 | ) | |
115 | { /* found; append port to list */ | |
116 | - if (p[-1] == '}') p--; | |
117 | - while (isdigit(*--p)) ; | |
118 | - p += 1 + sprintf(CS p+1, "%s%d,%d}", *p == ',' ? "" : "{", | |
119 | - i2->port, ipa->port); | |
120 | + for (p = i2->log; *p; ) p++; /* end of existing string */ | |
121 | + if (*--p == '}') *p = '\0'; /* drop EOL */ | |
122 | + while (isdigit(*--p)) ; /* char before port */ | |
123 | + | |
124 | + i2->log = *p == ':' /* no list yet? */ | |
125 | + ? string_sprintf("%.*s{%s,%d}", | |
126 | + (int)(p - i2->log + 1), i2->log, p+1, ipa->port) | |
127 | + : string_sprintf("%s,%d}", i2->log, ipa->port); | |
128 | + ipa->log = NULL; | |
129 | break; | |
130 | } | |
131 | if (i2 == ipa) /* first-time IP */ | |
132 | - p += sprintf(CS p, " [%s]:%d", ipa->address, ipa->port); | |
133 | + ipa->log = string_sprintf(" [%s]:%d", ipa->address, ipa->port); | |
134 | } | |
135 | } | |
136 | } | |
137 | + } | |
138 | ||
139 | - if (ipa) | |
140 | + p = big_buffer; | |
141 | + for (int j = 0, i; j < 2; j++) | |
142 | + { | |
143 | + /* First time round, look for SMTP ports; second time round, look for | |
144 | + SMTPS ports. For the first one of each, insert leading text. */ | |
145 | + | |
146 | + if (j == 0) | |
147 | { | |
148 | - memcpy(p, " ...", 5); | |
149 | - p += 4; | |
150 | + if (smtp_ports > 0) | |
151 | + p += sprintf(CS p, "SMTP on"); | |
152 | } | |
153 | + else | |
154 | + if (smtps_ports > 0) | |
155 | + p += sprintf(CS p, "%sSMTPS on", | |
156 | + smtp_ports == 0 ? "" : " and for "); | |
157 | + | |
158 | + /* Now the information about the port (and sometimes interface) */ | |
159 | + | |
160 | + for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next) | |
161 | + if (host_is_tls_on_connect_port(ipa->port) == (j > 0)) | |
162 | + if (ipa->log) | |
163 | + p += sprintf(CS p, "%s", ipa->log); | |
164 | + | |
165 | + if (ipa) | |
166 | + p += sprintf(CS p, " ..."); | |
167 | } | |
168 | ||
169 | log_write(0, LOG_MAIN, | |
170 | "exim %s daemon started: pid=%d, %s, listening for %s", | |
171 | version_string, getpid(), qinfo, big_buffer); | |
172 | diff --git a/src/host.c b/src/host.c | |
173 | index 29c977fe..a3b0977b 100644 | |
174 | --- a/src/host.c | |
175 | +++ b/src/host.c | |
176 | @@ -757,10 +757,11 @@ while ((s = string_nextinlist(&list, &sep, NULL, 0))) | |
177 | next = store_get(sizeof(ip_address_item)); | |
178 | next->next = NULL; | |
179 | Ustrcpy(next->address, s); | |
180 | next->port = port; | |
181 | next->v6_include_v4 = FALSE; | |
182 | + next->log = NULL; | |
183 | ||
184 | if (!yield) | |
185 | yield = last = next; | |
186 | else | |
187 | { | |
188 | diff --git a/src/structs.h b/src/structs.h | |
189 | index 20db0e5f..1e63d752 100644 | |
190 | --- a/src/structs.h | |
191 | +++ b/src/structs.h | |
192 | @@ -442,10 +442,11 @@ hold an IPv6 address. */ | |
193 | typedef struct ip_address_item { | |
194 | struct ip_address_item *next; | |
195 | int port; | |
196 | BOOL v6_include_v4; /* Used in the daemon */ | |
197 | uschar address[46]; | |
198 | + uschar * log; /* portion of "listening on" log line */ | |
199 | } ip_address_item; | |
200 | ||
201 | /* Structure for chaining together arbitrary strings. */ | |
202 | ||
203 | typedef struct string_item { | |
204 | -- | |
205 | 2.20.1 | |
206 |