2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 13:48:06 +00:00

snapshot-20001003

This commit is contained in:
Wietse Venema
2000-10-03 00:00:00 -05:00
committed by Viktor Dukhovni
parent daf47b5f29
commit 04bda7598b
44 changed files with 1293 additions and 702 deletions

2
postfix/.indent.pro vendored
View File

@@ -17,6 +17,8 @@
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TCONFIG_TIME_FN_TABLE
-TCONFIG_TIME_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT

View File

@@ -1,67 +1,104 @@
Purpose of this document
========================
This document describes the purpose of the Postfix fast ETRN service,
how the service works, and how it can be tested.
The Postfix fast ETRN service
=============================
The SMTP ETRN command was designed for sites that have intermittent
Internet connectivity. With ETRN, a site can tell the mail server
of its network provider "Please deliver all my mail now".
of its provider to "Please deliver all my mail now".
Postfix versions before 20001001 implemented the ETRN command in
Postfix versions before 20001003 implemented the ETRN command in
a lame manner: they would attempt to deliver all queued mail. This
is slow on mail servers that queue mail for many customers.
The Postfix "fast ETRN" service speeds up deliveries by looking
As of version 20001003, Postfix has a faster ETRN implementation.
At the same time, the command "sendmail -qR" is now implemented by
sending an ETRN command to the local SMTP server.
Postfix "fast ETRN/sendmail -qR" speeds up deliveries by looking
only at mail that is queued for a given destination site. Postfix
"slow ETRN" is still used as a fall-back method.
The "fast ETRN" service uses the new "fast flush" service which
maintains per-destination logfiles of queued mail. The "fast flush"
service is enabled by default:
How Postfix fast ETRN works
===========================
fast_flush_domains = $relay_domains
The "fast ETRN" service uses the new "flush" daemon which maintains
per-destination logfiles of queued mail. These logfiles are kept
below /var/spool/postfix/flush. Each logfile is named after its
destination domain name. Only destinations with syntactically valid
domain names can have per-destination logfiles.
By default, Postfix "fast ETRN" service is available only for
destinations that the local MTA is willing to relay mail to.
The behavior of the new "flush" daemon is controlled by parameters
in the main.cf configuration file.
To disable the "fast ETRN" service, specify an empty string:
By default, Postfix "fast ETRN/sendmail -qR" service is available
only for destinations that Postfix is willing to relay mail to:
fast_flush_domains =
fast_flush_policy = relay
The syntax of the fast_flush_domains parameter is exactly the
same as for the relay_domains parameter: a list of domain names,
files with domain names, or maptype:mapname lookup tables where
the right-hand side is ignored.
For destinations that cannot have "fast ETRN" service, Postfix
falls back to the old "slow ETRN" service that attempts to deliver
The relay_domains parameter specifies what destinations Postfix
will relay to. For destinations without "fast ETRN/sendmail -qR"
service, Postfix falls back to the old "slow ETRN" which delivers
all queued mail.
By default, every site can issue ETRN commands to your SMTP
server:
To enable "fast ETRN/sendmail -qR" for all destinations, specify:
smtpd_etrn_restrictions =
fast_flush_policy = all
To disable "fast ETRN/sendmail -qR", so that Postfix always uses
the old "slow ETRN" which delivers all queued mail, specify:
fast_flush_policy = none
Testing the fast ETRN service
=============================
If you run Postfix with "fast ETRN" service for the very first
time, you need to run "sendmail -q" to populate the per-site deferred
mail logfiles. If you omit this step, the logfiles will eventually
become populated as Postfix routinely attempts to deliver delayed
mail, but that will take a couple hours.
To test the "fast ETRN" service, telnet to the Postfix SMTP server
from a client that is allowed to execute ETRN commands, and type:
from a client that is allowed to execute ETRN commands (by default,
that's every client), and type:
helo my.client.name
etrn some.customer.domain
where "some.customer.domain" is the name of a domain that your mail
server is willing to relay mail to.
server is willing to relay mail to, and that your server has some
mail queued for.
In the maillog file, you should see something logged like:
In the maillog file, you should immediately see a couple of logfile
records, as evidence that the queue manager has opened queue files:
created fast ETRN cache for some.customer.domain
Oct 2 10:51:19 localhost postfix/qmgr[51999]: 682E8440A4:
from=<whatever>, size=12345, nrcpt=1 (queue active)
Oct 2 10:51:19 localhost postfix/qmgr[51999]: 02249440B7:
from=<whatever>, size=4711, nrcpt=1 (queue active)
It will then do a "slow ETRN" once. The next time the same ETRN
command is given, Postfix will do "fast ETRN".
What happens next depends on whether the destination is reachable.
If Postfix logs that it cannot create a fast ETRN cache for
"some.customer.domain", then execute the command "postfix check".
You probably skipped some installation instructions so that the
necessary directories were not created.
Repeat the exercise with another domain that your server is willing
to relay to, but that has no mail queued.
If Postfix logs that it uses slow ETRN service for "some.customer.domain",
instead of creating a fast ETRN cache, then either "some.customer.domain"
was not found in the DNS, or it was not listed as a valid fast ETRN
destination. Check your fast_flush_domains or relay_domains settings.
helo my.client.name
etrn some.other.customer.domain
This time, the "etrn" command should not trigger any mail deliveries
at all.
Finally, repeat the exercise with a destination that your mail
server is not willing to relay to. It does not matter if your
server has mail queued for that destination.
helo my.client.name
etrn not.a.customer.domain
If your "fast ETRN" caching policy is left at its default setting,
then the "etrn" command should trigger delivery of all queued mail.

View File

@@ -4300,10 +4300,12 @@ Apologies for any names omitted.
rid of them. To disallow, specify "strict_rfc821_envelopes
= yes". File: smtpd/smtpd.c.
20000926-8
20000926-20001003
First implementation of a logfile-based fast flush server,
which is the basis for ETRN and "sendmail -qRsite".
Feature: a "flush" server that keeps per-destination records
of deferred mail. It is the basis of a faster ETRN and
"sendmail -qRsite" implementation. This code was rewritten
half a dozen times.
20000928
@@ -4319,3 +4321,22 @@ Apologies for any names omitted.
Robustness? Log errors from SASL library code as warnings
not as fatal errors. Files: smtp*/*glue.c.
20001001
Feature: in master.cf, specify ? after wakeup time to avoid
waking up services that aren't being used.
20001003
Feature: the fast flush refresh and purge time interval
parameters can now be specified in seconds or in user-specified
units by providing an appropriate suffix: s (seconds), m
(minutes), h (hours), d (days), w (weeks). unit. This
was needed so that I could test the flush server code in
a reasonable way. Other time parameters will be migrated
as time permits. Files: global/mail_conf_time.c,
postconf/postconf.c.
Unfeature: qmgr_hog_factor is now disabled by default. It
was just too confusing.

View File

@@ -1,4 +1,4 @@
Incompatible changes with snapshot-20000928
Incompatible changes with snapshot-20001003
===========================================
If this release does not work for you, you can go back to a previous
@@ -12,13 +12,6 @@ again.
After installing the new Postfix release:
- Check the output from "postconf qmgr_message_active_limit". The
recommended value has changed to 10000.
If your setting is lower, either you need to remove the explicit
setting from the main.cf file (so that Postfix uses the recommended
default setting), or you need to update it.
- Check the output from "postconf hash_queue_names". The recommended
setting now includes the names of the "active", "bounce", "defer",
and "flush" directories.
@@ -28,25 +21,32 @@ After installing the new Postfix release:
file (so that Postfix uses the recommended default setting), or
you need to update it.
- Check the output from "postconf qmgr_message_active_limit". The
recommended value has changed to 10000.
If your setting is lower, either you need to remove the explicit
setting from the main.cf file (so that Postfix uses the recommended
default setting), or you need to update it.
- Add a new entry to the master.cf file for the new flush service:
flush unix - - n 18000? 0 flush
flush unix - - n 1000? 0 flush
This entry is not needed if you won't use the fast flush service
(this service is used by default; to disable, you need to specify
in the main.cf file an empty fast_flush_domains parameter:
This entry is not needed if you won't use the fast flush service.
This service is used by default; to disable the fast flush service,
you need to specify in the main.cf file:
fast_flush_domains =
fast_flush_policy = none
The 18000? requests that the "fast flush" service does some
cleaning up every 5 hours, but only if the fast flush service is
being used by some other Postfix service, and the 0 means that
Postfix should run as many flush servers as are needed, in order
to avoid deadlock conditions.
In the new master.cf entry, the 1000? requests that the "fast
flush" service does some cleaning up every 15 minutes, but only
if the fast flush service is actually being used. The 0 means
that Postfix should run as many flush servers as are needed.
Changing this may cause deadlock.
Now you can start Postfix again.
Major changes with snapshot-20000929
Major changes with snapshot-20001001
====================================
In order to improve performance of one-to-one deliveries, Postfix
@@ -55,22 +55,24 @@ by default now looks at up to 10000 messages at a time (was: 1000).
Until now, Postfix did a rather lame effort at implementing the
SMTP ETRN command - it attempted to deliver all mail in the queue,
regardless of its destination. This is slow if your mail server
queues mail for lots of different sites.
queues mail for lots of different destinations.
This release introduces "fast ETRN", which delivers only mail that
is known to be queued for the specified site. Postfix now maintains
so-called "fast flush" logfiles with information about what mail
is queued for specific sites. A "fast flush" logfile is "flushed"
after Postfix receives an appropriate ETRN command, or after someone
executes the command "sendmail -qRsite" for an appropriate site.
This release introduces fast "ETRN" and "sendmail -qR". Unlike
their lame predecessor, these deliver only mail that is queued for
the specified destinations.
A missing "fast flush" logfile is created automatically when an
SMTP client issues the ETRN command - but only for destinations
that the local MTA is willing to relay mail to. This policy is
controlled with the "fast_etrn_domains" configuration parameter
(default: $relay_domains). Other destinations remain stuck with
the old "slow ETRN" service that attempts to deliver all mail in
the queue.
Postfix now maintains per-destination logfiles with information
about what mail is queued for specific destinations. By default,
these logfiles are maintained only for destinations that Postfix
is willing to relay to (as controlled by the relay_domains parameter).
The maintenance policy for deferred mail logfiles is selected with
the "fast_flush_policy" configuration parameter. Possible values
are: "all" (maintain logs for all destinations), "relay" (maintain
logs for relay destinations) or "none" (maintain no logs).
Postfix falls back to the old slow ETRN for destinations that are
not eligible for the fast "ETRN" and "sendmail -qR" service.
See the file ETRN_README for details.

View File

@@ -343,17 +343,25 @@ mail_owner = postfix
# FAST ETRN SERVICE
#
# By default, Postfix does a rather lame effort at implementing the
# SMTP ETRN command - it attempts to deliver all queued mail regardless
# of its destination. This does not work well if your mail server
# queues mail for lots of sites. In order to enable a faster ETRN
# that only delivers mail that is known to be queued for a site,
# enable the fast flush cache. Currently, "fast ETRN" is available
# only for destinations that the local system is willing to relay
# mail to (as specified in the relay_domains parameter).
# Postfix maintains per-destination logfiles with information about
# deferred mail, so that mail can be flushed quickly with the SMTP
# "ETRN domain.name" command, or by executing "sendmail -qRdomain.name".
#
#enable_fast_flush = yes
#enable_fast_flush = no
# By default, Postfix maintains deferred mail logfile information
# only for destinations that Postfix is willing to relay to (as
# specified in the relay_domains parameter). For other destinations,
# Postfix attempts to deliver ALL queued mail after receiving the
# SMTP "ETRN domain.name" command, or after execution of "sendmail
# -qRdomain.name". This can be slow when a lot of mail is queued.
#
# The fast_flush_policy controls what destinations are eligible for
# this "fast ETRN/sendmail -qR" service. Specify "all" to make all
# destinations eligible, "relay" for relay destinations only, and
# "none" to turn this feature off.
#
#fast_flush_policy = all
#fast_flush_policy = relay
#fast_flush_policy = none
# SHOW SOFTWARE VERSION OR NOT
#

View File

@@ -75,7 +75,7 @@ qmgr fifo n - n 300 1 qmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
flush unix - - n 18000? 0 flush
flush unix - - n 1000? 0 flush
smtp unix - - n - - smtp
showq unix n - n - - showq
error unix - - n - - error

View File

@@ -6,58 +6,58 @@ FLUSH(8) FLUSH(8)
<b>NAME</b>
flush - Postfix fast flush daemon
flush - Postfix fast flush cache manager
<b>SYNOPSIS</b>
<b>flush</b> [generic Postfix daemon options]
<b>DESCRIPTION</b>
The flush server maintains so-called "fast flush" logfiles
with information about what messages are queued for a spe-
cific site. This program expects to be run from the <a href="master.8.html"><b>mas-</b>
<b>ter</b>(8)</a> process manager.
The flush server maintains a record of deferred mail by
destination. This information is used to improve the per-
formance of the SMTP <b>ETRN</b> request, and of its command-line
equivalent, <b>sendmail</b> <b>-qR</b>. This program expects to be run
from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
The record is implemented as per-destination logfiles with
as contents the queue IDs of deferred mail. The files are
append-only, and are truncated when delivery is requested
for a specific site.
Deferred mail by destination information is recorded only
for destinations that are eligible according to a config-
urable policy. The policy is specified with the
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>cache</b><i>_</i><b>policy</b> configuration parameter:
<b>all</b> Maintain per-destination deferred mail logfiles for
all destinations.
<b>relay</b> Maintain per-destination deferred mail logfiles
only for destinations that this system is willing
to relay mail to ($<b>relay</b><i>_</i><b>domains</b>).
<b>none</b> Do not maintain per-destination deferred mail log-
files.
This server implements the following requests:
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>ENABLE</b> <i>sitename</i>
Enable fast flush logging for the specified site.
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>APPEND</b> <i>sitename</i> <i>queue_id</i>
Append <i>queue_id</i> to the fast flush log for the spec-
ified site.
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>ADD</b> <i>sitename</i> <i>queue_id</i>
Inform the cache manager that the specified message
is queued for the specified site. Depending on
caching policy, the cache manager stores or ignores
the information.
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>SEND</b> <i>sitename</i>
Arrange for the delivery of all messages that are
listed in the fast flush logfile for the specified
site. After the logfile is processed, the file is
truncated to length zero.
Request delivery of all messages that are queued
for the specified site. Depending on cache policy,
this triggers delivery of specific messages or of
all queued mail. The per-destination logfile is
discarded.
<b>TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP</b> (wakeup signal from master)
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>PURGE</b>
Pretend that <b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>SEND</b> was received for all
sites with a non-empty "fast flush" logfile, and
delete empty "fast flush" logfiles that have not
been updated in several days. This operation com-
pletes in the background because it can take a
noticeable amount of time.
Fast flush logfiles are truncated only after a
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>SEND</b> request, not when mail is actually
delivered, and therefore can accumulate redundant
or even outdated information. In order to maintain
sanity, <b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>PURGE</b> must be requested occasion-
ally.
The response to the client is one of:
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>OK</b>
The request completed normally.
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>BAD</b>
The flush server rejected the request (bad request
name, bad request parameter value).
Delete empty per-destination logfiles that haven't
been updated in $<b>fast</b><i>_</i><b>flush</b><i>_</i><b>purge</b><i>_</i><b>delay</b> seconds.
@@ -71,8 +71,32 @@ FLUSH(8) FLUSH(8)
FLUSH(8) FLUSH(8)
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>UNKNOWN</b>
The specified site has no fast flush log.
Refresh non-empty per-destination logfiles that
were not read in $<b>fast</b><i>_</i><b>flush</b><i>_</i><b>refresh</b><i>_</i><b>delay</b> seconds.
This is done by pretending that send requests were
received for the corresponding sites.
Fast flush logfiles are truncated only after a
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>SEND</b> request, not when mail is actually
delivered, and therefore can accumulate outdated or
redundant data. In order to maintain sanity,
<b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>PURGE</b> should be requested at regular
imtervals.
After an initial sanity check of request parame-
ters, this request proceeds in the background.
The response to the client is one of:
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>OK</b>
The request completed normally.
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>BAD</b>
The flush server rejected the request (bad request
name, bad request parameter value).
<b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>FAIL</b>
The request failed.
<b>SECURITY</b>
The fast flush server is not security-sensitive. It does
@@ -84,10 +108,43 @@ FLUSH(8) FLUSH(8)
Problems and transactions are logged to <b>syslogd</b>(8).
<b>BUGS</b>
In reality, this server schedules delivery of messages,
regardless of their destination. This limitation is due to
the fact that one queue runner has to handle mail for mul-
tiple destinations.
In reality, this server schedules delivery of all recipi-
ents of deferred messages. This limitation is due to the
fact that one queue runner has to handle mail for multiple
destinations.
<b>FILES</b>
/var/spool/postfix/flush, location of "fast flush" logfiles.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
See the Postfix <b>main.cf</b> file for syntax details and for
default values. Use the <b>postfix</b> <b>reload</b> command after a
configuration change.
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>cache</b><i>_</i><b>policy</b>
What destinations can have a "fast flush" logfile:
<b>all</b>, <b>relay</b> (relay destinations) or <b>none</b>.
2
FLUSH(8) FLUSH(8)
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>refresh</b><i>_</i><b>delay</b>
Refresh a non-empty "fast flush" logfile that was
not read in this amount of time, by simulating a
send request for the corresponding destination.
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>purge</b><i>_</i><b>delay</b>
Remove an empty "fast flush" logfile that was not
updated in this amount of time.
<b>SEE</b> <b>ALSO</b>
<a href="smtpd.8.html">smtpd(8)</a> Postfix SMTP server
@@ -128,7 +185,16 @@ FLUSH(8) FLUSH(8)
2
3
</pre> </body> </html>

View File

@@ -228,19 +228,6 @@ SMTPD(8) SMTPD(8)
SMTP session before it is penalized with tarpit
delays.
<b>ETRN</b> <b>controls</b>
<b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
Restrict what domain names can be used in <b>ETRN</b> com-
mands, and what clients may issue <b>ETRN</b> commands.
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>domains</b>
The destinations that this system is willing to
provide "fast ETRN" service for. By default, "fast
ETRN" service is available only for destinations
that the local system is willing to relay mail to.
For other destinations, Postfix simply attempts to
deliver all mail in the queue.
<b>UCE</b> <b>control</b> <b>restrictions</b>
<b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
Restrict what clients may connect to this mail sys-
@@ -258,6 +245,19 @@ SMTPD(8) SMTPD(8)
Restrict what sender addresses are allowed in <b>MAIL</b>
<b>FROM</b> commands.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
<b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
Restrict what domain names can be used in <b>ETRN</b> com-
mands, and what clients may issue <b>ETRN</b> commands.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
Allow untrusted clients to specify addresses with
sender-specified routing. Enabling this opens up
nasty relay loopholes involving trusted backup MX
4
@@ -269,60 +269,60 @@ SMTPD(8) SMTPD(8)
SMTPD(8) SMTPD(8)
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
Allow untrusted clients to specify addresses with
sender-specified routing. Enabling this opens up
nasty relay loopholes involving trusted backup MX
hosts.
<b>restriction</b><i>_</i><b>classes</b>
Declares the name of zero or more parameters that
contain a list of UCE restrictions. The names of
these parameters can then be used instead of the
Declares the name of zero or more parameters that
contain a list of UCE restrictions. The names of
these parameters can then be used instead of the
restriction lists that they represent.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
List of DNS domains that publish the addresses of
List of DNS domains that publish the addresses of
blacklisted hosts.
<b>relay</b><i>_</i><b>domains</b>
Restrict what domains or networks this mail system
Restrict what domains or networks this mail system
will relay mail from or to.
<b>UCE</b> <b>control</b> <b>responses</b>
<b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates an access
Server response when a client violates an access
database restriction.
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates the
Server response when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates the
Server response when a client violates the
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> restriction.
<b>reject</b><i>_</i><b>code</b>
Response code when the client matches a <b>reject</b>
Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client attempts to violate
Server response when a client attempts to violate
the mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates the
Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client without address to
name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
Server response when a client without address to
name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
restriction.
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> message canonicalization
<a href="master.8.html">master(8)</a> process manager
syslogd(8) system logging
@@ -335,17 +335,8 @@ SMTPD(8) SMTPD(8)
SMTPD(8) SMTPD(8)
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> message canonicalization
<a href="master.8.html">master(8)</a> process manager
syslogd(8) system logging
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
@@ -382,6 +373,15 @@ SMTPD(8) SMTPD(8)

View File

@@ -4,7 +4,7 @@
.SH NAME
flush
\-
Postfix fast flush daemon
Postfix fast flush cache manager
.SH SYNOPSIS
.na
.nf
@@ -12,33 +12,56 @@ Postfix fast flush daemon
.SH DESCRIPTION
.ad
.fi
The flush server maintains so-called "fast flush" logfiles with
information about what messages are queued for a specific site.
The flush server maintains a record of deferred mail by destination.
This information is used to improve the performance of the SMTP
\fBETRN\fR request, and of its command-line equivalent,
\fBsendmail -qR\fR.
This program expects to be run from the \fBmaster\fR(8) process
manager.
The record is implemented as per-destination logfiles with
as contents the queue IDs of deferred mail. The files are
append-only, and are truncated when delivery is requested
for a specific site.
Deferred mail by destination information is recorded only for
destinations that are eligible according to a configurable policy.
The policy is specified with the \fBfast_flush_cache_policy\fR
configuration parameter:
.IP \fBall\fR
Maintain per-destination deferred mail logfiles for all destinations.
.IP \fBrelay\fR
Maintain per-destination deferred mail logfiles only for destinations
that this system is willing to relay mail to ($\fBrelay_domains\fR).
.IP \fBnone\fR
Do not maintain per-destination deferred mail logfiles.
.PP
This server implements the following requests:
.IP "\fBFLUSH_REQ_ENABLE\fI sitename\fR"
Enable fast flush logging for the specified site.
.IP "\fBFLUSH_REQ_APPEND\fI sitename queue_id\fR"
Append \fIqueue_id\fR to the fast flush log for the
specified site.
.IP "\fBFLUSH_REQ_ADD\fI sitename queue_id\fR"
Inform the cache manager that the specified message is queued for
the specified site. Depending on caching policy, the cache manager
stores or ignores the information.
.IP "\fBFLUSH_REQ_SEND\fI sitename\fR"
Arrange for the delivery of all messages that are listed in the fast
flush logfile for the specified site. After the logfile is processed,
the file is truncated to length zero.
Request delivery of all messages that are queued for the specified
site. Depending on cache policy, this triggers delivery of specific
messages or of all queued mail. The per-destination logfile is
discarded.
.IP "\fBTRIGGER_REQ_WAKEUP\fR (wakeup signal from master)"
.IP "\fBFLUSH_REQ_PURGE\fR"
Pretend that \fBFLUSH_REQ_SEND\fR was received for all sites with
a non-empty "fast flush" logfile, and delete empty "fast flush"
logfiles that have not been updated in several days. This operation
completes in the background because it can take a noticeable
amount of time.
Delete empty per-destination logfiles that haven't been updated in
$\fBfast_flush_purge_delay\fR seconds.
.sp
Refresh non-empty per-destination logfiles that were not read in
$\fBfast_flush_refresh_delay\fR seconds. This is done by pretending
that send requests were received for the corresponding sites.
.sp
Fast flush logfiles are truncated only after a \fBFLUSH_REQ_SEND\fR
request, not when mail is actually delivered, and therefore can
accumulate redundant or even outdated information. In order to
maintain sanity, \fBFLUSH_REQ_PURGE\fR must be requested occasionally.
accumulate outdated or redundant data. In order to maintain sanity,
\fBFLUSH_REQ_PURGE\fR should be requested at regular imtervals.
.sp
After an initial sanity check of request parameters, this request
proceeds in the background.
.PP
The response to the client is one of:
.IP \fBFLUSH_STAT_OK\fR
@@ -46,8 +69,8 @@ The request completed normally.
.IP \fBFLUSH_STAT_BAD\fR
The flush server rejected the request (bad request name, bad
request parameter value).
.IP \fBFLUSH_STAT_UNKNOWN\fR
The specified site has no fast flush log.
.IP \fBFLUSH_STAT_FAIL\fR
The request failed.
.SH SECURITY
.na
.nf
@@ -63,9 +86,31 @@ Problems and transactions are logged to \fBsyslogd\fR(8).
.SH BUGS
.ad
.fi
In reality, this server schedules delivery of messages, regardless
of their destination. This limitation is due to the fact that
In reality, this server schedules delivery of all recipients
of deferred messages. This limitation is due to the fact that
one queue runner has to handle mail for multiple destinations.
.SH FILES
.na
.nf
/var/spool/postfix/flush, location of "fast flush" logfiles.
.SH CONFIGURATION PARAMETERS
.na
.nf
.ad
.fi
See the Postfix \fBmain.cf\fR file for syntax details and for
default values. Use the \fBpostfix reload\fR command after a
configuration change.
.IP \fBfast_flush_cache_policy\fR
What destinations can have a "fast flush" logfile: \fBall\fR,
\fBrelay\fR (relay destinations) or \fBnone\fR.
.IP \fBfast_flush_refresh_delay\fR
Refresh a non-empty "fast flush" logfile that was not read in
this amount of time, by simulating a send request for the
corresponding destination.
.IP \fBfast_flush_purge_delay\fR
Remove an empty "fast flush" logfile that was not updated in
this amount of time.
.SH SEE ALSO
.na
.nf

View File

@@ -165,18 +165,6 @@ Disconnect after a client has made this number of errors.
Limit the number of times a client can issue a junk command
such as NOOP, VRFY, ETRN or RSET in one SMTP session before
it is penalized with tarpit delays.
.SH "ETRN controls"
.ad
.fi
.IP \fBsmtpd_etrn_restrictions\fR
Restrict what domain names can be used in \fBETRN\fR commands,
and what clients may issue \fBETRN\fR commands.
.IP \fBfast_flush_domains\fR
The destinations that this system is willing to provide "fast ETRN"
service for. By default, "fast ETRN" service is available only
for destinations that the local system is willing to relay mail to.
For other destinations, Postfix simply attempts to deliver all mail
in the queue.
.SH "UCE control restrictions"
.ad
.fi
@@ -192,6 +180,9 @@ Restrict what client hostnames are allowed in \fBHELO\fR and
Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands.
.IP \fBsmtpd_recipient_restrictions\fR
Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands.
.IP \fBsmtpd_etrn_restrictions\fR
Restrict what domain names can be used in \fBETRN\fR commands,
and what clients may issue \fBETRN\fR commands.
.IP \fBallow_untrusted_routing\fR
Allow untrusted clients to specify addresses with sender-specified
routing. Enabling this opens up nasty relay loopholes involving

View File

@@ -66,11 +66,15 @@ flush.o: ../../include/valid_hostname.h
flush.o: ../../include/htable.h
flush.o: ../../include/dict.h
flush.o: ../../include/argv.h
flush.o: ../../include/scan_dir.h
flush.o: ../../include/mail_params.h
flush.o: ../../include/mail_queue.h
flush.o: ../../include/mail_proto.h
flush.o: ../../include/iostuff.h
flush.o: ../../include/mail_flush.h
flush.o: ../../include/flush_clnt.h
flush.o: ../../include/mail_conf.h
flush.o: ../../include/mail_scan_dir.h
flush.o: ../../include/maps.h
flush.o: ../../include/domain_list.h
flush.o: ../../include/mail_server.h

View File

@@ -2,37 +2,60 @@
/* NAME
/* flush 8
/* SUMMARY
/* Postfix fast flush daemon
/* Postfix fast flush cache manager
/* SYNOPSIS
/* \fBflush\fR [generic Postfix daemon options]
/* DESCRIPTION
/* The flush server maintains so-called "fast flush" logfiles with
/* information about what messages are queued for a specific site.
/* The flush server maintains a record of deferred mail by destination.
/* This information is used to improve the performance of the SMTP
/* \fBETRN\fR request, and of its command-line equivalent,
/* \fBsendmail -qR\fR.
/* This program expects to be run from the \fBmaster\fR(8) process
/* manager.
/*
/* The record is implemented as per-destination logfiles with
/* as contents the queue IDs of deferred mail. The files are
/* append-only, and are truncated when delivery is requested
/* for a specific site.
/*
/* Deferred mail by destination information is recorded only for
/* destinations that are eligible according to a configurable policy.
/* The policy is specified with the \fBfast_flush_cache_policy\fR
/* configuration parameter:
/* .IP \fBall\fR
/* Maintain per-destination deferred mail logfiles for all destinations.
/* .IP \fBrelay\fR
/* Maintain per-destination deferred mail logfiles only for destinations
/* that this system is willing to relay mail to ($\fBrelay_domains\fR).
/* .IP \fBnone\fR
/* Do not maintain per-destination deferred mail logfiles.
/* .PP
/* This server implements the following requests:
/* .IP "\fBFLUSH_REQ_ENABLE\fI sitename\fR"
/* Enable fast flush logging for the specified site.
/* .IP "\fBFLUSH_REQ_APPEND\fI sitename queue_id\fR"
/* Append \fIqueue_id\fR to the fast flush log for the
/* specified site.
/* .IP "\fBFLUSH_REQ_ADD\fI sitename queue_id\fR"
/* Inform the cache manager that the specified message is queued for
/* the specified site. Depending on caching policy, the cache manager
/* stores or ignores the information.
/* .IP "\fBFLUSH_REQ_SEND\fI sitename\fR"
/* Arrange for the delivery of all messages that are listed in the fast
/* flush logfile for the specified site. After the logfile is processed,
/* the file is truncated to length zero.
/* Request delivery of all messages that are queued for the specified
/* site. Depending on cache policy, this triggers delivery of specific
/* messages or of all queued mail. The per-destination logfile is
/* discarded.
/* .IP "\fBTRIGGER_REQ_WAKEUP\fR (wakeup signal from master)"
/* .IP "\fBFLUSH_REQ_PURGE\fR"
/* Pretend that \fBFLUSH_REQ_SEND\fR was received for all sites with
/* a non-empty "fast flush" logfile, and delete empty "fast flush"
/* logfiles that have not been updated in several days. This operation
/* completes in the background because it can take a noticeable
/* amount of time.
/* Delete empty per-destination logfiles that haven't been updated in
/* $\fBfast_flush_purge_delay\fR seconds.
/* .sp
/* Refresh non-empty per-destination logfiles that were not read in
/* $\fBfast_flush_refresh_delay\fR seconds. This is done by pretending
/* that send requests were received for the corresponding sites.
/* .sp
/* Fast flush logfiles are truncated only after a \fBFLUSH_REQ_SEND\fR
/* request, not when mail is actually delivered, and therefore can
/* accumulate redundant or even outdated information. In order to
/* maintain sanity, \fBFLUSH_REQ_PURGE\fR must be requested occasionally.
/* request, not when mail is actually delivered, and therefore can
/* accumulate outdated or redundant data. In order to maintain sanity,
/* \fBFLUSH_REQ_PURGE\fR should be requested at regular imtervals.
/* .sp
/* After an initial sanity check of request parameters, this request
/* proceeds in the background.
/* .PP
/* The response to the client is one of:
/* .IP \fBFLUSH_STAT_OK\fR
@@ -40,8 +63,8 @@
/* .IP \fBFLUSH_STAT_BAD\fR
/* The flush server rejected the request (bad request name, bad
/* request parameter value).
/* .IP \fBFLUSH_STAT_UNKNOWN\fR
/* The specified site has no fast flush log.
/* .IP \fBFLUSH_STAT_FAIL\fR
/* The request failed.
/* SECURITY
/* .ad
/* .fi
@@ -51,9 +74,27 @@
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS
/* In reality, this server schedules delivery of messages, regardless
/* of their destination. This limitation is due to the fact that
/* In reality, this server schedules delivery of all recipients
/* of deferred messages. This limitation is due to the fact that
/* one queue runner has to handle mail for multiple destinations.
/* FILES
/* /var/spool/postfix/flush, location of "fast flush" logfiles.
/* CONFIGURATION PARAMETERS
/* .ad
/* .fi
/* See the Postfix \fBmain.cf\fR file for syntax details and for
/* default values. Use the \fBpostfix reload\fR command after a
/* configuration change.
/* .IP \fBfast_flush_cache_policy\fR
/* What destinations can have a "fast flush" logfile: \fBall\fR,
/* \fBrelay\fR (relay destinations) or \fBnone\fR.
/* .IP \fBfast_flush_refresh_delay\fR
/* Refresh a non-empty "fast flush" logfile that was not read in
/* this amount of time, by simulating a send request for the
/* corresponding destination.
/* .IP \fBfast_flush_purge_delay\fR
/* Remove an empty "fast flush" logfile that was not updated in
/* this amount of time.
/* SEE ALSO
/* smtpd(8) Postfix SMTP server
/* qmgr(8) Postfix queue manager
@@ -97,9 +138,11 @@
#include <mail_queue.h>
#include <mail_proto.h>
#include <mail_flush.h>
#include <flush_clnt.h>
#include <mail_conf.h>
#include <mail_scan_dir.h>
#include <maps.h>
#include <domain_list.h>
/* Single server skeleton. */
@@ -107,28 +150,97 @@
/* Application-specific. */
#define STR(x) vstring_str(x)
/*
* Tunable parameters.
*/
int var_fflush_refresh;
int var_fflush_purge;
char *var_relay_domains;
/*
* Flush policy stuff.
*/
#define FLUSH_POLICY_UNKNOWN 0
#define FLUSH_POLICY_ALL 1
#define FLUSH_POLICY_RELAY 2
#define FLUSH_POLICY_NONE 3
static DOMAIN_LIST *flush_domains;
static int flush_policy = FLUSH_POLICY_UNKNOWN;
/*
* Some hard-wired policy: how many queue IDs we remember while we're
* flushing a logfile.
*/
#define FLUSH_DUP_FILTER_SIZE 10000 /* graceful degradation */
#define FLUSH_MAX_UNUSED (7 * 24 * 60 * 60)
/* flush_append - append queue ID to per-site fast flush log */
/*
* Silly little macros.
*/
static int flush_append(const char *site, const char *queue_id)
#define STR(x) vstring_str(x)
#define STREQ(x,y) (strcmp(x,y) == 0)
/* flush_policy_init - initialize fast flush policy stuff */
static int flush_policy_init(void)
{
char *myname = "flush_append";
if (STREQ(var_fflush_policy, FFLUSH_POLICY_ALL)) {
flush_policy = FLUSH_POLICY_ALL;
} else if (STREQ(var_fflush_policy, FFLUSH_POLICY_RELAY)) {
flush_domains = domain_list_init(var_relay_domains);
flush_policy = FLUSH_POLICY_RELAY;
} else if (STREQ(var_fflush_policy, FFLUSH_POLICY_NONE)) {
flush_policy = FLUSH_POLICY_NONE;
} else {
msg_fatal("invalid %s configuration parameter value: %s",
VAR_FFLUSH_POLICY, var_fflush_policy);
}
}
/* flush_policy_ok - check caching policy */
static int flush_policy_ok(const char *site)
{
if (flush_policy == FLUSH_POLICY_UNKNOWN)
flush_policy_init();
switch (flush_policy) {
case FLUSH_POLICY_ALL:
return (1);
case FLUSH_POLICY_RELAY:
return (domain_list_match(flush_domains, site));
case FLUSH_POLICY_NONE:
return (0);
default:
msg_panic("invalid fast flush policy %d", flush_policy);
}
}
/* flush_add_service - append queue ID to per-site fast flush log */
static int flush_add_service(const char *site, const char *queue_id)
{
char *myname = "flush_add_service";
VSTREAM *log;
if (msg_verbose)
msg_info("%s: site %s queue_id %s", myname, site, queue_id);
/*
* Open the logfile.
* If this site is not eligible for caching, just ignore the request.
*/
if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_APPEND | O_WRONLY, 0600)) == 0) {
if (errno != ENOENT)
msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
return (FLUSH_STAT_UNKNOWN);
}
if (flush_policy_ok(site) == 0)
return (FLUSH_STAT_OK);
/*
* Open the logfile or bust.
*/
if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site,
O_CREAT | O_APPEND | O_WRONLY, 0600)) == 0)
msg_fatal("%s: open fast flush log for site %s: %m",
myname, site);
/*
* We must lock the logfile, so that we don't lose information due to
@@ -158,11 +270,11 @@ static int flush_append(const char *site, const char *queue_id)
return (FLUSH_STAT_OK);
}
/* flush_site - flush mail queued for site */
/* flush_send_service - flush mail queued for site */
static int flush_site(const char *site)
static int flush_send_service(const char *site)
{
char *myname = "flush_site";
char *myname = "flush_send_service";
VSTRING *queue_id;
VSTRING *queue_file;
VSTREAM *log;
@@ -178,12 +290,19 @@ static int flush_site(const char *site)
msg_info("%s: site %s", myname, site);
/*
* Open the logfile.
* If this site is not eligible for caching, deliver all queued mail.
*/
if (flush_policy_ok(site) == 0)
return (mail_flush_deferred());
/*
* Open the logfile. If the file does not exist, then there is no queued
* mail for this destination.
*/
if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_RDWR, 0600)) == 0) {
if (errno != ENOENT)
msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
return (FLUSH_STAT_UNKNOWN);
return (FLUSH_STAT_OK);
}
/*
@@ -198,11 +317,10 @@ static int flush_site(const char *site)
/*
* This is the part that dominates running time: schedule the listed
* queue files for delivery by updating their file time stamps. This
* should take no more than a couple seconds under normal conditions
* (sites that receive millions of messages in a day should not use fast
* flush service). Filter out duplicate names to avoid hammering the file
* system, with some finite limit on the amount of memory that we are
* willing to sacrifice. Graceful degradation.
* should take no more than a couple seconds under normal conditions.
* Filter out duplicate names to avoid hammering the file system, with
* some finite limit on the amount of memory that we are willing to
* sacrifice. Graceful degradation.
*/
queue_id = vstring_alloc(10);
queue_file = vstring_alloc(10);
@@ -228,11 +346,12 @@ static int flush_site(const char *site)
msg_warn("%s: update %s time stamps: %m",
myname, STR(queue_file));
} else if (mail_queue_rename(STR(queue_id), MAIL_QUEUE_DEFERRED,
MAIL_QUEUE_INCOMING) < 0
&& errno != ENOENT)
msg_warn("%s: rename from %s to %s: %m",
STR(queue_file), MAIL_QUEUE_DEFERRED,
MAIL_QUEUE_INCOMING);
MAIL_QUEUE_INCOMING) < 0) {
if (errno != ENOENT)
msg_warn("%s: rename from %s to %s: %m",
STR(queue_file), MAIL_QUEUE_DEFERRED,
MAIL_QUEUE_INCOMING);
}
} else {
if (msg_verbose)
msg_info("%s: site %s: skip file %s as duplicate",
@@ -247,8 +366,7 @@ static int flush_site(const char *site)
* Truncate the fast flush log.
*/
if (count > 0 && ftruncate(vstream_fileno(log), (off_t) 0) < 0)
msg_fatal("%s: truncate fast flush log for site %s: %m",
myname, site);
msg_fatal("%s: truncate fast flush log for site %s: %m", myname, site);
/*
* Request delivery and clean up.
@@ -267,34 +385,11 @@ static int flush_site(const char *site)
return (FLUSH_STAT_OK);
}
/* flush_enable - enable fast flush logging for site */
/* flush_purge_service - housekeeping */
static int flush_enable(const char *site)
static int flush_purge_service(void)
{
char *myname = "flush_enable";
VSTREAM *log;
if (msg_verbose)
msg_info("%s: site %s", myname, site);
/*
* Open or create the logfile. Multiple requests may arrive in parallel,
* so allow for the possibility that the file already exists.
*/
if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_CREAT | O_RDWR, 0600)) == 0)
msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
if (vstream_fclose(log) != 0)
msg_warn("write fast flush log for site %s: %m", site);
return (FLUSH_STAT_OK);
}
/* flush_purge - housekeeping */
static void flush_purge(void)
{
char *myname = "flush_purge";
char *myname = "flush_purge_service";
SCAN_DIR *scan;
char *site;
struct stat st;
@@ -302,13 +397,14 @@ static void flush_purge(void)
scan = scan_dir_open(MAIL_QUEUE_FLUSH);
while ((site = mail_scan_dir_next(scan)) != 0) {
mail_queue_path(path, MAIL_QUEUE_FLUSH, site);
if (valid_hostname(site) == 0) {
msg_warn("%s: bad fast flush logfile name: %s", myname, STR(path));
msg_warn("%s: bad fast flush logfile name: %s", myname, site);
if (unlink(STR(path)) < 0)
msg_warn("remove %s: %m", STR(path));
continue;
}
if (stat(mail_queue_path(path, MAIL_QUEUE_FLUSH, site), &st) < 0) {
if (stat(STR(path), &st) < 0) {
if (errno != ENOENT)
msg_warn("%s: stat %s: %m", myname, STR(path));
else if (msg_verbose)
@@ -316,22 +412,28 @@ static void flush_purge(void)
continue;
}
if (st.st_size == 0) {
if (st.st_mtime + FLUSH_MAX_UNUSED < event_time()) {
if (st.st_mtime + var_fflush_purge < event_time()) {
if (unlink(STR(path)) < 0)
msg_warn("remove %s: %m", STR(path));
else if (msg_verbose)
msg_info("%s: unlink %s, unused for %d days",
myname, STR(path), FLUSH_MAX_UNUSED / 84600);
msg_info("%s: unlink %s, empty and unchanged for %d days",
myname, STR(path), var_fflush_purge / 86400);
} else if (msg_verbose)
msg_info("%s: skip site %s - empty log", myname, site);
} else {
} else if (st.st_atime + var_fflush_refresh < event_time()) {
if (msg_verbose)
msg_info("%s: flush site %s", myname, site);
flush_site(site);
flush_send_service(site);
} else {
if (msg_verbose)
msg_info("%s: skip site %s, unread for <%d hours(s) ",
myname, site, var_fflush_refresh / 3600);
}
}
scan_dir_close(scan);
vstring_free(path);
return (FLUSH_STAT_OK);
}
/* flush_service - perform service for client */
@@ -340,13 +442,13 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
char **argv)
{
VSTRING *request = vstring_alloc(10);
VSTRING *site = vstring_alloc(10);
VSTRING *queue_id = vstring_alloc(10);
int status = FLUSH_STAT_BAD;
VSTRING *site = 0;
VSTRING *queue_id = 0;
static char wakeup[] = { /* master wakeup request */
TRIGGER_REQ_WAKEUP,
0,
};
int status = FLUSH_STAT_OK;
/*
* Sanity check. This service takes no command-line arguments.
@@ -364,44 +466,51 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
*
* All connection-management stuff is handled by the common code in
* single_server.c.
*
* Note that the purge operation only acknowledges receipt of the request
* and proceeds in the background. All other operations send their result
* status after the operation is completed.
*/
#define STREQ(x,y) (strcmp((x), (y)) == 0)
if (mail_scan(client_stream, "%s", request) == 1) {
if (STREQ(STR(request), FLUSH_REQ_APPEND)) {
if (STREQ(STR(request), FLUSH_REQ_ADD)) {
site = vstring_alloc(10);
queue_id = vstring_alloc(10);
if (mail_scan(client_stream, "%s %s", site, queue_id) == 2
&& valid_hostname(STR(site))
&& mail_queue_id_ok(STR(queue_id)))
status = flush_append(STR(site), STR(queue_id));
mail_print(client_stream, "%d", status);
&& mail_queue_id_ok(STR(queue_id))) {
status = flush_add_service(STR(site), STR(queue_id));
}
} else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
site = vstring_alloc(10);
if (mail_scan(client_stream, "%s", site) == 1
&& valid_hostname(STR(site)))
status = flush_site(STR(site));
mail_print(client_stream, "%d", status);
} else if (STREQ(STR(request), FLUSH_REQ_ENABLE)) {
if (mail_scan(client_stream, "%s", site) == 1
&& valid_hostname(STR(site)))
status = flush_enable(STR(site));
mail_print(client_stream, "%d", status);
&& valid_hostname(STR(site))) {
status = flush_send_service(STR(site));
}
} else if (STREQ(STR(request), FLUSH_REQ_PURGE)
|| STREQ(STR(request), wakeup)) {
mail_print(client_stream, "%d", FLUSH_STAT_OK);
flush_purge();
status = flush_purge_service();
}
}
mail_print(client_stream, "%d", status);
vstring_free(request);
vstring_free(site);
vstring_free(queue_id);
if (site)
vstring_free(site);
if (queue_id)
vstring_free(queue_id);
}
/* main - pass control to the single-threaded skeleton */
int main(int argc, char **argv)
{
single_server_main(argc, argv, flush_service, 0);
static CONFIG_TIME_TABLE time_table[] = {
VAR_FFLUSH_REFRESH, DEF_FFLUSH_REFRESH, &var_fflush_refresh, 1, 0,
VAR_FFLUSH_PURGE, DEF_FFLUSH_PURGE, &var_fflush_purge, 1, 0,
0,
};
static CONFIG_STR_TABLE str_table[] = {
VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
0,
};
single_server_main(argc, argv, flush_service,
MAIL_SERVER_TIME_TABLE, time_table,
MAIL_SERVER_STR_TABLE, str_table,
0);
}

View File

@@ -17,7 +17,8 @@ SRCS = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \
record.c remove.c resolve_clnt.c resolve_local.c rewrite_clnt.c \
sent.c smtp_stream.c split_addr.c string_list.c sys_exits.c \
timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c
tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
flush_clnt.c mail_conf_time.c
OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
debug_peer.o debug_process.o defer.o deliver_completed.o \
deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
@@ -36,7 +37,8 @@ OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
record.o remove.o resolve_clnt.o resolve_local.o rewrite_clnt.o \
sent.o smtp_stream.o split_addr.o string_list.o sys_exits.o \
timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o
tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
flush_clnt.o mail_conf_time.o
HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
@@ -51,7 +53,7 @@ HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
quote_821_local.h quote_822_local.h rec_streamlf.h rec_type.h \
recipient_list.h record.h resolve_clnt.h resolve_local.h \
rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h
sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@@ -64,7 +66,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
mail_addr_map mail_date maps mynetworks mypwd namadr_list \
off_cvt peer_name quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse \
quote_821_local
quote_821_local mail_conf_time
LIBS = ../../lib/libutil.a
LIB_DIR = ../../lib
@@ -202,6 +204,11 @@ peer_name: $(LIB)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
mail_conf_time: $(LIB) $(LIBS)
mv $@.o junk
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
tests: tok822_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
@@ -310,8 +317,7 @@ defer.o: mail_queue.h
defer.o: ../../include/vstream.h
defer.o: mail_proto.h
defer.o: ../../include/iostuff.h
defer.o: mail_params.h
defer.o: mail_flush.h
defer.o: flush_clnt.h
defer.o: bounce.h
defer.o: defer.h
deliver_completed.o: deliver_completed.c
@@ -386,6 +392,16 @@ file_id.o: ../../include/msg.h
file_id.o: ../../include/vstring.h
file_id.o: ../../include/vbuf.h
file_id.o: file_id.h
flush_clnt.o: flush_clnt.c
flush_clnt.o: ../../include/sys_defs.h
flush_clnt.o: ../../include/msg.h
flush_clnt.o: ../../include/vstream.h
flush_clnt.o: ../../include/vbuf.h
flush_clnt.o: mail_proto.h
flush_clnt.o: ../../include/iostuff.h
flush_clnt.o: mail_flush.h
flush_clnt.o: flush_clnt.h
flush_clnt.o: mail_params.h
header_opts.o: header_opts.c
header_opts.o: ../../include/sys_defs.h
header_opts.o: ../../include/msg.h
@@ -503,6 +519,17 @@ mail_conf_str.o: ../../include/sys_defs.h
mail_conf_str.o: ../../include/msg.h
mail_conf_str.o: ../../include/mymalloc.h
mail_conf_str.o: mail_conf.h
mail_conf_time.o: mail_conf_time.c
mail_conf_time.o: ../../include/sys_defs.h
mail_conf_time.o: ../../include/msg.h
mail_conf_time.o: ../../include/mymalloc.h
mail_conf_time.o: ../../include/dict.h
mail_conf_time.o: ../../include/vstream.h
mail_conf_time.o: ../../include/vbuf.h
mail_conf_time.o: ../../include/argv.h
mail_conf_time.o: ../../include/stringops.h
mail_conf_time.o: ../../include/vstring.h
mail_conf_time.o: mail_conf.h
mail_connect.o: mail_connect.c
mail_connect.o: ../../include/sys_defs.h
mail_connect.o: ../../include/msg.h
@@ -541,13 +568,11 @@ mail_error.o: mail_error.h
mail_error.o: ../../include/name_mask.h
mail_flush.o: mail_flush.c
mail_flush.o: ../../include/sys_defs.h
mail_flush.o: ../../include/msg.h
mail_flush.o: mail_proto.h
mail_flush.o: ../../include/vstream.h
mail_flush.o: ../../include/vbuf.h
mail_flush.o: mail_proto.h
mail_flush.o: ../../include/iostuff.h
mail_flush.o: mail_flush.h
mail_flush.o: mail_params.h
mail_open_ok.o: mail_open_ok.c
mail_open_ok.o: ../../include/sys_defs.h
mail_open_ok.o: ../../include/msg.h
@@ -620,7 +645,6 @@ mail_scan.o: ../../include/vstring_vstream.h
mail_scan.o: ../../include/mymalloc.h
mail_scan.o: mail_proto.h
mail_scan.o: ../../include/iostuff.h
mail_scan.o: mail_params.h
mail_scan_dir.o: mail_scan_dir.c
mail_scan_dir.o: ../../include/sys_defs.h
mail_scan_dir.o: ../../include/scan_dir.h

View File

@@ -115,8 +115,7 @@
#include "mail_queue.h"
#include "mail_proto.h"
#include "mail_params.h"
#include "mail_flush.h"
#include "flush_clnt.h"
#include "bounce.h"
#include "defer.h"
@@ -155,12 +154,11 @@ int vdefer_append(int flags, const char *id, const char *recipient,
vstring_free(why);
/*
* Notify the fast flush service.
* Notify the fast flush service. XXX Should not this belong in the
* bounce/defer daemon? Well, doing it here is more robust.
*/
if (*var_fast_flush_domains
&& (rcpt_domain = strrchr(recipient, '@')) != 0
&& *++rcpt_domain != 0)
mail_flush_append(rcpt_domain, id);
if ((rcpt_domain = strrchr(recipient, '@')) != 0 && *++rcpt_domain != 0)
flush_add(rcpt_domain, id);
return (-1);
}

View File

@@ -40,8 +40,6 @@
/* opens the queue file, and acquires a shared lock.
/* A null result means that the client sent bad information or that
/* it went away unexpectedly.
/* If the fast flush service is enabled, deliver_request_read()
/* initializes the client-side fast flush duplicate filter.
/*
/* The \fBflags\fR structure member is the bit-wise OR of zero or more
/* of the following:
@@ -101,8 +99,6 @@
#include "mail_queue.h"
#include "mail_proto.h"
#include "mail_params.h"
#include "mail_flush.h"
#include "mail_open_ok.h"
#include "recipient_list.h"
#include "deliver_request.h"
@@ -316,16 +312,8 @@ DELIVER_REQUEST *deliver_request_read(VSTREAM *stream)
request = deliver_request_alloc();
if (deliver_request_get(stream, request) < 0) {
deliver_request_free(request);
return (0);
request = 0;
}
/*
* Make sure the mail flush dupfilter sees no false positive if we're
* repeatedly delivering the same message.
*/
if (*var_fast_flush_domains)
mail_flush_append_init();
return (request);
}

View File

@@ -0,0 +1,188 @@
/*++
/* NAME
/* flush_clnt 3
/* SUMMARY
/* fast flush cache manager client interface
/* SYNOPSIS
/* #include <flush_clnt.h>
/*
/* int flush_add(site, queue_id)
/* const char *site;
/* const char *queue_id;
/*
/* int flush_send(site)
/* const char *site;
/*
/* int flush_purge()
/* DESCRIPTION
/* The following routines operate through the "fast flush" service.
/* This service maintains a cache of what mail is queued. The cache
/* is maintained for eligible destinations. A destination is the
/* right-hand side of a user@domain email address.
/*
/* flush_add() informs the "fast flush" cache manager that mail is
/* queued for the specified site with the specified queue ID.
/*
/* flush_send() requests delivery of all mail that is queued for
/* the specified destination.
/*
/* flush_purge() requests the "fast flush" cache manager to refresh
/* cached information that was not used or not updated for some
/* configurable amount of time.
/* DIAGNOSTICS
/* The result codes and their meanings are (see flush_clnt(5h)):
/* .IP MAIL_FLUSH_OK
/* The request completed successfully.
/* .IP MAIL_FLUSH_FAIL
/* The request failed (the request could not be sent to the server,
/* or the server reported failure).
/* .IP MAIL_FLUSH_BAD
/* The "fast flush" server rejected the request (invalid request
/* parameter).
/* SEE ALSO
/* flush(8) Postfix fast flush cache manager
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include "sys_defs.h"
#include <unistd.h>
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <vstream.h>
/* Global library. */
#include <mail_proto.h>
#include <mail_flush.h>
#include <flush_clnt.h>
#include <mail_params.h>
/* Application-specific. */
#define STR(x) vstring_str(x)
/* flush_clnt - generic fast flush service client */
static int flush_clnt(const char *format,...)
{
VSTREAM *flush;
int status;
va_list ap;
/*
* Connect to the fast flush service over local IPC.
*/
if ((flush = mail_connect(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
BLOCKING)) == 0)
return (FLUSH_STAT_FAIL);
/*
* Do not get stuck forever.
*/
vstream_control(flush,
VSTREAM_CTL_TIMEOUT, var_ipc_timeout,
VSTREAM_CTL_END);
/*
* Send a request with the site name, and receive the request acceptance
* status.
*/
va_start(ap, format);
mail_vprint(flush, format, ap);
va_end(ap);
if (mail_scan(flush, "%d", &status) != 1)
status = FLUSH_STAT_FAIL;
/*
* Clean up.
*/
vstream_fclose(flush);
return (status);
}
/* flush_purge - house keeping */
int flush_purge(void)
{
char *myname = "flush_purge";
int status;
if (msg_verbose)
msg_info("%s", myname);
/*
* Don't bother the server if the service is turned off.
*/
if (strcmp(var_fflush_policy, FFLUSH_POLICY_NONE) == 0)
status = FLUSH_STAT_OK;
else
status = flush_clnt("%s", FLUSH_REQ_PURGE);
if (msg_verbose)
msg_info("%s: status %d", myname, status);
return (status);
}
/* flush_send - deliver mail queued for site */
int flush_send(const char *site)
{
char *myname = "flush_send";
int status;
if (msg_verbose)
msg_info("%s: site %s", myname, site);
/*
* Don't bother the server if the service is turned off.
*/
if (strcmp(var_fflush_policy, FFLUSH_POLICY_NONE) == 0)
status = mail_flush_deferred();
else
status = flush_clnt("%s %s", FLUSH_REQ_SEND, site);
if (msg_verbose)
msg_info("%s: site %s status %d", myname, site, status);
return (status);
}
/* flush_add - inform "fast flush" cache manager */
int flush_add(const char *site, const char *queue_id)
{
char *myname = "flush_add";
int status;
if (msg_verbose)
msg_info("%s: site %s id %s", myname, site, queue_id);
/*
* Don't bother the server if the service is turned off.
*/
if (strcmp(var_fflush_policy, FFLUSH_POLICY_NONE) == 0)
status = FLUSH_STAT_OK;
else
status = flush_clnt("%s %s %s", FLUSH_REQ_ADD, site, queue_id);
if (msg_verbose)
msg_info("%s: site %s id %s status %d", myname, site, queue_id,
status);
return (status);
}

View File

@@ -0,0 +1,47 @@
#ifndef _FLUSH_CLNT_H_INCLUDED_
#define _FLUSH_CLNT_H_INCLUDED_
/*++
/* NAME
/* flush_clnt 3h
/* SUMMARY
/* flush backed up mail
/* SYNOPSIS
/* #include <flush_clnt.h>
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
extern int flush_add(const char *, const char *);
extern int flush_send(const char *);
extern int flush_purge(void);
/*
* Mail flush server requests.
*/
#define FLUSH_REQ_ADD "add" /* append queue ID to site log */
#define FLUSH_REQ_SEND "send" /* flush mail queued for site */
#define FLUSH_REQ_PURGE "purge" /* refresh or delete old info */
/*
* Mail flush server status codes.
*/
#define FLUSH_STAT_FAIL -1 /* request failed */
#define FLUSH_STAT_OK 0 /* request executed */
#define FLUSH_STAT_BAD 3 /* invalid parameter */
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
#endif

View File

@@ -46,9 +46,11 @@ extern const char *mail_conf_lookup_eval(const char *);
extern char *get_mail_conf_str(const char *, const char *, int, int);
extern int get_mail_conf_int(const char *, int, int, int);
extern int get_mail_conf_bool(const char *, int);
extern int get_mail_conf_time(const char *, const char *, int, int);
extern char *get_mail_conf_raw(const char *, const char *, int, int);
extern int get_mail_conf_int2(const char *, const char *, int, int, int);
extern int get_mail_conf_time2(const char *, const char *, const char *, int, int);
/*
* Lookup with function-call defaults.
@@ -56,6 +58,7 @@ extern int get_mail_conf_int2(const char *, const char *, int, int, int);
extern char *get_mail_conf_str_fn(const char *, const char *(*) (void), int, int);
extern int get_mail_conf_int_fn(const char *, int (*) (void), int, int);
extern int get_mail_conf_bool_fn(const char *, int (*) (void));
extern int get_mail_conf_time_fn(const char *, const char *(*) (void), int, int);
extern char *get_mail_conf_raw_fn(const char *, const char *(*) (void), int, int);
/*
@@ -64,6 +67,7 @@ extern char *get_mail_conf_raw_fn(const char *, const char *(*) (void), int, int
extern void set_mail_conf_str(const char *, const char *);
extern void set_mail_conf_int(const char *, int);
extern void set_mail_conf_bool(const char *, int);
extern void set_mail_conf_time(const char *, const char *);
/*
* Tables that allow us to selectively copy values from the global
@@ -91,9 +95,18 @@ typedef struct {
int *target; /* pointer to global variable */
} CONFIG_BOOL_TABLE;
typedef struct {
const char *name; /* config variable name */
const char *defval; /* default value */
int *target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
} CONFIG_TIME_TABLE;
extern void get_mail_conf_str_table(CONFIG_STR_TABLE *);
extern void get_mail_conf_int_table(CONFIG_INT_TABLE *);
extern void get_mail_conf_bool_table(CONFIG_BOOL_TABLE *);
extern void get_mail_conf_time_table(CONFIG_TIME_TABLE *);
extern void get_mail_conf_raw_table(CONFIG_STR_TABLE *);
/*
@@ -122,9 +135,18 @@ typedef struct {
int *target; /* pointer to global variable */
} CONFIG_BOOL_FN_TABLE;
typedef struct {
const char *name; /* config variable name */
const char *(*defval) (void); /* default value provider */
int *target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
} CONFIG_TIME_FN_TABLE;
extern void get_mail_conf_str_fn_table(CONFIG_STR_FN_TABLE *);
extern void get_mail_conf_int_fn_table(CONFIG_INT_FN_TABLE *);
extern void get_mail_conf_bool_fn_table(CONFIG_BOOL_FN_TABLE *);
extern void get_mail_conf_time_fn_table(CONFIG_TIME_FN_TABLE *);
extern void get_mail_conf_raw_fn_table(CONFIG_STR_FN_TABLE *);
/* LICENSE

View File

@@ -0,0 +1,260 @@
/*++
/* NAME
/* mail_conf_time 3
/* SUMMARY
/* time interval configuration parameter support
/* SYNOPSIS
/* #include <mail_conf.h>
/*
/* int get_mail_conf_time(name, defval, min, max);
/* const char *name;
/* const char *defval;
/* int min;
/* int max;
/*
/* int get_mail_conf_time_fn(name, defval, min, max);
/* const char *name;
/* const char *(*defval)();
/* int min;
/* int max;
/*
/* void set_mail_conf_time(name, value)
/* const char *name;
/* const char *value;
/*
/* void get_mail_conf_time_table(table)
/* CONFIG_INT_TABLE *table;
/*
/* void get_mail_conf_time_fn_table(table)
/* CONFIG_INT_TABLE *table;
/* AUXILIARY FUNCTIONS
/* int get_mail_conf_time2(name1, name2, defval, min, max);
/* const char *name1;
/* const char *name2;
/* const char *defval;
/* int min;
/* int max;
/* DESCRIPTION
/* This module implements configuration parameter support
/* for time interval values. By default, times are specified
/* in units of seconds, but the conversion routines understand
/* one-letter suffixes to specify an explicit time unit: s
/* (seconds), m (minutes), h (hours), d (days) or w (weeks).
/*
/* get_mail_conf_time() looks up the named entry in the global
/* configuration dictionary. The default value is returned
/* when no value was found.
/* \fImin\fR is zero or specifies a lower limit on the integer
/* value or string length; \fImax\fR is zero or specifies an
/* upper limit on the integer value or string length.
/*
/* get_mail_conf_time_fn() is similar but specifies a function that
/* provides the default value. The function is called only
/* when the default value is needed.
/*
/* set_mail_conf_time() updates the named entry in the global
/* configuration dictionary. This has no effect on values that
/* have been looked up earlier via the get_mail_conf_XXX() routines.
/*
/* get_mail_conf_time_table() and get_mail_conf_time_fn_table() initialize
/* lists of variables, as directed by their table arguments. A table
/* must be terminated by a null entry.
/*
/* get_mail_conf_time2() concatenates the two names and is otherwise
/* identical to get_mail_conf_time().
/* DIAGNOSTICS
/* Fatal errors: malformed numerical value, unknown time unit.
/* SEE ALSO
/* config(3) general configuration
/* mail_conf_str(3) string-valued configuration parameters
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdlib.h>
#include <stdio.h> /* sscanf() */
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <dict.h>
#include <stringops.h>
/* Global library. */
#include "mail_conf.h"
#define MINUTE (60)
#define HOUR (60 * MINUTE)
#define DAY (24 * HOUR)
#define WEEK (7 * DAY)
/* convert_mail_conf_time - look up and convert integer parameter value */
static int convert_mail_conf_time(const char *name, int *intval)
{
const char *strval;
char unit;
char junk;
if ((strval = mail_conf_lookup_eval(name)) != 0) {
if (sscanf(strval, "%d%c%c", intval, &unit, &junk) == 2) {
switch (unit) {
case 'w':
*intval *= WEEK;
return (1);
case 'd':
*intval *= DAY;
return (1);
case 'h':
*intval *= HOUR;
return (1);
case 'm':
*intval *= MINUTE;
return (1);
case 's':
return (1);
break;
default:
msg_fatal("bad time unit: %s", strval);
}
}
if (sscanf(strval, "%d%c", intval, &junk) != 1)
msg_fatal("bad numerical configuration: %s = %s", name, strval);
return (1);
}
return (0);
}
/* check_mail_conf_time - validate integer value */
static void check_mail_conf_time(const char *name, int intval, int min, int max)
{
if (min && intval < min)
msg_fatal("invalid %s: %d (min %d)", name, intval, min);
if (max && intval > max)
msg_fatal("invalid %s: %d (max %d)", name, intval, max);
}
/* get_mail_conf_time - evaluate integer-valued configuration variable */
int get_mail_conf_time(const char *name, const char *defval, int min, int max)
{
int intval;
if (convert_mail_conf_time(name, &intval) == 0)
set_mail_conf_time(name, defval);
if (convert_mail_conf_time(name, &intval) == 0)
msg_panic("get_mail_conf_time: parameter not found: %s", name);
check_mail_conf_time(name, intval, min, max);
return (intval);
}
/* get_mail_conf_time2 - evaluate integer-valued configuration variable */
int get_mail_conf_time2(const char *name1, const char *name2,
const char *defval, int min, int max)
{
int intval;
char *name;
name = concatenate(name1, name2, (char *) 0);
if (convert_mail_conf_time(name, &intval) == 0)
set_mail_conf_time(name, defval);
if (convert_mail_conf_time(name, &intval) == 0)
msg_panic("get_mail_conf_time2: parameter not found: %s", name);
check_mail_conf_time(name, intval, min, max);
myfree(name);
return (intval);
}
/* get_mail_conf_time_fn - evaluate integer-valued configuration variable */
typedef const char *(*stupid_indent_time) (void);
int get_mail_conf_time_fn(const char *name, stupid_indent_time defval,
int min, int max)
{
int intval;
if (convert_mail_conf_time(name, &intval) == 0)
set_mail_conf_time(name, defval());
if (convert_mail_conf_time(name, &intval) == 0)
msg_panic("get_mail_conf_time_fn: parameter not found: %s", name);
check_mail_conf_time(name, intval, min, max);
return (intval);
}
/* set_mail_conf_time - update integer-valued configuration dictionary entry */
void set_mail_conf_time(const char *name, const char *value)
{
mail_conf_update(name, value);
}
/* get_mail_conf_time_table - look up table of integers */
void get_mail_conf_time_table(CONFIG_TIME_TABLE *table)
{
while (table->name) {
table->target[0] = get_mail_conf_time(table->name, table->defval,
table->min, table->max);
table++;
}
}
/* get_mail_conf_time_fn_table - look up integers, defaults are functions */
void get_mail_conf_time_fn_table(CONFIG_TIME_FN_TABLE *table)
{
while (table->name) {
table->target[0] = get_mail_conf_time_fn(table->name, table->defval,
table->min, table->max);
table++;
}
}
#ifdef TEST
/*
* Stand-alone driver program for regression testing.
*/
#include <vstream.h>
int main(int unused_argc, char **unused_argv)
{
static int seconds;
static int minutes;
static int hours;
static int days;
static int weeks;
static CONFIG_TIME_TABLE time_table[] = {
"seconds", "10s", &seconds, 0, 0,
"minutes", "10m", &minutes, 0, 0,
"hours", "10h", &hours, 0, 0,
"days", "10d", &days, 0, 0,
"weeks", "10w", &weeks, 0, 0,
0,
};
get_mail_conf_time_table(time_table);
vstream_printf("seconds = %d\n", seconds);
vstream_printf("minutes = %d\n", minutes);
vstream_printf("hours = %d\n", hours);
vstream_printf("days = %d\n", days);
vstream_printf("weeks = %d\n", weeks);
vstream_fflush(VSTREAM_OUT);
}
#endif

View File

@@ -2,70 +2,18 @@
/* NAME
/* mail_flush 3
/* SUMMARY
/* mail flush service client interface
/* flush backed up mail
/* SYNOPSIS
/* #include <mail_flush.h>
/*
/* int mail_flush_deferred()
/*
/* int mail_flush_purge()
/*
/* int mail_flush_enable(site)
/* const char *site;
/*
/* int mail_flush_site(site)
/* const char *site;
/*
/* int mail_flush_append(site, queue_id)
/* const char *site;
/* const char *queue_id;
/*
/* void mail_flush_append_init()
/* DESCRIPTION
/* This module deals with delivery of delayed mail.
/* This module triggers delivery of backed up mail.
/*
/* mail_flush_deferred() triggers delivery of all deferred
/* or incoming mail.
/*
/* The following services are available only for sites that have a
/* "fast flush" logfile. These files list all mail that is queued
/* for a given site, and are created on demand when, for example,
/* an eligible SMTP client issues the ETRN command.
/*
/* mail_flush_enable() enables the "fast flush" service for
/* the named site.
/*
/* mail_flush_site() uses the "fast flush" service to trigger
/* delivery of messages queued for the specified site.
/*
/* mail_flush_append() appends a record to the "fast flush"
/* logfile for the specified site, with the queue ID of mail
/* that still should be delivered. This routine uses a little
/* duplicate filter to avoid appending multiple identical
/* records when one has to defer multi-recipient mail.
/*
/* mail_flush_append_init() initializes a duplicate filter that is used
/* by mail_flush_append(). mail_flush_append_init() must be called once
/* before calling mail_flush_append() and must be called whenever
/* the application opens a new queue file, to prevent false
/* positives with the duplicate filter when repeated attempts
/* are made to deliver the same message.
/*
/* mail_flush_purge() requests the "fast flush" service to
/* flush all its "fast flush" logfiles. This is necessary
/* once a day or so, in order to prevent accumulation of
/* too much outdated information.
/* DIAGNOSTICS
/* The result codes and their meaning are (see mail_flush(5h)):
/* .IP MAIL_FLUSH_OK
/* The request completed normally.
/* .IP MAIL_FLUSH_FAIL
/* The request failed.
/* .IP MAIL_FLUSH_UNKNOWN
/* The specified site has no "fast flush" logfile.
/* .IP MAIL_FLUSH_BAD
/* The "fast flush" server rejected the request (invalid request
/* parameter).
/* The result is 0 in case of success, -1 in case of failure.
/* LICENSE
/* .ad
/* .fi
@@ -80,28 +28,13 @@
/* System library. */
#include "sys_defs.h"
#include <unistd.h>
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <vstream.h>
#include <vstring.h>
/* Global library. */
#include <mail_proto.h>
#include <mail_flush.h>
#include <mail_params.h>
/* Application-specific. */
#define STR(x) vstring_str(x)
static VSTRING *mail_flush_saved_site;
static VSTRING *mail_flush_saved_id;
static int mail_flush_saved_status;
/* mail_flush_deferred - flush deferred queue */
@@ -120,135 +53,3 @@ int mail_flush_deferred(void)
return (mail_trigger(MAIL_CLASS_PUBLIC, MAIL_SERVICE_QUEUE,
qmgr_trigger, sizeof(qmgr_trigger)));
}
/* mail_flush_append_init - initialize repeat filter */
void mail_flush_append_init(void)
{
if (mail_flush_saved_site == 0) {
mail_flush_saved_site = vstring_alloc(10);
mail_flush_saved_id = vstring_alloc(10);
}
vstring_strcpy(mail_flush_saved_site, "");
vstring_strcpy(mail_flush_saved_id, "");
}
/* mail_flush_cached - see if request repeats */
static int mail_flush_cached(const char *site, const char *queue_id)
{
if (strcmp(STR(mail_flush_saved_site), site) == 0
&& strcmp(STR(mail_flush_saved_id), queue_id) == 0) {
return (1);
} else {
vstring_strcpy(mail_flush_saved_site, site);
vstring_strcpy(mail_flush_saved_id, queue_id);
return (0);
}
}
/* mail_flush_clnt - generic fast flush service client */
static int mail_flush_clnt(const char *format,...)
{
VSTREAM *flush;
int status;
va_list ap;
/*
* Connect to the fast flush service over local IPC.
*/
if ((flush = mail_connect(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
BLOCKING)) == 0)
return (FLUSH_STAT_FAIL);
/*
* Do not get stuck forever.
*/
vstream_control(flush,
VSTREAM_CTL_TIMEOUT, var_ipc_timeout,
VSTREAM_CTL_END);
/*
* Send a request with the site name, and receive the request completion
* status.
*/
va_start(ap, format);
mail_vprint(flush, format, ap);
va_end(ap);
if (mail_scan(flush, "%d", &status) != 1)
status = FLUSH_STAT_FAIL;
/*
* Clean up.
*/
vstream_fclose(flush);
return (status);
}
/* mail_flush_enable - enable fast flush logging for site */
int mail_flush_enable(const char *site)
{
char *myname = "mail_flush_enable";
int status;
if (msg_verbose)
msg_info("%s: site %s", myname, site);
status = mail_flush_clnt("%s %s", FLUSH_REQ_ENABLE, site);
if (msg_verbose)
msg_info("%s: site %s status %d", myname, site, status);
return (status);
}
/* mail_flush_purge - house keeping */
int mail_flush_purge(void)
{
char *myname = "mail_flush_purge";
int status;
if (msg_verbose)
msg_info("%s", myname);
status = mail_flush_clnt("%s", FLUSH_REQ_SEND);
if (msg_verbose)
msg_info("%s: status %d", myname, status);
return (status);
}
/* mail_flush_site - flush deferred mail for site */
int mail_flush_site(const char *site)
{
char *myname = "mail_flush_site";
int status;
if (msg_verbose)
msg_info("%s: site %s", myname, site);
status = mail_flush_clnt("%s %s", FLUSH_REQ_SEND, site);
if (msg_verbose)
msg_info("%s: site %s status %d", myname, site, status);
return (status);
}
/* mail_flush_append - append record to fast flush log */
int mail_flush_append(const char *site, const char *queue_id)
{
char *myname = "mail_flush_append";
if (msg_verbose)
msg_info("%s: site %s id %s", myname, site, queue_id);
if (mail_flush_cached(site, queue_id) == 0)
mail_flush_saved_status =
mail_flush_clnt("%s %s %s", FLUSH_REQ_APPEND, site, queue_id);
if (msg_verbose)
msg_info("%s: site %s id %s status %d", myname, site, queue_id,
mail_flush_saved_status);
return (mail_flush_saved_status);
}

View File

@@ -11,32 +11,9 @@
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
/* External interface. */
extern int mail_flush_deferred(void);
extern int mail_flush_purge(void);
extern int mail_flush_enable(const char *);
extern int mail_flush_site(const char *);
extern int mail_flush_append(const char *, const char *);
extern void mail_flush_append_init(void);
/*
* Mail flush server requests.
*/
#define FLUSH_REQ_APPEND "append"/* append queue ID to site log */
#define FLUSH_REQ_SEND "send" /* flush mail queued for site */
#define FLUSH_REQ_ENABLE "enable"/* flush mail queued for site */
#define FLUSH_REQ_PURGE "purge" /* flush mail queued for site */
/*
* Mail flush server status codes.
*/
#define FLUSH_STAT_FAIL -1 /* everyone */
#define FLUSH_STAT_OK 0 /* everyone */
#define FLUSH_STAT_UNKNOWN 2 /* mail_flush_site() only */
#define FLUSH_STAT_BAD 3 /* mail_flush_site() only */
/* LICENSE
/* .ad

View File

@@ -58,7 +58,7 @@
/* int var_ownreq_special;
/* int var_daemon_timeout;
/* char *var_syslog_facility;
/* char *var_fast_flush_domains;
/* char *var_fflush_policy;
/*
/* void mail_params_init()
/* DESCRIPTION
@@ -165,8 +165,7 @@ time_t var_starttime;
int var_ownreq_special;
int var_daemon_timeout;
char *var_syslog_facility;
char *var_relay_domains;
char *var_fast_flush_domains;
char *var_fflush_policy;
/* check_myhostname - lookup hostname and validate */
@@ -277,8 +276,7 @@ void mail_params_init()
VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 1,
VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fast_flush_domains, 0, 0,
VAR_FFLUSH_POLICY, DEF_FFLUSH_POLICY, &var_fflush_policy, 1, 0,
0,
};
static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {

View File

@@ -490,7 +490,7 @@ extern int var_min_delivery_slots;
extern int var_qmgr_fudge;
#define VAR_QMGR_HOG "qmgr_site_hog_factor"
#define DEF_QMGR_HOG 90
#define DEF_QMGR_HOG 100
extern int var_qmgr_hog;
/*
@@ -1067,9 +1067,21 @@ extern char *var_filter_xport;
/*
* Fast flush service support.
*/
#define VAR_FFLUSH_DOMAINS "fast_flush_domains"
#define DEF_FFLUSH_DOMAINS "$relay_domains"
extern char *var_fast_flush_domains;
#define VAR_FFLUSH_POLICY "fast_flush_policy"
#define DEF_FFLUSH_POLICY FFLUSH_POLICY_RELAY
extern char *var_fflush_policy;
#define FFLUSH_POLICY_ALL "all"
#define FFLUSH_POLICY_RELAY "relay"
#define FFLUSH_POLICY_NONE "none"
#define VAR_FFLUSH_PURGE "fast_flush_purge_delay"
#define DEF_FFLUSH_PURGE "7d"
extern int var_fflush_purge;
#define VAR_FFLUSH_REFRESH "fast_flush_refresh_delay"
#define DEF_FFLUSH_REFRESH "12h"
extern int var_fflush_refresh;
/* LICENSE
/* .ad

View File

@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-20001001"
#define DEF_MAIL_VERSION "Snapshot-20001003"
extern char *var_mail_version;
/* LICENSE

View File

@@ -19,7 +19,8 @@
#define MAIL_SERVER_INT_TABLE 1
#define MAIL_SERVER_STR_TABLE 2
#define MAIL_SERVER_BOOL_TABLE 3
#define MAIL_SERVER_RAW_TABLE 4
#define MAIL_SERVER_TIME_TABLE 4
#define MAIL_SERVER_RAW_TABLE 5
#define MAIL_SERVER_PRE_INIT 10
#define MAIL_SERVER_POST_INIT 11

View File

@@ -56,6 +56,11 @@
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_TIME_TABLE (CONFIG_TIME_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
@@ -469,6 +474,9 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
case MAIL_SERVER_BOOL_TABLE:
get_mail_conf_bool_table(va_arg(ap, CONFIG_BOOL_TABLE *));
break;
case MAIL_SERVER_TIME_TABLE:
get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
break;
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
break;

View File

@@ -51,6 +51,11 @@
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_TIME_TABLE (CONFIG_TIME_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
@@ -441,6 +446,9 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
case MAIL_SERVER_BOOL_TABLE:
get_mail_conf_bool_table(va_arg(ap, CONFIG_BOOL_TABLE *));
break;
case MAIL_SERVER_TIME_TABLE:
get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
break;
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
break;

View File

@@ -58,6 +58,11 @@
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_TIME_TABLE (CONFIG_TIME_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
/* order as specified, and multiple instances of the same type
/* are allowed.
/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
/* A table with configurable parameters, to be loaded from the
/* global Postfix configuration file. Tables are loaded in the
@@ -441,6 +446,9 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
case MAIL_SERVER_BOOL_TABLE:
get_mail_conf_bool_table(va_arg(ap, CONFIG_BOOL_TABLE *));
break;
case MAIL_SERVER_TIME_TABLE:
get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
break;
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
break;

View File

@@ -95,7 +95,6 @@ qmgr_active.o: ../../include/recipient_list.h
qmgr_active.o: ../../include/bounce.h
qmgr_active.o: ../../include/defer.h
qmgr_active.o: ../../include/rec_type.h
qmgr_active.o: ../../include/mail_flush.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
qmgr_active.o: ../../include/maps.h
@@ -264,6 +263,7 @@ qmgr_scan.o: ../../include/msg.h
qmgr_scan.o: ../../include/mymalloc.h
qmgr_scan.o: ../../include/scan_dir.h
qmgr_scan.o: ../../include/mail_scan_dir.h
qmgr_scan.o: ../../include/flush_clnt.h
qmgr_scan.o: qmgr.h
qmgr_scan.o: ../../include/vstream.h
qmgr_scan.o: ../../include/vbuf.h

View File

@@ -103,7 +103,6 @@
#include <bounce.h>
#include <defer.h>
#include <rec_type.h>
#include <mail_flush.h>
/* Application-specific. */
@@ -227,13 +226,6 @@ void qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id)
*/
if (message->refcount == 0)
qmgr_active_done(message);
/*
* Make sure the mail flush dupfilter sees no false positive if we're
* repeatedly trying to deliver the same message.
*/
else if (*var_fast_flush_domains)
mail_flush_append_init();
}
}

View File

@@ -697,7 +697,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
* Optionally defer deliveries over specific transports, unless the
* restriction is lifted temporarily.
*/
if (*var_defer_xports && (message->qflags & QMGR_SCAN_ALL) == 0) {
if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DEAD) == 0) {
if (defer_xport_argv == 0)
defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,");
for (cpp = defer_xport_argv->argv; *cpp; cpp++)

View File

@@ -67,6 +67,7 @@
/* Global library. */
#include <mail_scan_dir.h>
#include <flush_clnt.h>
/* Application-specific. */
@@ -100,6 +101,14 @@ static void qmgr_scan_start(QMGR_SCAN *scan_info)
if (scan_info->nflags & QMGR_FLUSH_DEAD)
qmgr_enable_all();
/*
* Optionally inform the fast flush cache manager that we're attempting
* to deliver all queued mail.
*/
if ((scan_info->nflags & QMGR_FLUSH_DEAD)
&& (scan_info->nflags & QMGR_SCAN_ALL))
flush_purge();
/*
* Start or restart the scan.
*/

View File

@@ -10,7 +10,7 @@ DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
str_vars.h
str_vars.h time_table.h time_vars.h
PROG = postconf
SAMPLES = ../../conf/main.cf.default
INC_DIR = ../../include
@@ -88,11 +88,13 @@ postconf.o: ../../include/iostuff.h
postconf.o: ../../include/mail_version.h
postconf.o: ../../include/mail_params.h
postconf.o: ../../include/mail_addr.h
postconf.o: time_vars.h
postconf.o: bool_vars.h
postconf.o: int_vars.h
postconf.o: str_vars.h
postconf.o: local_vars.h
postconf.o: smtp_vars.h
postconf.o: time_table.h
postconf.o: bool_table.h
postconf.o: int_table.h
postconf.o: str_table.h

View File

@@ -18,6 +18,12 @@
print | "sed 's/[ ][ ]*/ /g' | sort -u >bool_table.h"
}
}
/^(static| )*CONFIG_TIME_TABLE .*\{/,/\};/ {
if ($1 ~ /VAR/) {
print "int " substr($3,2,length($3)-2) ";" > "time_vars.h"
print | "sed 's/[ ][ ]*/ /g' | sort -u >time_table.h"
}
}
# Workaround for broken gawk versions.

View File

@@ -116,6 +116,7 @@ DICT *text_table;
/*
* Declarations generated by scanning actual C source files.
*/
#include "time_vars.h"
#include "bool_vars.h"
#include "int_vars.h"
#include "str_vars.h"
@@ -129,6 +130,11 @@ DICT *text_table;
/*
* Lookup tables generated by scanning actual C source files.
*/
static CONFIG_TIME_TABLE time_table[] = {
#include "time_table.h"
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
#include "bool_table.h"
0,
@@ -394,6 +400,7 @@ static void read_parameters(void)
static void hash_parameters(void)
{
CONFIG_TIME_TABLE *ctt;
CONFIG_BOOL_TABLE *cbt;
CONFIG_INT_TABLE *cit;
CONFIG_STR_TABLE *cst;
@@ -401,6 +408,8 @@ static void hash_parameters(void)
param_table = htable_create(100);
for (ctt = time_table; ctt->name; ctt++)
htable_enter(param_table, ctt->name, (char *) ctt);
for (cbt = bool_table; cbt->name; cbt++)
htable_enter(param_table, cbt->name, (char *) cbt);
for (cit = int_table; cit->name; cit++)
@@ -458,6 +467,29 @@ static void print_bool(int mode, CONFIG_BOOL_TABLE *cbt)
}
}
/* print_time - print relative time parameter */
static void print_time(int mode, CONFIG_TIME_TABLE * ctt)
{
const char *value;
if (mode & SHOW_DEFS) {
show_strval(mode, ctt->name, ctt->defval);
} else {
value = dict_lookup(CONFIG_DICT, ctt->name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
show_strval(mode, ctt->name, ctt->defval);
} else {
show_strval(mode, ctt->name, value);
}
} else {
if (value != 0)
show_strval(mode, ctt->name, value);
}
}
}
/* print_int - print integer parameter */
static void print_int(int mode, CONFIG_INT_TABLE *cit)
@@ -560,6 +592,8 @@ static void print_parameter(int mode, char *ptr)
/*
* This is gross, but the best we can do on short notice.
*/
if (INSIDE(ptr, time_table))
print_time(mode, (CONFIG_TIME_TABLE *) ptr);
if (INSIDE(ptr, bool_table))
print_bool(mode, (CONFIG_BOOL_TABLE *) ptr);
if (INSIDE(ptr, int_table))

View File

@@ -93,7 +93,6 @@ qmgr_active.o: ../../include/recipient_list.h
qmgr_active.o: ../../include/bounce.h
qmgr_active.o: ../../include/defer.h
qmgr_active.o: ../../include/rec_type.h
qmgr_active.o: ../../include/mail_flush.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
qmgr_active.o: ../../include/maps.h
@@ -236,6 +235,7 @@ qmgr_scan.o: ../../include/msg.h
qmgr_scan.o: ../../include/mymalloc.h
qmgr_scan.o: ../../include/scan_dir.h
qmgr_scan.o: ../../include/mail_scan_dir.h
qmgr_scan.o: ../../include/flush_clnt.h
qmgr_scan.o: qmgr.h
qmgr_scan.o: ../../include/vstream.h
qmgr_scan.o: ../../include/vbuf.h

View File

@@ -103,7 +103,6 @@
#include <bounce.h>
#include <defer.h>
#include <rec_type.h>
#include <mail_flush.h>
/* Application-specific. */
@@ -227,13 +226,6 @@ void qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id)
*/
if (message->refcount == 0)
qmgr_active_done(message);
/*
* Make sure the mail flush dupfilter sees no false positive if we're
* repeatedly trying to deliver the same message.
*/
else if (*var_fast_flush_domains)
mail_flush_append_init();
}
}

View File

@@ -580,7 +580,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
* Optionally defer deliveries over specific transports, unless the
* restriction is lifted temporarily.
*/
if (*var_defer_xports && (message->qflags & QMGR_SCAN_ALL) == 0) {
if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DEAD) == 0) {
if (defer_xport_argv == 0)
defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,");
for (cpp = defer_xport_argv->argv; *cpp; cpp++)

View File

@@ -67,6 +67,7 @@
/* Global library. */
#include <mail_scan_dir.h>
#include <flush_clnt.h>
/* Application-specific. */
@@ -100,6 +101,14 @@ static void qmgr_scan_start(QMGR_SCAN *scan_info)
if (scan_info->nflags & QMGR_FLUSH_DEAD)
qmgr_enable_all();
/*
* Optionally inform the fast flush cache manager that we're attempting
* to deliver all queued mail.
*/
if ((scan_info->nflags & QMGR_FLUSH_DEAD)
&& (scan_info->nflags & QMGR_SCAN_ALL))
flush_purge();
/*
* Start or restart the scan.
*/

View File

@@ -59,10 +59,10 @@ sendmail.o: ../../include/msg.h
sendmail.o: ../../include/mymalloc.h
sendmail.o: ../../include/vstream.h
sendmail.o: ../../include/vbuf.h
sendmail.o: ../../include/vstring.h
sendmail.o: ../../include/msg_vstream.h
sendmail.o: ../../include/msg_syslog.h
sendmail.o: ../../include/vstring_vstream.h
sendmail.o: ../../include/vstring.h
sendmail.o: ../../include/username.h
sendmail.o: ../../include/fullname.h
sendmail.o: ../../include/argv.h
@@ -70,6 +70,7 @@ sendmail.o: ../../include/safe.h
sendmail.o: ../../include/iostuff.h
sendmail.o: ../../include/stringops.h
sendmail.o: ../../include/set_ugid.h
sendmail.o: ../../include/connect.h
sendmail.o: ../../include/mail_queue.h
sendmail.o: ../../include/mail_proto.h
sendmail.o: ../../include/mail_params.h
@@ -85,3 +86,4 @@ sendmail.o: ../../include/tok822.h
sendmail.o: ../../include/resolve_clnt.h
sendmail.o: ../../include/mail_flush.h
sendmail.o: ../../include/mail_stream.h
sendmail.o: ../../include/smtp_stream.h

View File

@@ -120,7 +120,7 @@ smtpd.o: ../../include/off_cvt.h
smtpd.o: ../../include/debug_peer.h
smtpd.o: ../../include/mail_error.h
smtpd.o: ../../include/name_mask.h
smtpd.o: ../../include/mail_flush.h
smtpd.o: ../../include/flush_clnt.h
smtpd.o: ../../include/mail_stream.h
smtpd.o: ../../include/mail_queue.h
smtpd.o: ../../include/tok822.h

View File

@@ -151,18 +151,6 @@
/* Limit the number of times a client can issue a junk command
/* such as NOOP, VRFY, ETRN or RSET in one SMTP session before
/* it is penalized with tarpit delays.
/* .SH "ETRN controls"
/* .ad
/* .fi
/* .IP \fBsmtpd_etrn_restrictions\fR
/* Restrict what domain names can be used in \fBETRN\fR commands,
/* and what clients may issue \fBETRN\fR commands.
/* .IP \fBfast_flush_domains\fR
/* The destinations that this system is willing to provide "fast ETRN"
/* service for. By default, "fast ETRN" service is available only
/* for destinations that the local system is willing to relay mail to.
/* For other destinations, Postfix simply attempts to deliver all mail
/* in the queue.
/* .SH "UCE control restrictions"
/* .ad
/* .fi
@@ -178,6 +166,9 @@
/* Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands.
/* .IP \fBsmtpd_recipient_restrictions\fR
/* Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands.
/* .IP \fBsmtpd_etrn_restrictions\fR
/* Restrict what domain names can be used in \fBETRN\fR commands,
/* and what clients may issue \fBETRN\fR commands.
/* .IP \fBallow_untrusted_routing\fR
/* Allow untrusted clients to specify addresses with sender-specified
/* routing. Enabling this opens up nasty relay loopholes involving
@@ -279,7 +270,7 @@
#include <off_cvt.h>
#include <debug_peer.h>
#include <mail_error.h>
#include <mail_flush.h>
#include <flush_clnt.h>
#include <mail_stream.h>
#include <mail_queue.h>
#include <tok822.h>
@@ -307,6 +298,7 @@
*/
int var_smtpd_rcpt_limit;
int var_smtpd_tmout;
char *var_relay_domains;
int var_smtpd_soft_erlim;
int var_smtpd_hard_erlim;
int var_queue_minfree; /* XXX use off_t */
@@ -349,7 +341,6 @@ bool var_smtpd_sasl_enable;
char *var_smtpd_sasl_opts;
char *var_smtpd_sasl_realm;
char *var_filter_xport;
char *var_fast_flush_domains;
/*
* Global state, for stand-alone mode queue file cleanup. When this is
@@ -1083,10 +1074,6 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "501 Error: invalid parameter syntax");
return (-1);
}
if (SMTPD_STAND_ALONE(state)) {
smtpd_chat_reply(state, "458 Unable to queue messages");
return (-1);
}
/*
* XXX The implementation borrows heavily from the code that implements
@@ -1094,43 +1081,22 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
* rejected. RFC 1985 requires that 459 be sent when the server refuses
* to perform the request.
*/
if (SMTPD_STAND_ALONE(state)) {
smtpd_chat_reply(state, "458 Unable to queue messages");
return (-1);
}
if ((err = smtpd_check_etrn(state, argv[1].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
}
if (!*var_fast_flush_domains) {
mail_flush_deferred();
smtpd_chat_reply(state, "250 Queuing started");
return (0);
}
/*
* Create a fast ETRN cache file on the fly for an eligible site.
*/
switch (mail_flush_site(argv[1].strval)) {
case FLUSH_STAT_UNKNOWN:
if (smtpd_check_etrn_cache_policy_ok(state, argv[1].strval)) {
if (mail_flush_enable(argv[1].strval) != FLUSH_STAT_OK) {
msg_warn("can't create fast ETRN cache for %s", argv[1].strval);
} else {
msg_info("created fast ETRN cache for %s (client=%s)",
argv[1].strval, state->namaddr);
}
} else {
msg_info("using slow ETRN service for %s (client=%s)",
argv[1].strval, state->namaddr);
}
/* Fallthrough. */
case FLUSH_STAT_FAIL:
mail_flush_deferred();
/* Fallthrough. */
switch (flush_send(argv[1].strval)) {
case FLUSH_STAT_OK:
smtpd_chat_reply(state, "250 Queuing started");
return (0);
case FLUSH_STAT_BAD:
msg_warn("bad ETRN %.100s... from %s", argv[1].strval, state->namaddr);
default:
smtpd_chat_reply(state, "458 Unable to queue messages");
msg_warn("bad ETRN destination %.100s... from %s",
argv[1].strval, state->namaddr);
return (-1);
}
}
@@ -1460,6 +1426,7 @@ int main(int argc, char **argv)
0,
};
static CONFIG_STR_TABLE str_table[] = {
VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
VAR_SMTPD_BANNER, DEF_SMTPD_BANNER, &var_smtpd_banner, 1, 0,
VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,

View File

@@ -27,10 +27,6 @@
/* char *smtpd_check_etrn(state, destination)
/* SMTPD_STATE *state;
/* char *destination;
/*
/* int smtpd_check_etrn_cache_policy_ok(state, destination)
/* SMTPD_STATE *state;
/* char *destination;
/* DESCRIPTION
/* This module implements additional checks on SMTP client requests.
/* A client request is validated in the context of the session state.
@@ -183,11 +179,6 @@
/* Restrictions on the hostname that is sent with the HELO/EHLO
/* command.
/* .PP
/* smtpd_check_etrn_cache_policy_ok() returns "true" if it is OK to
/* create a fast ETRN cache file for the specified destination.
/* The default policy ($smtpd_fast_flush_domains) is that the local MTA
/* must be willing to relay mail to that destination.
/*
/* smtpd_check_size() checks if a message with the given size can
/* be received (zero means that the message size is unknown). The
/* message is rejected when:
@@ -328,7 +319,6 @@ static MAPS *relocated_maps;
*/
static DOMAIN_LIST *relay_domains;
static NAMADR_LIST *mynetworks;
static DOMAIN_LIST *fast_flush_domains;
/*
* Pre-parsed restriction lists.
@@ -454,7 +444,6 @@ void smtpd_check_init(void)
*/
mynetworks = namadr_list_init(var_mynetworks);
relay_domains = domain_list_init(var_relay_domains);
fast_flush_domains = domain_list_init(var_fast_flush_domains);
/*
* Pre-parse and pre-open the recipient maps.
@@ -916,7 +905,7 @@ static int has_my_addr(char *host)
msg_info("%s: host %s", myname, host);
/*
* If we can't lookup the host, say we're not listed.
* If we can't lookup the host, play safe and assume it is OK.
*/
#define YUP 1
#define NOPE 0
@@ -924,12 +913,12 @@ static int has_my_addr(char *host)
if ((hp = gethostbyname(host)) == 0) {
if (msg_verbose)
msg_info("%s: host %s: not found", myname, host);
return (NOPE);
return (YUP);
}
if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
msg_warn("address type %d length %d for %s",
hp->h_addrtype, hp->h_length, host);
return (NOPE);
return (YUP);
}
for (cpp = hp->h_addr_list; *cpp; cpp++) {
memcpy((char *) &addr, *cpp, sizeof(addr));
@@ -1928,41 +1917,6 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
/* smtpd_check_etrn_cache_policy_ok - is it OK to create a fast ETRN cache? */
int smtpd_check_etrn_cache_policy_ok(SMTPD_STATE *unused_state, char *domain)
{
/*
* Fast ETRN cache files are created on demand. Anything else would make
* the feature unusable. However, it should not be possible that some
* network vandal abuses this feature to create lots of bogus fast ETRN
* cache files.
*
* By default, Postfix accepts ETRN commands from everywhere, but will
* create fast ETRN cache files only for destinations that Postfix is
* willing to relay mail to.
*/
/*
* The domain name must exist.
*/
if (dns_lookup_types(domain, 0, (DNS_RR **) 0, (VSTRING *) 0,
(VSTRING *) 0, T_A, T_MX, 0) != DNS_OK)
return (0);
/*
* The domain name must be an authorized relay destination.
*/
if (domain_list_match(fast_flush_domains, domain) == 0)
return (0);
/*
* Must be OK then.
*/
return (1);
}
/* smtpd_check_rcptmap - permit if recipient address matches lookup table */
char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)

View File

@@ -20,7 +20,6 @@ extern char *smtpd_check_rcptmap(SMTPD_STATE *, char *);
extern char *smtpd_check_size(SMTPD_STATE *, off_t);
extern char *smtpd_check_rcpt(SMTPD_STATE *, char *);
extern char *smtpd_check_etrn(SMTPD_STATE *, char *);
extern int smtpd_check_etrn_cache_policy_ok(SMTPD_STATE *, char *);
/* LICENSE
/* .ad