]> git.pld-linux.org Git - packages/exim.git/blame - exim-git.patch
- rel 3; use exim-4_86+fixes branch instead of master
[packages/exim.git] / exim-git.patch
CommitLineData
cb4fdfcc 1commit da1aecfce80fba32b9abb328cf78088d95b7700a
4022a9ec 2Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
cb4fdfcc 3Date: Wed Aug 19 15:22:41 2015 +0200
4022a9ec 4
cb4fdfcc
AM
5 Fix post-transport-crash.
6
7 The crash probably was introduced in a39bd74d3e94 and
8 needs 'split_spool_directory=yes' to expose.
4022a9ec 9
cb4fdfcc 10 Thanks to Wolfgang Breyha, who found the same fix.
4022a9ec 11
cb4fdfcc 12 (cherry picked from commit 6b51df8340eacc95e3def9a4376506610e91996c)
4022a9ec 13
cb4fdfcc
AM
14diff --git a/src/src/transport.c b/src/src/transport.c
15index fa6f869..a6ad3ed 100644
16--- a/src/src/transport.c
17+++ b/src/src/transport.c
18@@ -1752,7 +1752,7 @@ while (1)
19 {
20 if (split_spool_directory)
21 sprintf(CS spool_file, "%s%c/%s-D",
22- spool_dir, new_message_id[5], msgq[i].message_id);
23+ spool_dir, msgq[i].message_id[5], msgq[i].message_id);
24 else
25 sprintf(CS spool_file, "%s%s-D", spool_dir, msgq[i].message_id);
4022a9ec
AM
26
27
cb4fdfcc
AM
28commit d7168d8b112d3ba642a25ed04de36fb76d4a847d
29Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
30Date: Thu Aug 20 13:58:06 2015 +0200
4022a9ec 31
cb4fdfcc
AM
32 Fix post-transport-crash: safeguard for missing spool BUG 1671
33
34 Based on a proposal from Wolfgang Breyha.
35
36 (cherry picked from commit dadff1d47e54962b0fdf98e8ce5cef42b6cb7fb5)
4022a9ec 37
cb4fdfcc
AM
38diff --git a/src/src/deliver.c b/src/src/deliver.c
39index 78f8f4b..4154ff7 100644
40--- a/src/src/deliver.c
41+++ b/src/src/deliver.c
42@@ -9,6 +9,7 @@
4022a9ec 43
4022a9ec 44
cb4fdfcc
AM
45 #include "exim.h"
46+#include <assert.h>
4022a9ec 47
4022a9ec 48
cb4fdfcc
AM
49 /* Data block for keeping track of subprocesses for parallel remote
50@@ -7904,17 +7905,36 @@ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA =
51 uschar *
52 deliver_get_sender_address (uschar * id)
53 {
54+int rc;
55+uschar * new_sender_address,
56+ * save_sender_address;
4022a9ec 57+
cb4fdfcc
AM
58 if (!spool_open_datafile(id))
59 return NULL;
60
61+/* Save and restore the global sender_address. I'm not sure if we should
62+not save/restore all the other global variables too, because
63+spool_read_header() may change all of them. But OTOH, when this
64+deliver_get_sender_address() gets called, the current message is done
65+already and nobody needs the globals anymore. (HS12, 2015-08-21) */
4022a9ec 66+
cb4fdfcc
AM
67 sprintf(CS spoolname, "%s-H", id);
68-if (spool_read_header(spoolname, TRUE, TRUE) != spool_read_OK)
69+save_sender_address = sender_address;
4022a9ec 70+
cb4fdfcc 71+rc = spool_read_header(spoolname, TRUE, TRUE);
4022a9ec 72+
cb4fdfcc
AM
73+new_sender_address = sender_address;
74+sender_address = save_sender_address;
4022a9ec 75+
cb4fdfcc
AM
76+if (rc != spool_read_OK)
77 return NULL;
4022a9ec 78
cb4fdfcc 79+assert(new_sender_address);
4022a9ec 80+
cb4fdfcc
AM
81 (void)close(deliver_datafile);
82 deliver_datafile = -1;
4022a9ec 83
cb4fdfcc
AM
84-return sender_address;
85+return new_sender_address;
86 }
87
88 /* vi: aw ai sw=2
89diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
90index a952413..5ac5533 100644
91--- a/src/src/transports/smtp.c
92+++ b/src/src/transports/smtp.c
93@@ -1274,14 +1274,19 @@ we will veto this new message. */
4022a9ec 94 static BOOL
cb4fdfcc 95 smtp_are_same_identities(uschar * message_id, smtp_compare_t * s_compare)
4022a9ec 96 {
cb4fdfcc
AM
97-uschar * save_sender_address = sender_address;
98-uschar * current_local_identity =
4022a9ec 99+
cb4fdfcc
AM
100+uschar * message_local_identity,
101+ * current_local_identity,
102+ * new_sender_address;
4022a9ec 103+
cb4fdfcc
AM
104+current_local_identity =
105 smtp_local_identity(s_compare->current_sender_address, s_compare->tblock);
106-uschar * new_sender_address = deliver_get_sender_address(message_id);
107-uschar * message_local_identity =
108- smtp_local_identity(new_sender_address, s_compare->tblock);
4022a9ec 109
cb4fdfcc
AM
110-sender_address = save_sender_address;
111+if (!(new_sender_address = deliver_get_sender_address(message_id)))
112+ return 0;
113+
114+message_local_identity =
115+ smtp_local_identity(new_sender_address, s_compare->tblock);
4022a9ec 116
cb4fdfcc 117 return Ustrcmp(current_local_identity, message_local_identity) == 0;
4022a9ec 118 }
4022a9ec 119
cb4fdfcc 120commit 9e1acebc3fbb288da804ab9031c7c448dffd841a
4022a9ec
AM
121Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
122Date: Tue Aug 11 17:36:29 2015 +0200
123
124 Fix ESMTP MAIL command option processing
125
126 If the address containes spaces, the option processing
127 was confused.
cb4fdfcc
AM
128
129 (cherry picked from commit 2ef7ed082481b2dccd3c2e0eae849b24bf0b172a)
4022a9ec
AM
130
131diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
cb4fdfcc 132index cf0a5d6..980d54b 100644
4022a9ec
AM
133--- a/src/src/smtp_in.c
134+++ b/src/src/smtp_in.c
135@@ -9,6 +9,7 @@
136
137
138 #include "exim.h"
139+#include <assert.h>
140
141
142 /* Initialize for TCP wrappers if so configured. It appears that the macro
143@@ -232,6 +233,7 @@ static uschar *protocols[] = {
144
145 /* Sanity check and validate optional args to MAIL FROM: envelope */
146 enum {
147+ ENV_MAIL_OPT_NULL,
148 ENV_MAIL_OPT_SIZE, ENV_MAIL_OPT_BODY, ENV_MAIL_OPT_AUTH,
149 #ifndef DISABLE_PRDR
150 ENV_MAIL_OPT_PRDR,
151@@ -240,7 +242,6 @@ enum {
152 #ifdef EXPERIMENTAL_INTERNATIONAL
153 ENV_MAIL_OPT_UTF8,
154 #endif
155- ENV_MAIL_OPT_NULL
156 };
157 typedef struct {
158 uschar * name; /* option requested during MAIL cmd */
159@@ -260,7 +261,8 @@ static env_mail_type_t env_mail_type_list[] = {
160 #ifdef EXPERIMENTAL_INTERNATIONAL
161 { US"SMTPUTF8",ENV_MAIL_OPT_UTF8, FALSE }, /* rfc6531 */
162 #endif
163- { US"NULL", ENV_MAIL_OPT_NULL, FALSE }
164+ /* keep this the last entry */
165+ { US"NULL", ENV_MAIL_OPT_NULL, FALSE },
166 };
167
168 /* When reading SMTP from a remote host, we have to use our own versions of the
169@@ -3887,7 +3889,7 @@ while (done <= 0)
170 if (!extract_option(&name, &value)) break;
171
172 for (mail_args = env_mail_type_list;
173- (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list);
174+ mail_args->value != ENV_MAIL_OPT_NULL;
175 mail_args++
176 )
177 if (strcmpic(name, mail_args->name) == 0)
178@@ -4066,15 +4068,17 @@ while (done <= 0)
179 }
180 break;
181 #endif
182- /* Unknown option. Stick back the terminator characters and break
183+ /* No valid option. Stick back the terminator characters and break
184 the loop. Do the name-terminator second as extract_option sets
185- value==name when it found no equal-sign.
186- An error for a malformed address will occur. */
187- default:
188+ value==name when it found no equal-sign.
189+ An error for a malformed address will occur. */
190+ case ENV_MAIL_OPT_NULL:
191 value[-1] = '=';
192 name[-1] = ' ';
193 arg_error = TRUE;
194 break;
195+
196+ default: assert(0);
197 }
198 /* Break out of for loop if switch() had bad argument or
199 when start of the email address is reached */
200
cb4fdfcc 201commit 22c82c48aa5d23c49d38e3581810ea54587df61b
4022a9ec 202Author: Jeremy Harris <jgh146exb@wizmail.org>
cb4fdfcc 203Date: Tue Aug 25 10:36:27 2015 +0100
4022a9ec 204
cb4fdfcc
AM
205 Close logs after daemon-process exceptional write. Bug 728
206
207 (cherry picked from commit c8899c20aa08c9ae6a4c291aad23ba90512bebe4)
4022a9ec 208
cb4fdfcc
AM
209diff --git a/src/src/daemon.c b/src/src/daemon.c
210index 894a96f..a7a49f0 100644
211--- a/src/src/daemon.c
212+++ b/src/src/daemon.c
213@@ -735,6 +735,7 @@ else (void)close(dup_accept_socket);
214 /* Release any store used in this process, including the store used for holding
215 the incoming host address and an expanded active_hostname. */
4022a9ec 216
cb4fdfcc
AM
217+log_close_all();
218 store_reset(reset_point);
219 sender_host_address = NULL;
220 }
221
222commit 4d3b8805796ffa39889060d9f216bfaf7391c542
223Author: Jeremy Harris <jgh146exb@wizmail.org>
224Date: Thu Sep 17 13:35:16 2015 +0100
225
226 DNS: time-limit cached returns, using TTL. Bug 1395
227
228 This can matter for fast-changing data such as DNSBLs.
229
230 (cherry picked from commit 14b3c5bc64a16df07583fe4b5ef2e0129d063893)
231
232 DNS: avoid overflow in cache TTL for negative entries. Bug 1395
233
234 (cherry picked from commit e162fc9757d4b8cb41aca74214e968622d6c3dee)
235
236diff --git a/src/src/dns.c b/src/src/dns.c
237index 64958d9..abed126 100644
238--- a/src/src/dns.c
239+++ b/src/src/dns.c
240@@ -390,7 +390,8 @@ from the following bytes. */
241
242 dnss->aptr += namelen;
243 GETSHORT(dnss->srr.type, dnss->aptr); /* Record type */
244-dnss->aptr += 6; /* Don't want class or TTL */
245+dnss->aptr += 2; /* Don't want class */
246+GETLONG(dnss->srr.ttl, dnss->aptr); /* TTL */
247 GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */
248 dnss->srr.data = dnss->aptr; /* The record's data follows */
249 dnss->aptr += dnss->srr.size; /* Advance to next RR */
250diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h
251index cdd1c85..03de8f6 100644
252--- a/src/src/lookupapi.h
253+++ b/src/src/lookupapi.h
254@@ -34,7 +34,7 @@ typedef struct lookup_info {
255 int, /* length of key or query */
256 uschar **, /* for returning answer */
257 uschar **, /* for error message */
258- BOOL *); /* to request cache cleanup */
259+ uint *); /* cache TTL, sconds */
260 void (*close)( /* close function */
261 void *); /* handle */
262 void (*tidy)(void); /* tidy function */
263@@ -46,9 +46,10 @@ typedef struct lookup_info {
264 } lookup_info;
265
266 /* This magic number is used by the following lookup_module_info structure
267- for checking API compatibility. It's equivalent to the string"LMM2" */
268-#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4d32
269+ for checking API compatibility. It used to be equivalent to the string"LMM3" */
270+#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4933
271 /* Version 2 adds: version_report */
272+/* Version 3 change: non/cache becomes TTL in seconds */
273
274 typedef struct lookup_module_info {
275 uint magic;
276diff --git a/src/src/lookups/README b/src/src/lookups/README
277index 98905dc..31fea64 100644
278--- a/src/src/lookups/README
279+++ b/src/src/lookups/README
280@@ -122,12 +122,15 @@ DEFER. The arguments are:
281 uschar **errmsg where to put an error message on failure;
282 this is initially set to "", and should be left
283 as that for a standard "entry not found" error
284- BOOL *do_cache the lookup should set this to FALSE when it changes data.
285- This is TRUE by default. When set to FALSE the cache tree
286+ uint *do_cache the lookup should set this to 0 when it changes data.
287+ This is MAXINT by default. When set to 0 the cache tree
288 of the current search handle will be cleaned and the
289 current result will NOT be cached. Currently the mysql
290 and pgsql lookups use this when UPDATE/INSERT queries are
291 executed.
292+ If set to a nonzero number of seconds, the cached value
293+ becomes unusable after this time. Currently the dnsdb
294+ lookup uses this to support the TTL value.
295
296 Even though the key is zero-terminated, the length is passed because in the
297 common case it has been computed already and is often needed.
298diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c
299index ea017de..ba925dc 100644
300--- a/src/src/lookups/cdb.c
301+++ b/src/src/lookups/cdb.c
302@@ -279,7 +279,7 @@ cdb_find(void *handle,
303 int key_len,
304 uschar **result,
305 uschar **errmsg,
306- BOOL *do_cache)
307+ uint *do_cache)
308 {
309 struct cdb_state * cdbp = handle;
310 uint32 item_key_len,
311diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c
312index 03248e4..b8c42d5 100644
313--- a/src/src/lookups/dbmdb.c
314+++ b/src/src/lookups/dbmdb.c
315@@ -87,7 +87,7 @@ the keylength in order to include the terminating zero. */
316
317 static int
318 dbmdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
319- uschar **result, uschar **errmsg, BOOL *do_cache)
320+ uschar **result, uschar **errmsg, uint *do_cache)
321 {
322 EXIM_DB *d = (EXIM_DB *)handle;
323 EXIM_DATUM key, data;
324@@ -120,7 +120,7 @@ return FAIL;
4022a9ec 325
cb4fdfcc
AM
326 int
327 static dbmnz_find(void *handle, uschar *filename, const uschar *keystring, int length,
328- uschar **result, uschar **errmsg, BOOL *do_cache)
329+ uschar **result, uschar **errmsg, uint *do_cache)
4022a9ec 330 {
cb4fdfcc
AM
331 return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
332 do_cache);
333@@ -140,7 +140,7 @@ return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
334
335 static int
336 dbmjz_find(void *handle, uschar *filename, const uschar *keystring, int length,
337- uschar **result, uschar **errmsg, BOOL *do_cache)
338+ uschar **result, uschar **errmsg, uint *do_cache)
339 {
340 uschar *key_item, *key_buffer, *key_p;
341 const uschar *key_elems = keystring;
342diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
343index e3de279..70e6c8c 100644
344--- a/src/src/lookups/dnsdb.c
345+++ b/src/src/lookups/dnsdb.c
346@@ -131,7 +131,7 @@ separator, as always, is colon. */
347
348 static int
349 dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
350- uschar **result, uschar **errmsg, BOOL *do_cache)
351+ uschar **result, uschar **errmsg, uint *do_cache)
352 {
353 int rc;
354 int size = 256;
355@@ -388,6 +388,9 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
356 {
357 if (rr->type != searchtype) continue;
4022a9ec 358
cb4fdfcc
AM
359+ if (*do_cache > rr->ttl)
360+ *do_cache = rr->ttl;
361+
362 if (type == T_A || type == T_AAAA || type == T_ADDRESSES)
363 {
364 dns_address *da;
365diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c
366index f8c592a..9f7dd8d 100644
367--- a/src/src/lookups/dsearch.c
368+++ b/src/src/lookups/dsearch.c
369@@ -67,7 +67,7 @@ for us. */
4022a9ec 370
cb4fdfcc
AM
371 int
372 static dsearch_find(void *handle, uschar *dirname, const uschar *keystring, int length,
373- uschar **result, uschar **errmsg, BOOL *do_cache)
374+ uschar **result, uschar **errmsg, uint *do_cache)
375 {
376 struct stat statbuf;
377 int save_errno;
378diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c
379index 23e1dea..7fd53d0 100644
380--- a/src/src/lookups/ibase.c
381+++ b/src/src/lookups/ibase.c
382@@ -451,7 +451,7 @@ deferred with a retryable error. */
383
384 static int
385 ibase_find(void *handle, uschar * filename, uschar * query, int length,
386- uschar ** result, uschar ** errmsg, BOOL *do_cache)
387+ uschar ** result, uschar ** errmsg, uint *do_cache)
388 {
389 int sep = 0;
390 uschar *server;
391diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
392index a56eff3..b870df1 100644
393--- a/src/src/lookups/ldap.c
394+++ b/src/src/lookups/ldap.c
395@@ -1339,7 +1339,7 @@ The handle and filename arguments are not used. */
396
397 static int
398 eldap_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
399- uschar **result, uschar **errmsg, BOOL *do_cache)
400+ uschar **result, uschar **errmsg, uint *do_cache)
401 {
402 /* Keep picky compilers happy */
403 do_cache = do_cache;
404@@ -1348,7 +1348,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
405
406 static int
407 eldapm_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
408- uschar **result, uschar **errmsg, BOOL *do_cache)
409+ uschar **result, uschar **errmsg, uint *do_cache)
410 {
411 /* Keep picky compilers happy */
412 do_cache = do_cache;
413@@ -1357,7 +1357,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
414
415 static int
416 eldapdn_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
417- uschar **result, uschar **errmsg, BOOL *do_cache)
418+ uschar **result, uschar **errmsg, uint *do_cache)
419 {
420 /* Keep picky compilers happy */
421 do_cache = do_cache;
422@@ -1366,7 +1366,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
4022a9ec 423
cb4fdfcc
AM
424 int
425 eldapauth_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
426- uschar **result, uschar **errmsg, BOOL *do_cache)
427+ uschar **result, uschar **errmsg, uint *do_cache)
428 {
429 /* Keep picky compilers happy */
430 do_cache = do_cache;
431diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h
432index 73e9303..d2487d3 100644
433--- a/src/src/lookups/lf_functions.h
434+++ b/src/src/lookups/lf_functions.h
435@@ -12,7 +12,7 @@ extern int lf_check_file(int, uschar *, int, int, uid_t *, gid_t *,
436 extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *);
437 extern int lf_sqlperform(const uschar *, const uschar *, const uschar *,
438 const uschar *, uschar **,
439- uschar **, BOOL *, int(*)(const uschar *, uschar *, uschar **,
440- uschar **, BOOL *, BOOL *));
441+ uschar **, uint *, int(*)(const uschar *, uschar *, uschar **,
442+ uschar **, BOOL *, uint *));
443
444 /* End of lf_functions.h */
445diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c
446index 2d7f326..6d4f7a7 100644
447--- a/src/src/lookups/lf_sqlperform.c
448+++ b/src/src/lookups/lf_sqlperform.c
449@@ -27,7 +27,7 @@ Arguments:
450 query the query
451 result where to pass back the result
452 errmsg where to pass back an error message
453- do_cache to be set FALSE if data is changed
454+ do_cache to be set zero if data is changed
455 func the lookup function to call
456
457 Returns: the return from the lookup function, or DEFER
458@@ -36,8 +36,8 @@ Returns: the return from the lookup function, or DEFER
459 int
460 lf_sqlperform(const uschar *name, const uschar *optionname,
461 const uschar *optserverlist, const uschar *query,
462- uschar **result, uschar **errmsg, BOOL *do_cache,
463- int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *))
464+ uschar **result, uschar **errmsg, uint *do_cache,
465+ int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, uint *))
466 {
467 int sep, rc;
468 uschar *server;
469diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c
470index 3883d4b..eb70a45 100644
471--- a/src/src/lookups/lsearch.c
472+++ b/src/src/lookups/lsearch.c
473@@ -323,7 +323,7 @@ return FAIL;
474
475 static int
476 lsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
477- uschar **result, uschar **errmsg, BOOL *do_cache)
478+ uschar **result, uschar **errmsg, uint *do_cache)
479 {
480 do_cache = do_cache; /* Keep picky compilers happy */
481 return internal_lsearch_find(handle, filename, keystring, length, result,
482@@ -340,7 +340,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
483
484 static int
485 wildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
486- uschar **result, uschar **errmsg, BOOL *do_cache)
487+ uschar **result, uschar **errmsg, uint *do_cache)
488 {
489 do_cache = do_cache; /* Keep picky compilers happy */
490 return internal_lsearch_find(handle, filename, keystring, length, result,
491@@ -357,7 +357,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
492
493 static int
494 nwildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
495- uschar **result, uschar **errmsg, BOOL *do_cache)
496+ uschar **result, uschar **errmsg, uint *do_cache)
497 {
498 do_cache = do_cache; /* Keep picky compilers happy */
499 return internal_lsearch_find(handle, filename, keystring, length, result,
500@@ -375,7 +375,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
501
502 static int
503 iplsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
504- uschar **result, uschar **errmsg, BOOL *do_cache)
505+ uschar **result, uschar **errmsg, uint *do_cache)
506 {
507 do_cache = do_cache; /* Keep picky compilers happy */
508 if ((length == 1 && keystring[0] == '*') ||
509diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c
510index 8dff86a..1ce8831 100644
511--- a/src/src/lookups/mysql.c
512+++ b/src/src/lookups/mysql.c
513@@ -74,7 +74,7 @@ Arguments:
514 resultptr where to store the result
515 errmsg where to point an error message
516 defer_break TRUE if no more servers are to be tried after DEFER
517- do_cache set false if data is changed
518+ do_cache set zero if data is changed
519
520 The server string is of the form "host/dbname/user/password". The host can be
521 host:port. This string is in a nextinlist temporary buffer, so can be
522@@ -85,7 +85,7 @@ Returns: OK, FAIL, or DEFER
523
524 static int
525 perform_mysql_search(const uschar *query, uschar *server, uschar **resultptr,
526- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
527+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
528 {
529 MYSQL *mysql_handle = NULL; /* Keep compilers happy */
530 MYSQL_RES *mysql_result = NULL;
531@@ -225,7 +225,7 @@ can be detected by calling mysql_field_count(). If its result is zero, no data
532 was expected (this is all explained clearly in the MySQL manual). In this case,
533 we return the number of rows affected by the command. In this event, we do NOT
534 want to cache the result; also the whole cache for the handle must be cleaned
535-up. Setting do_cache FALSE requests this. */
536+up. Setting do_cache zero requests this. */
537
538 if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
539 {
540@@ -233,7 +233,7 @@ if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
541 {
542 DEBUG(D_lookup) debug_printf("MYSQL: query was not one that returns data\n");
543 result = string_sprintf("%d", mysql_affected_rows(mysql_handle));
544- *do_cache = FALSE;
545+ *do_cache = 0;
546 goto MYSQL_EXIT;
4022a9ec 547 }
cb4fdfcc
AM
548 *errmsg = string_sprintf("MYSQL: lookup result failed: %s\n",
549@@ -341,7 +341,7 @@ shared with other SQL lookups. */
4022a9ec 550
cb4fdfcc
AM
551 static int
552 mysql_find(void *handle, uschar *filename, const uschar *query, int length,
553- uschar **result, uschar **errmsg, BOOL *do_cache)
554+ uschar **result, uschar **errmsg, uint *do_cache)
555 {
556 return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query,
557 result, errmsg, do_cache, perform_mysql_search);
558diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c
559index 7b012b1..1faa884 100644
560--- a/src/src/lookups/nis.c
561+++ b/src/src/lookups/nis.c
562@@ -42,7 +42,7 @@ code. */
563
564 static int
565 nis_find(void *handle, uschar *filename, uschar *keystring, int length,
566- uschar **result, uschar **errmsg, BOOL *do_cache)
567+ uschar **result, uschar **errmsg, uint *do_cache)
568 {
569 int rc;
570 uschar *nis_data;
571@@ -68,7 +68,7 @@ return (rc == YPERR_KEY || rc == YPERR_MAP)? FAIL : DEFER;
4022a9ec 572
cb4fdfcc
AM
573 static int
574 nis0_find(void *handle, uschar *filename, uschar *keystring, int length,
575- uschar **result, uschar **errmsg, BOOL *do_cache)
576+ uschar **result, uschar **errmsg, uint *do_cache)
4022a9ec 577 {
4022a9ec 578 int rc;
cb4fdfcc
AM
579 uschar *nis_data;
580diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c
581index 8895cee..a4a7a2d 100644
582--- a/src/src/lookups/nisplus.c
583+++ b/src/src/lookups/nisplus.c
584@@ -43,7 +43,7 @@ equals sign. */
585
586 static int
587 nisplus_find(void *handle, uschar *filename, uschar *query, int length,
588- uschar **result, uschar **errmsg, BOOL *do_cache)
589+ uschar **result, uschar **errmsg, uint *do_cache)
590 {
591 int i;
592 int ssize = 0;
593diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c
594index 1f2520a..adb17b4 100644
595--- a/src/src/lookups/oracle.c
596+++ b/src/src/lookups/oracle.c
597@@ -517,7 +517,7 @@ deferred with a retryable error. */
598
599 static int
600 oracle_find(void *handle, uschar *filename, uschar *query, int length,
601- uschar **result, uschar **errmsg, BOOL *do_cache)
602+ uschar **result, uschar **errmsg, uint *do_cache)
603 {
604 int sep = 0;
605 uschar *server;
606diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c
607index e726f3e..315677f 100644
608--- a/src/src/lookups/passwd.c
609+++ b/src/src/lookups/passwd.c
610@@ -34,7 +34,7 @@ return (void *)(-1); /* Just return something non-null */
611
612 static int
613 passwd_find(void *handle, uschar *filename, const uschar *keystring, int length,
614- uschar **result, uschar **errmsg, BOOL *do_cache)
615+ uschar **result, uschar **errmsg, uint *do_cache)
616 {
617 struct passwd *pw;
618
619diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c
620index c86ac23..4be3d98 100644
621--- a/src/src/lookups/pgsql.c
622+++ b/src/src/lookups/pgsql.c
623@@ -119,7 +119,7 @@ Returns: OK, FAIL, or DEFER
624
625 static int
626 perform_pgsql_search(const uschar *query, uschar *server, uschar **resultptr,
627- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
628+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
629 {
630 PGconn *pg_conn = NULL;
631 PGresult *pg_result = NULL;
632@@ -290,10 +290,10 @@ else
633 /* The command was successful but did not return any data since it was
634 * not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
635 * high level code to not cache this query, and clean the current cache for
636- * this handle by setting *do_cache FALSE. */
637+ * this handle by setting *do_cache zero. */
638 result = string_copy(US PQcmdTuples(pg_result));
639 offset = Ustrlen(result);
640- *do_cache = FALSE;
641+ *do_cache = 0;
642 DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
643 "but was successful. Rows affected: %s\n", result);
644
645@@ -399,7 +399,7 @@ shared with other SQL lookups. */
646
647 static int
648 pgsql_find(void *handle, uschar *filename, const uschar *query, int length,
649- uschar **result, uschar **errmsg, BOOL *do_cache)
650+ uschar **result, uschar **errmsg, uint *do_cache)
651 {
652 return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query,
653 result, errmsg, do_cache, perform_pgsql_search);
654diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c
655index ac4d0ec..18cd3a0 100644
656--- a/src/src/lookups/redis.c
657+++ b/src/src/lookups/redis.c
658@@ -65,7 +65,7 @@ redis_tidy(void)
659 */
660 static int
661 perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
662- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
663+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
664 {
665 redisContext *redis_handle = NULL; /* Keep compilers happy */
666 redisReply *redis_reply = NULL;
667@@ -197,7 +197,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
668 case REDIS_REPLY_ERROR:
669 *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str);
670 *defer_break = FALSE;
671- *do_cache = FALSE;
672+ *do_cache = 0;
673 goto REDIS_EXIT;
674 /* NOTREACHED */
675
676@@ -205,7 +205,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
677 case REDIS_REPLY_NIL:
678 DEBUG(D_lookup) debug_printf("REDIS: query was not one that returned any data\n");
679 result = string_sprintf("");
680- *do_cache = FALSE;
681+ *do_cache = 0;
682 goto REDIS_EXIT;
683 /* NOTREACHED */
684
685@@ -304,7 +304,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
686
687 static int
688 redis_find(void *handle __attribute__((unused)), uschar *filename __attribute__((unused)),
689- uschar *command, int length, uschar **result, uschar **errmsg, BOOL *do_cache)
690+ uschar *command, int length, uschar **result, uschar **errmsg, uint *do_cache)
691 {
692 return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command,
693 result, errmsg, do_cache, perform_redis_search);
694diff --git a/src/src/lookups/spf.c b/src/src/lookups/spf.c
695index 23ad2ad..2671fc9 100644
696--- a/src/src/lookups/spf.c
697+++ b/src/src/lookups/spf.c
698@@ -31,7 +31,9 @@ static void dummy(int x) { dummy2(x-1); }
699 #include <spf2/spf_dns_resolv.h>
700 #include <spf2/spf_dns_cache.h>
701
702-static void *spf_open(uschar *filename, uschar **errmsg) {
703+static void *
704+spf_open(uschar *filename, uschar **errmsg)
705+{
706 SPF_server_t *spf_server = NULL;
707 spf_server = SPF_server_new(SPF_DNS_CACHE, 0);
708 if (spf_server == NULL) {
709@@ -41,13 +43,17 @@ static void *spf_open(uschar *filename, uschar **errmsg) {
710 return (void *) spf_server;
711 }
712
713-static void spf_close(void *handle) {
714+static void
715+spf_close(void *handle)
716+{
717 SPF_server_t *spf_server = handle;
718 if (spf_server) SPF_server_free(spf_server);
719 }
720
721-static int spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
722- uschar **result, uschar **errmsg, BOOL *do_cache) {
723+static int
724+spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
725+ uschar **result, uschar **errmsg, uint *do_cache)
726+{
727 SPF_server_t *spf_server = handle;
728 SPF_request_t *spf_request = NULL;
729 SPF_response_t *spf_response = NULL;
730diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c
731index bb92c8c..e2330f9 100644
732--- a/src/src/lookups/sqlite.c
733+++ b/src/src/lookups/sqlite.c
734@@ -81,7 +81,7 @@ return 0;
735
736 static int
737 sqlite_find(void *handle, uschar *filename, const uschar *query, int length,
738- uschar **result, uschar **errmsg, BOOL *do_cache)
739+ uschar **result, uschar **errmsg, uint *do_cache)
740 {
741 int ret;
742 struct strbuf res = { NULL, 0, 0 };
743@@ -93,7 +93,7 @@ if (ret != SQLITE_OK)
744 return FAIL;
745 }
4022a9ec 746
cb4fdfcc
AM
747-if (res.string == NULL) *do_cache = FALSE;
748+if (res.string == NULL) *do_cache = 0;
749
750 *result = res.string;
751 return OK;
752diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c
753index c82fa7f..401f7c8 100644
754--- a/src/src/lookups/testdb.c
755+++ b/src/src/lookups/testdb.c
756@@ -38,7 +38,7 @@ return (void *)(1); /* Just return something non-null */
757
758 static int
759 testdb_find(void *handle, uschar *filename, const uschar *query, int length,
760- uschar **result, uschar **errmsg, BOOL *do_cache)
761+ uschar **result, uschar **errmsg, uint *do_cache)
762 {
763 handle = handle; /* Keep picky compilers happy */
764 filename = filename;
765@@ -57,7 +57,7 @@ if (Ustrcmp(query, "defer") == 0)
766 return DEFER;
767 }
4022a9ec 768
cb4fdfcc
AM
769-if (Ustrcmp(query, "nocache") == 0) *do_cache = FALSE;
770+if (Ustrcmp(query, "nocache") == 0) *do_cache = 0;
771
772 *result = string_copy(query);
773 return OK;
774diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c
775index 4166089..9ac5a3a 100644
776--- a/src/src/lookups/whoson.c
777+++ b/src/src/lookups/whoson.c
778@@ -36,7 +36,7 @@ return (void *)(1); /* Just return something non-null */
779
780 static int
781 whoson_find(void *handle, uschar *filename, uschar *query, int length,
782- uschar **result, uschar **errmsg, BOOL *do_cache)
783+ uschar **result, uschar **errmsg, uint *do_cache)
784 {
785 uschar buffer[80];
786 handle = handle; /* Keep picky compilers happy */
787diff --git a/src/src/search.c b/src/src/search.c
788index a055291..cd522da 100644
789--- a/src/src/search.c
790+++ b/src/src/search.c
791@@ -466,6 +466,7 @@ internal_search_find(void *handle, uschar *filename, uschar *keystring)
792 {
793 tree_node *t = (tree_node *)handle;
794 search_cache *c = (search_cache *)(t->data.ptr);
795+expiring_data *e;
796 uschar *data = NULL;
797 int search_type = t->name[0] - '0';
798 int old_pool = store_pool;
799@@ -491,18 +492,27 @@ store_pool = POOL_SEARCH;
800 /* Look up the data for the key, unless it is already in the cache for this
801 file. No need to check c->item_cache for NULL, tree_search will do so. */
802
803-if ((t = tree_search(c->item_cache, keystring)) == NULL)
804+if ( (t = tree_search(c->item_cache, keystring))
805+ && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL))
806+ )
807+ { /* Data was in the cache already; set the pointer from the tree node */
808+ data = e->ptr;
809+ DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
810+ keystring,
811+ filename ? US"\n in " : US"", filename ? filename : US"");
812+ }
813+else
4022a9ec 814 {
cb4fdfcc
AM
815- BOOL do_cache = TRUE;
816+ uint do_cache = UINT_MAX;
817 int keylength = Ustrlen(keystring);
4022a9ec 818
cb4fdfcc 819 DEBUG(D_lookup)
4022a9ec 820 {
cb4fdfcc
AM
821- if (filename != NULL)
822- debug_printf("file lookup required for %s\n in %s\n",
823- keystring, filename);
824- else
825- debug_printf("database lookup required for %s\n", keystring);
826+ if (t) debug_printf("cached data found but past valid time; ");
827+ debug_printf("%s lookup required for %s%s%s\n",
828+ filename ? US"file" : US"database",
829+ keystring,
830+ filename ? US"\n in " : US"", filename ? filename : US"");
4022a9ec
AM
831 }
832
cb4fdfcc
AM
833 /* Call the code for the different kinds of search. DEFER is handled
834@@ -511,9 +521,7 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
4022a9ec 835
cb4fdfcc
AM
836 if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength,
837 &data, &search_error_message, &do_cache) == DEFER)
838- {
839 search_find_defer = TRUE;
840- }
4022a9ec 841
cb4fdfcc
AM
842 /* A record that has been found is now in data, which is either NULL
843 or points to a bit of dynamic store. Cache the result of the lookup if
844@@ -524,10 +532,22 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
845 else if (do_cache)
846 {
847 int len = keylength + 1;
848- t = store_get(sizeof(tree_node) + len);
849- memcpy(t->name, keystring, len);
850- t->data.ptr = data;
851- tree_insertnode(&c->item_cache, t);
852+
853+ if (t) /* Previous, out-of-date cache entry. Update with the */
854+ { /* new result and forget the old one */
855+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
856+ e->ptr = data;
857+ }
858+ else
4022a9ec 859+ {
cb4fdfcc
AM
860+ t = store_get(sizeof(tree_node) + len + sizeof(expiring_data));
861+ e = (expiring_data *)((char *)t + sizeof(tree_node) + len);
862+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
863+ e->ptr = data;
864+ memcpy(t->name, keystring, len);
865+ t->data.ptr = e;
866+ tree_insertnode(&c->item_cache, t);
4022a9ec 867+ }
cb4fdfcc 868 }
4022a9ec 869
cb4fdfcc
AM
870 /* If caching was disabled, empty the cache tree. We just set the cache
871@@ -540,34 +560,19 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
872 }
873 }
4022a9ec 874
cb4fdfcc 875-/* Data was in the cache already; set the pointer from the tree node */
4022a9ec 876-
cb4fdfcc
AM
877-else
878- {
879- data = US t->data.ptr;
880- DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
881- keystring,
882- (filename == NULL)? US"" : US"\n in ",
883- (filename == NULL)? US"" : filename);
884- }
4022a9ec 885-
cb4fdfcc 886-/* Debug: output the answer */
4022a9ec 887-
cb4fdfcc
AM
888 DEBUG(D_lookup)
889 {
890- if (data == NULL)
891- {
892- if (search_find_defer) debug_printf("lookup deferred: %s\n",
893- search_error_message);
894- else debug_printf("lookup failed\n");
4022a9ec 895- }
cb4fdfcc
AM
896- else debug_printf("lookup yielded: %s\n", data);
897+ if (data)
898+ debug_printf("lookup yielded: %s\n", data);
899+ else if (search_find_defer)
900+ debug_printf("lookup deferred: %s\n", search_error_message);
901+ else debug_printf("lookup failed\n");
902 }
4022a9ec 903
cb4fdfcc 904 /* Return it in new dynamic store in the regular pool */
4022a9ec 905
cb4fdfcc
AM
906 store_pool = old_pool;
907-return (data == NULL)? NULL : string_copy(data);
908+return data ? string_copy(data) : NULL;
4022a9ec
AM
909 }
910
4022a9ec 911
4022a9ec 912diff --git a/src/src/structs.h b/src/src/structs.h
cb4fdfcc 913index 6f143d6..d9da38b 100644
4022a9ec
AM
914--- a/src/src/structs.h
915+++ b/src/src/structs.h
cb4fdfcc
AM
916@@ -657,6 +657,16 @@ typedef struct tree_node {
917 uschar name[1]; /* node name - variable length */
918 } tree_node;
919
920+/* Structure for holding time-limited data such as DNS returns.
921+We use this rather than extending tree_node to avoid wasting
922+space for most tree use (variables...) at the cost of complexity
923+for the lookups cache */
924+
925+typedef struct expiring_data {
926+ time_t expiry; /* if nonzero, data invalid after this time */
927+ void *ptr; /* pointer to data */
928+} expiring_data;
929+
930 /* Structure for holding the handle and the cached last lookup for searches.
931 This block is pointed to by the tree entry for the file. The file can get
932 closed if too many are opened at once. There is a LRU chain for deciding which
933@@ -676,6 +686,7 @@ uncompressed, but the data pointer is into the raw data. */
934 typedef struct {
935 uschar name[DNS_MAXNAME]; /* domain name */
936 int type; /* record type */
937+ unsigned short ttl; /* time-to-live, seconds */
938 int size; /* size of data */
939 uschar *data; /* pointer to data */
940 } dns_record;
941diff --git a/src/src/verify.c b/src/src/verify.c
942index e00e7b9..d392fda 100644
943--- a/src/src/verify.c
944+++ b/src/src/verify.c
945@@ -21,6 +21,7 @@ uschar ctbuffer[8192];
946 /* Structure for caching DNSBL lookups */
4022a9ec 947
cb4fdfcc
AM
948 typedef struct dnsbl_cache_block {
949+ time_t expiry;
950 dns_address *rhs;
951 uschar *text;
952 int rc;
953@@ -3584,21 +3585,37 @@ if (!string_format(query, sizeof(query), "%s.%s", prepend, domain))
4022a9ec 954
cb4fdfcc 955 /* Look for this query in the cache. */
4022a9ec 956
cb4fdfcc
AM
957-t = tree_search(dnsbl_cache, query);
958+if ( (t = tree_search(dnsbl_cache, query))
959+ && (cb = t->data.ptr)->expiry > time(NULL)
960+ )
4022a9ec 961+
cb4fdfcc 962+/* Previous lookup was cached */
4022a9ec 963+
cb4fdfcc
AM
964+ {
965+ HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
966+ }
4022a9ec 967
cb4fdfcc
AM
968 /* If not cached from a previous lookup, we must do a DNS lookup, and
969 cache the result in permanent memory. */
4022a9ec 970
cb4fdfcc
AM
971-if (t == NULL)
972+else
4022a9ec 973 {
cb4fdfcc 974+ uint ttl = 3600;
4022a9ec 975+
cb4fdfcc 976 store_pool = POOL_PERM;
4022a9ec 977
cb4fdfcc
AM
978- /* Set up a tree entry to cache the lookup */
979+ if (t)
4022a9ec 980+ {
cb4fdfcc 981+ HDEBUG(D_dnsbl) debug_printf("cached data found but past valid time; ");
4022a9ec
AM
982+ }
983
cb4fdfcc
AM
984- t = store_get(sizeof(tree_node) + Ustrlen(query));
985- Ustrcpy(t->name, query);
986- t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
987- (void)tree_insertnode(&dnsbl_cache, t);
988+ else
989+ { /* Set up a tree entry to cache the lookup */
990+ t = store_get(sizeof(tree_node) + Ustrlen(query));
991+ Ustrcpy(t->name, query);
992+ t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
993+ (void)tree_insertnode(&dnsbl_cache, t);
4022a9ec
AM
994+ }
995
cb4fdfcc 996 /* Do the DNS loopup . */
4022a9ec 997
cb4fdfcc 998@@ -3616,7 +3633,10 @@ if (t == NULL)
4022a9ec 999
cb4fdfcc
AM
1000 Quite apart from one A6 RR generating multiple addresses, there are DNS
1001 lists that return more than one A record, so we must handle multiple
1002- addresses generated in that way as well. */
1003+ addresses generated in that way as well.
1004+
1005+ Mark the cache entry with the "now" plus the minimum of the address TTLs,
1006+ or some suitably far-future time if none were found. */
4022a9ec 1007
cb4fdfcc
AM
1008 if (cb->rc == DNS_SUCCEED)
1009 {
1010@@ -3634,6 +3654,7 @@ if (t == NULL)
1011 *addrp = da;
1012 while (da->next != NULL) da = da->next;
1013 addrp = &(da->next);
1014+ if (ttl > rr->ttl) ttl = rr->ttl;
1015 }
1016 }
4022a9ec 1017 }
cb4fdfcc
AM
1018@@ -3645,17 +3666,10 @@ if (t == NULL)
1019 if (cb->rhs == NULL) cb->rc = DNS_NODATA;
4022a9ec 1020 }
4022a9ec 1021
cb4fdfcc
AM
1022+ cb->expiry = time(NULL)+ttl;
1023 store_pool = old_pool;
1024 }
4022a9ec 1025
cb4fdfcc
AM
1026-/* Previous lookup was cached */
1027-
1028-else
1029- {
1030- HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
1031- cb = t->data.ptr;
1032- }
1033-
1034 /* We now have the result of the DNS lookup, either newly done, or cached
1035 from a previous call. If the lookup succeeded, check against the address
1036 list if there is one. This may be a positive equality list (introduced by
1037
1038commit c4dcf906ceb3a45c6b30f76476d73ca836b262cd
1039Author: Jeremy Harris <jgh146exb@wizmail.org>
1040Date: Sat Sep 19 13:59:22 2015 +0100
1041
1042 Retry: always use interface, if set, for retry DB key. Bug 1678
1043
1044 Even constant values must be used, as multiple transports with
1045 different values may be in play and should be kept distinct.
1046
1047 (cherry picked from commit 6f6dedccb47f231a0712d882da20feffbac8d0bc)
1048
1049diff --git a/src/src/functions.h b/src/src/functions.h
1050index 0257904..94e3f5f 100644
1051--- a/src/src/functions.h
1052+++ b/src/src/functions.h
1053@@ -374,7 +374,7 @@ extern int smtp_sock_connect(host_item *, int, int, uschar *,
1054 extern int smtp_feof(void);
1055 extern int smtp_ferror(void);
1056 extern uschar *smtp_get_connection_info(void);
1057-extern BOOL smtp_get_interface(uschar *, int, address_item *, BOOL *,
1058+extern BOOL smtp_get_interface(uschar *, int, address_item *,
1059 uschar **, uschar *);
1060 extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
1061 extern int smtp_getc(void);
1062diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c
1063index c704a0b..2fdf38b 100644
1064--- a/src/src/smtp_out.c
1065+++ b/src/src/smtp_out.c
1066@@ -26,7 +26,6 @@ Arguments:
1067 which case the function does nothing
1068 host_af AF_INET or AF_INET6 for the outgoing IP address
1069 addr the mail address being handled (for setting errors)
1070- changed if not NULL, set TRUE if expansion actually changed istring
1071 interface point this to the interface
1072 msg to add to any error message
1073
1074@@ -36,7 +35,7 @@ Returns: TRUE on success, FALSE on failure, with error message
1075
1076 BOOL
1077 smtp_get_interface(uschar *istring, int host_af, address_item *addr,
1078- BOOL *changed, uschar **interface, uschar *msg)
1079+ uschar **interface, uschar *msg)
1080 {
1081 const uschar * expint;
1082 uschar *iface;
1083@@ -54,8 +53,6 @@ if (expint == NULL)
1084 return FALSE;
1085 }
4022a9ec 1086
cb4fdfcc
AM
1087-if (changed != NULL) *changed = expint != istring;
1088-
1089 while (isspace(*expint)) expint++;
1090 if (*expint == 0) return TRUE;
4022a9ec 1091
cb4fdfcc
AM
1092diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
1093index 5ac5533..ba7fb5e 100644
1094--- a/src/src/transports/smtp.c
1095+++ b/src/src/transports/smtp.c
1096@@ -3174,7 +3174,6 @@ for (cutoff_retry = 0; expired &&
1097 BOOL serialized = FALSE;
1098 BOOL host_is_expired = FALSE;
1099 BOOL message_defer = FALSE;
1100- BOOL ifchanges = FALSE;
1101 BOOL some_deferred = FALSE;
1102 address_item *first_addr = NULL;
1103 uschar *interface = NULL;
1104@@ -3350,15 +3349,18 @@ for (cutoff_retry = 0; expired &&
1105 if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
1106
1107 /* Select IPv4 or IPv6, and choose an outgoing interface. If the interface
1108- string changes upon expansion, we must add it to the key that is used for
1109- retries, because connections to the same host from a different interface
1110- should be treated separately. */
1111+ string is set, even if constant (as different transports can have different
1112+ constant settings), we must add it to the key that is used for retries,
1113+ because connections to the same host from a different interface should be
1114+ treated separately. */
1115
1116 host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6;
1117- if (!smtp_get_interface(ob->interface, host_af, addrlist, &ifchanges,
1118- &interface, tid))
1119- return FALSE;
1120- if (ifchanges) pistring = string_sprintf("%s/%s", pistring, interface);
1121+ if ((rs = ob->interface) && *rs)
1122+ {
1123+ if (!smtp_get_interface(rs, host_af, addrlist, &interface, tid))
1124+ return FALSE;
1125+ pistring = string_sprintf("%s/%s", pistring, interface);
1126+ }
4022a9ec 1127
cb4fdfcc
AM
1128 /* The first time round the outer loop, check the status of the host by
1129 inspecting the retry data. The second time round, we are interested only
1130diff --git a/src/src/verify.c b/src/src/verify.c
1131index d392fda..6411c7e 100644
1132--- a/src/src/verify.c
1133+++ b/src/src/verify.c
1134@@ -444,7 +444,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount.
1135
1136 host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6;
1137
1138- if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
1139+ if (!smtp_get_interface(tf->interface, host_af, addr, &interface,
1140 US"callout") ||
1141 !smtp_get_port(tf->port, addr, &port, US"callout"))
1142 log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
1143@@ -579,7 +579,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount.
1144 deliver_domain = addr->domain;
1145 transport_name = addr->transport->name;
1146
1147- if ( !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
1148+ if ( !smtp_get_interface(tf->interface, host_af, addr, &interface,
1149 US"callout")
1150 || !smtp_get_port(tf->port, addr, &port, US"callout")
1151 )
This page took 0.281695 seconds and 4 git commands to generate.