summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/src/deliver.c52
-rw-r--r--src/src/functions.h2
-rw-r--r--src/src/retry.c72
3 files changed, 42 insertions, 84 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 34f75fe13..c743fee33 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -2383,48 +2383,12 @@ while (addr_local != NULL)
retry_record->expired;
/* If we haven't reached the retry time, there is one more check
- to do, which is for the ultimate address timeout. */
+ to do, which is for the ultimate address timeout. We also do this
+ check during routing so this one might be redundant... */
if (!ok)
- {
- retry_config *retry =
- retry_find_config(retry_key+2, addr2->domain,
- retry_record->basic_errno,
- retry_record->more_errno);
-
- DEBUG(D_deliver|D_retry)
- {
- debug_printf("retry time not reached for %s: "
- "checking ultimate address timeout\n", addr2->address);
- debug_printf(" now=%d first_failed=%d next_try=%d expired=%d\n",
- (int)now, (int)retry_record->first_failed,
- (int)retry_record->next_try, retry_record->expired);
- }
-
- if (retry != NULL && retry->rules != NULL)
- {
- retry_rule *last_rule;
- for (last_rule = retry->rules;
- last_rule->next != NULL;
- last_rule = last_rule->next);
- DEBUG(D_deliver|D_retry)
- debug_printf(" received_time=%d diff=%d timeout=%d\n",
- received_time, (int)now - received_time, last_rule->timeout);
- if (now - received_time > last_rule->timeout) ok = TRUE;
- }
- else
- {
- DEBUG(D_deliver|D_retry)
- debug_printf("no retry rule found: assume timed out\n");
- ok = TRUE; /* No rule => timed out */
- }
-
- DEBUG(D_deliver|D_retry)
- {
- if (ok) debug_printf("on queue longer than maximum retry for "
- "address - allowing delivery\n");
- }
- }
+ ok = retry_ultimate_address_timeout(retry_key, addr2->domain,
+ retry_record, now);
}
}
else DEBUG(D_retry) debug_printf("no retry record exists\n");
@@ -5656,7 +5620,10 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */
will be far too many attempts for an address that gets a 4xx error. In
fact, after such an error, we should not get here because, the host should
not be remembered as one this message needs. However, there was a bug that
- used to cause this to happen, so it is best to be on the safe side. */
+ used to cause this to happen, so it is best to be on the safe side.
+
+ Even if we haven't reached the retry time in the hints, there is one
+ more check to do, which is for the ultimate address timeout. */
else if (((queue_running && !deliver_force) || continue_hostname != NULL)
&&
@@ -5666,6 +5633,9 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */
||
(address_retry_record != NULL &&
now < address_retry_record->next_try))
+ &&
+ !retry_ultimate_address_timeout(addr->address_retry_key,
+ addr->domain, address_retry_record, now)
)
{
addr->message = US"retry time not reached";
diff --git a/src/src/functions.h b/src/src/functions.h
index 174db07eb..604dd4a6a 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -269,6 +269,8 @@ extern void retry_add_item(address_item *, uschar *, int);
extern BOOL retry_check_address(uschar *, host_item *, uschar *, BOOL,
uschar **, uschar **);
extern retry_config *retry_find_config(uschar *, uschar *, int, int);
+extern BOOL retry_ultimate_address_timeout(uschar *, uschar *,
+ dbdata_retry *, time_t);
extern void retry_update(address_item **, address_item **, address_item **);
extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
extern uschar *rewrite_address_qualify(uschar *, BOOL);
diff --git a/src/src/retry.c b/src/src/retry.c
index e877bf7d0..480933542 100644
--- a/src/src/retry.c
+++ b/src/src/retry.c
@@ -17,26 +17,34 @@
*************************************************/
/* This function tests whether a message has been on the queue longer than
-the maximum retry time for a particular host.
+the maximum retry time for a particular host or address.
Arguments:
- host_key the key to look up a host retry rule
+ retry_key the key to look up a retry rule
domain the domain to look up a domain retry rule
- basic_errno a specific error number, or zero if none
- more_errno additional data for the error
+ retry_record contains error information for finding rule
now the time
Returns: TRUE if the ultimate timeout has been reached
*/
-static BOOL
-ultimate_address_timeout(uschar *host_key, uschar *domain, int basic_errno,
- int more_errno, time_t now)
+BOOL
+retry_ultimate_address_timeout(uschar *retry_key, uschar *domain,
+ dbdata_retry *retry_record, time_t now)
{
-BOOL address_timeout = TRUE; /* no rule => timed out */
+BOOL address_timeout;
+
+DEBUG(D_retry)
+ {
+ debug_printf("retry time not reached: checking ultimate address timeout\n");
+ debug_printf(" now=%d first_failed=%d next_try=%d expired=%d\n",
+ (int)now, (int)retry_record->first_failed,
+ (int)retry_record->next_try, retry_record->expired);
+ }
retry_config *retry =
- retry_find_config(host_key+2, domain, basic_errno, more_errno);
+ retry_find_config(retry_key+2, domain,
+ retry_record->basic_errno, retry_record->more_errno);
if (retry != NULL && retry->rules != NULL)
{
@@ -44,17 +52,23 @@ if (retry != NULL && retry->rules != NULL)
for (last_rule = retry->rules;
last_rule->next != NULL;
last_rule = last_rule->next);
- DEBUG(D_transport|D_retry)
+ DEBUG(D_retry)
debug_printf(" received_time=%d diff=%d timeout=%d\n",
received_time, (int)(now - received_time), last_rule->timeout);
address_timeout = (now - received_time > last_rule->timeout);
}
else
{
- DEBUG(D_transport|D_retry)
+ DEBUG(D_retry)
debug_printf("no retry rule found: assume timed out\n");
+ address_timeout = TRUE;
}
+DEBUG(D_retry)
+ if (address_timeout)
+ debug_printf("on queue longer than maximum retry for address - "
+ "allowing delivery\n");
+
return address_timeout;
}
@@ -206,25 +220,10 @@ if (host_retry_record != NULL)
if (now < host_retry_record->next_try && !deliver_force)
{
- DEBUG(D_transport|D_retry)
- {
- debug_printf("host retry time not reached: checking ultimate address "
- "timeout\n");
- debug_printf(" now=%d first_failed=%d next_try=%d expired=%d\n",
- (int)now, (int)host_retry_record->first_failed,
- (int)host_retry_record->next_try,
- host_retry_record->expired);
- }
-
if (!host_retry_record->expired &&
- ultimate_address_timeout(host_key, domain,
- host_retry_record->basic_errno, host_retry_record->more_errno, now))
- {
- DEBUG(D_transport|D_retry)
- debug_printf("on queue longer than maximum retry for "
- "address - allowing delivery\n");
+ retry_ultimate_address_timeout(host_key, domain,
+ host_retry_record, now))
return FALSE;
- }
/* We have not hit the ultimate address timeout; host is unusable. */
@@ -249,25 +248,12 @@ if (message_retry_record != NULL)
*retry_message_key = message_key;
if (now < message_retry_record->next_try && !deliver_force)
{
- DEBUG(D_transport|D_retry)
- {
- debug_printf("host+message retry time not reached: checking ultimate "
- "address timeout\n");
- debug_printf(" now=%d first_failed=%d next_try=%d expired=%d\n",
- (int)now, (int)message_retry_record->first_failed,
- (int)message_retry_record->next_try, message_retry_record->expired);
- }
- if (!ultimate_address_timeout(host_key, domain, 0, 0, now))
+ if (!retry_ultimate_address_timeout(host_key, domain,
+ message_retry_record, now))
{
host->status = hstatus_unusable;
host->why = hwhy_retry;
}
- else
- {
- DEBUG(D_transport|D_retry)
- debug_printf("on queue longer than maximum retry for "
- "address - allowing delivery\n");
- }
return FALSE;
}
}