Fix ultimate retry timeouts for intermittently deliverable recipients.
authorTony Finch <dot@dotat.at>
Thu, 29 Nov 2012 18:39:52 +0000 (18:39 +0000)
committerTony Finch <dot@dotat.at>
Thu, 29 Nov 2012 19:31:53 +0000 (19:31 +0000)
commitba9af0af397dd7d395378b883f8d9beb3bdd5ffd
tree3a817db0946196e0f83d9f90e5f9737cc4f378d7
parent29343b0827b6da8cd4e86a8afbc54070462b834b
Fix ultimate retry timeouts for intermittently deliverable recipients.

When a queue runner is handling a message, Exim first routes the
recipient addresses, during which it prunes them based on the retry
hints database. After that it attempts to deliver the message to
any remaining recipients. It then updates the hints database using
the retry rules.

So if a recipient address works intermittently, it can get repeatedly
deferred at routing time. The retry hints record remains fresh so the
address never reaches the final cutoff time.

This is a fairly common occurrence when a user is bumping up against
their storage quota. Exim had some logic in its local delivery code
to deal with this. However it did not apply to per-recipient defers
in remote deliveries, e.g. over LMTP to a separate IMAP message store.

This commit adds a proper retry rule check during routing so that
the final cutoff time is checked against the message's age. I also
took the opportunity to unify three very similar blocks of code.

I suspect this new check makes the old local delivery cutoff check
redundant, but I have not verified this so I left the code in place.
src/src/deliver.c
src/src/functions.h
src/src/retry.c