1e82ae1bc7
1. the known users of async don't upgrade 2. async becomes a win when concurrent connections exceed a few hundred simultaneous 3. anyone that needs async should be looking at Haraka instead 4. the perl async dependencies aren't maintained
94 lines
2.8 KiB
Plaintext
94 lines
2.8 KiB
Plaintext
#
|
|
# This file is best read with ``perldoc advanced.pod''
|
|
#
|
|
|
|
###
|
|
# Conventions:
|
|
# plugin names: F<myplugin>
|
|
# constants: I<LOGDEBUG>
|
|
# smtp commands, answers: B<HELO>, B<250 Queued!>
|
|
#
|
|
# Notes:
|
|
# * due to restrictions of some POD parsers, no C<<$object->method()>>
|
|
# are allowed, use C<$object-E<gt>method()>
|
|
#
|
|
|
|
=head1 Advanced Playground
|
|
|
|
=head2 Discarding messages
|
|
|
|
If you want to make the client think a message has been regularily accepted,
|
|
but in real you delete it or send it to F</dev/null>, ..., use something
|
|
like the following plugin and load it before your default queue plugin.
|
|
|
|
sub hook_queue {
|
|
my ($self, $transaction) = @_;
|
|
if ($transaction->notes('discard_mail')) {
|
|
my $msg_id = $transaction->header->get('Message-Id') || '';
|
|
$msg_id =~ s/[\r\n].*//s;
|
|
return(OK, "Queued! $msg_id");
|
|
}
|
|
return(DECLINED);
|
|
}
|
|
|
|
|
|
=head2 Changing return values
|
|
|
|
This is an example how to use the C<isa_plugin> method.
|
|
|
|
The B<rcpt_ok_maxrelay> plugin wraps the B<rcpt_ok> plugin. The B<rcpt_ok>
|
|
plugin checks the F<rcpthosts> and F<morercpthosts> config files for
|
|
domains, which we accept mail for. If not found it tells the
|
|
client that relaying is not allowed. Clients which are marked as
|
|
C<relay clients> are excluded from this rule. This plugin counts the
|
|
number of unsuccessfull relaying attempts and drops the connection if
|
|
too many were made.
|
|
|
|
The optional parameter I<MAX_RELAY_ATTEMPTS> configures this plugin to drop
|
|
the connection after I<MAX_RELAY_ATTEMPTS> unsuccessful relaying attempts.
|
|
Set to C<0> to disable, default is C<5>.
|
|
|
|
Note: Do not load both (B<rcpt_ok> and B<rcpt_ok_maxrelay>). This plugin
|
|
should be configured to run I<last>, like B<rcpt_ok>.
|
|
|
|
use Qpsmtpd::DSN;
|
|
|
|
sub init {
|
|
my ($self, $qp, @args) = @_;
|
|
die "too many arguments"
|
|
if @args > 1;
|
|
$self->{_count_relay_max} = defined $args[0] ? $args[0] : 5;
|
|
$self->isa_plugin("rcpt_ok");
|
|
}
|
|
|
|
sub hook_rcpt {
|
|
my ($self, $transaction, $recipient) = @_;
|
|
my ($rc, @msg) = $self->SUPER::hook_rcpt($transaction, $recipient);
|
|
|
|
return ($rc, @msg)
|
|
unless (($rc == DENY) and $self->{_count_relay_max});
|
|
|
|
my $count =
|
|
($self->connection->notes('count_relay_attempts') || 0) + 1;
|
|
$self->connection->notes('count_relay_attempts', $count);
|
|
|
|
return ($rc, @msg) unless ($count > $self->{_count_relay_max});
|
|
return Qpsmtpd::DSN->relaying_denied(DENY_DISCONNECT,
|
|
"Too many relaying attempts");
|
|
}
|
|
|
|
=head2 Results of other hooks
|
|
|
|
B<NOTE:> just copied from README.plugins
|
|
|
|
If we're in a transaction, the results of a callback are stored in
|
|
|
|
$self->transaction->notes( $code->{name})->{"hook_$hook"}->{return}
|
|
|
|
If we're in a connection, store things in the connection notes instead.
|
|
B<FIXME>: does the above (regarding connection notes) work?
|
|
|
|
=cut
|
|
|
|
# vim: ts=2 sw=2 expandtab
|