qpsmtpd/plugins/random_error
2013-08-05 15:05:15 -07:00

93 lines
1.8 KiB
Perl

#!perl -w
use strict;
use warnings;
use Qpsmtpd::Constants;
=head1 NAME
random_error
=head1 DESCRIPTION
This plugin randomly disconnects and issues DENYSOFTs.
=head1 CONFIG
one parameter is allowed, which is how often to error, as a percentage
of messages. The default is 1. Use a negative number to disable.
2/5 of failures are DENYSOFT_DISCONNECT, 3/5 simply DENYSOFT.
For use with other plugins, scribble the revised failure rate to
$self->connection->notes('random_fail_%');
=cut
sub register {
my ($self, $qp, @args) = @_;
die "Invalid args: '@args'" unless @args < 2;
($self->{__PACKAGE__ . '_how'}) = $args[0] || 1;
}
sub NEXT() { DECLINED }
sub random_fail {
my $fpct = $_[0]->connection->notes('random_fail_%');
=head1 calculating the probability of failure
There are six tests a message must pass to reach the queueing stage, and we wish to
provide random failure for each one, with the combined probability being out
configuration argument. So we want to solve this equation:
(1-x) ** 6 = ( 1 - input_number )
or
x = 1 - ( (1 - input_number ) ** (1/6) )
=cut
my $successp = 1 - ($fpct / 100);
$_[0]->log(LOGINFO,
"to fail, rand(1) must be more than " . ($successp**(1 / 6)));
rand(1) < ($successp**(1 / 6)) and return NEXT;
rand(5) < 2 and return (DENYSOFT_DISCONNECT, "random failure");
return (DENYSOFT, "random failure");
}
sub hook_connect {
$_[0]->connection->notes('random_fail_%', $_[0]->{__PACKAGE__ . '_how'});
goto &random_fail;
}
sub hook_helo {
goto &random_fail;
}
sub hook_ehlo {
goto &random_fail;
}
sub hook_mail {
goto &random_fail;
}
sub hook_rcpt {
goto &random_fail;
}
sub hook_data {
goto &random_fail;
}
sub hook_data_post {
goto &random_fail;
}