Add support for multiple postfix cleanup sockets

The current postfix-queue plugin allows the administrator to set a
single path to a local postfix cleanup socket file from the plugin
'command line'.  This adds a 'cleanup_sockets' configuration directive
that can contain a list of paths as well as host/port combinations
pointing to postfix cleanup services, which will be tried in the order
that they appear.  Not yet tested.
This commit is contained in:
jaredj 2009-03-05 08:06:50 +08:00 committed by Ask Bjørn Hansen
parent 5c3bd220aa
commit 295474503f
2 changed files with 32 additions and 13 deletions

View File

@ -14,6 +14,7 @@ details.
use strict; use strict;
use IO::Socket::UNIX; use IO::Socket::UNIX;
use IO::Socket::INET;
use vars qw(@ISA); use vars qw(@ISA);
@ISA = qw(IO::Socket::UNIX); @ISA = qw(IO::Socket::UNIX);
@ -92,12 +93,22 @@ sub print_rec_time {
sub open_cleanup { sub open_cleanup {
my ($class, $socket) = @_; my ($class, $socket) = @_;
$socket = "/var/spool/postfix/public/cleanup" my $self;
unless defined $socket; if ($socket =~ m#^(/.+)#) {
$socket = $1; # un-taint socket path
my $self = IO::Socket::UNIX->new(Type => SOCK_STREAM, $self = IO::Socket::UNIX->new(Type => SOCK_STREAM,
Peer => $socket); Peer => $socket) if $socket;
die qq(Couldn't open unix socket "$socket": $!) unless ref $self;
} elsif ($socket =~ /(.*):(\d+)/) {
my ($host,$port) = ($1,$2); # un-taint address and port
$self = IO::Socket::INET->new(Proto => 'tcp',
PeerAddr => $host,PeerPort => $port)
if $host and $port;
}
unless (ref $self) {
warn "Couldn't open \"$socket\": $!";
return;
}
# allow buffered writes # allow buffered writes
$self->autoflush(0); $self->autoflush(0);
bless ($self, $class); bless ($self, $class);
@ -163,7 +174,11 @@ $transaction is supposed to be a Qpsmtpd::Transaction object.
sub inject_mail { sub inject_mail {
my ($class, $transaction) = @_; my ($class, $transaction) = @_;
my $strm = $class->open_cleanup($transaction->notes('postfix-queue-socket')); my @sockets = @{$transaction->notes('postfix-queue-sockets')
// ['/var/spool/postfix/public/cleanup']};
my $strm;
$strm = $class->open_cleanup($_) and last for @sockets;
die "Unable to open any cleanup sockets!" unless $strm;
my %at = $strm->get_attr; my %at = $strm->get_attr;
my $qid = $at{queue_id}; my $qid = $at{queue_id};

View File

@ -11,7 +11,10 @@ This plugin passes mails on to the postfix cleanup daemon.
The first optional parameter is the location of the cleanup socket. If it does The first optional parameter is the location of the cleanup socket. If it does
not start with a ``/'', it is treated as a flag for cleanup (see below). not start with a ``/'', it is treated as a flag for cleanup (see below).
If set, the environment variable POSTFIXQUEUE overrides this setting. The 'postfix_queue' plugin can also contain a list of cleanup socket paths
and/or remote postfix cleanup service hosts specified in the form of
'address:port'. If set, the environment variable POSTFIXQUEUE overrides both
of these settings.
All other parameters are flags for cleanup, no flags are enabled by default. All other parameters are flags for cleanup, no flags are enabled by default.
See below in ``POSTFIX COMPATIBILITY'' for flags understood by your postfix See below in ``POSTFIX COMPATIBILITY'' for flags understood by your postfix
@ -133,9 +136,6 @@ sub register {
$self->{_queue_socket} = $1; $self->{_queue_socket} = $1;
shift @args; shift @args;
} }
else {
$self->{_queue_socket} = "/var/spool/postfix/public/cleanup";
}
foreach (@args) { foreach (@args) {
if ($self->can("CLEANUP_".$_) and /^(FLAG_[A-Z0-9_]+)$/) { if ($self->can("CLEANUP_".$_) and /^(FLAG_[A-Z0-9_]+)$/) {
@ -152,14 +152,18 @@ sub register {
$self->{_queue_socket} = "/var/spool/postfix/public/cleanup"; $self->{_queue_socket} = "/var/spool/postfix/public/cleanup";
} }
$self->{_queue_socket} = $ENV{POSTFIXQUEUE} if $ENV{POSTFIXQUEUE}; $self->{_queue_socket_env} = $ENV{POSTFIXQUEUE} if $ENV{POSTFIXQUEUE};
} }
sub hook_queue { sub hook_queue {
my ($self, $transaction) = @_; my ($self, $transaction) = @_;
$transaction->notes('postfix-queue-flags', $self->{_queue_flags}); $transaction->notes('postfix-queue-flags', $self->{_queue_flags});
$transaction->notes('postfix-queue-socket', $self->{_queue_socket}); my @queue;
@queue = ($self->{_queue_socket_env}) if $self->{_queue_socket_env};
@queue = $self->qp->config('cleanup_sockets') unless @queue;
@queue = ($self->{_queue_socket} // ()) unless @queue;
$transaction->notes('postfix-queue-sockets', \@queue) if @queue;
# $self->log(LOGDEBUG, "queue-flags=".$transaction->notes('postfix-queue-flags')); # $self->log(LOGDEBUG, "queue-flags=".$transaction->notes('postfix-queue-flags'));
my ($status, $qid, $reason) = Qpsmtpd::Postfix->inject_mail($transaction); my ($status, $qid, $reason) = Qpsmtpd::Postfix->inject_mail($transaction);