<NME> random_error
<BEF> #!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 {
sub NEXT() { DECLINED }

sub random_fail {
	my $self = shift;
	my $fpct = $self->qp->connection->notes('random_fail_%');
	rand(100) > ($fpct / 6) and return NEXT;
	rand(5) < 2 and return (DENYSOFT_DISCONNECT, "random failure");
	return (DENYSOFT, "random failure");
}


sub hook_connect {
    $self->qp->connection->notes('random_fail_%', $self->{__PACKAGE__.'_how'});
    goto &random_fail
}

    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;
}


<MSG> Updates to the random_error sample plugin from David Nicol

Signed-off-by: Robert <c9484850f6ee3d3fb73f3c3345f26ec064da35e4@pobox.com>

<DFF> @@ -30,16 +30,31 @@ sub register {
 sub NEXT() { DECLINED }
 
 sub random_fail {
-	my $self = shift;
-	my $fpct = $self->qp->connection->notes('random_fail_%');
-	rand(100) > ($fpct / 6) and return NEXT;
+        my $fpct = $_[0]->qp->connection->notes('random_fail_%');
+
+=head 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 {
-    $self->qp->connection->notes('random_fail_%', $self->{__PACKAGE__.'_how'});
+    $_[0]->qp->connection->notes('random_fail_%', $_[0]->{__PACKAGE__.'_how'});
     goto &random_fail
 }
 

{'addition_count': 19, 'commit_subject': 'Updates to the random_error sample plugin from David Nicol', 'deletion_count': 4, 'file_extension': '', 'lang': 'random_error', 'license': 'mit', 'repo_name': 'smtpd/qpsmtpd'}