initlog($prog_name, 'mail');
-if (!GetOptions ('testmode=s' => \$opt_testmode,
- 'pidfile=s' => \$opt_pidfile,
- 'untrusted' => \$opt_untrusted,
- 'database=s' => \$opt_database)) {
+if (!GetOptions(
+ 'testmode=s' => \$opt_testmode,
+ 'pidfile=s' => \$opt_pidfile,
+ 'untrusted' => \$opt_untrusted,
+ 'database=s' => \$opt_database
+)) {
die "usage error\n";
exit (-1);
}
exit (0);
}
+ my $memory = PMG::Config::Mail::physical_memory();
+ if ($memory < 3840) {
+ warn "total memory below 4 GiB, consider setting 'max_filters' manually to avoid OOM-kills\n"
+ if !defined($pmg_cfg->get('mail', 'max_filters', 1));
+ }
+
$max_servers = $pmg_cfg->get('mail', 'max_filters') + 2;
$min_servers = 2;
$min_spare_servers = 1;
$max_requests = 20;
}
+print "using pre-fork workers with min=$min_servers, max=$max_servers, min_spare=$min_spare_servers"
+ .", max_spare=$max_spare_servers, max_requests=$max_requests\n";
+
$opt_max_dequeue = 0 if $opt_testmode;
my $daemonize = 1;
my %rule_targets;
my %rule_actions;
my %rule_marks;
+ my %rule_spaminfo;
my $matching_rules = [];
my $rulecache = $self->{rulecache};
next;
}
- $rule_marks{$rule->{id}} =
+ my ($marks, $spaminfo) =
$rulecache->what_match ($rule->{id}, $queue, $entity, $msginfo, $dbh);
+ $rule_marks{$rule->{id}} = $marks;
+ $rule_spaminfo{$rule->{id}} = $spaminfo;
+
$rule_actions{$rule->{id}} = $rulecache->get_actions ($rule->{id});
my $fin = $rulecache->final ($rule->{id});
next if $final->{$target};
next if !defined ($rule_marks{$rule->{id}});
next if !defined ($rule_marks{$rule->{id}}->{$target});
- next if !defined ($rule_marks{$rule->{id}}->{$target}->{marks});
next if !$rulecache->to_match ($rule->{id}, $target, $ldap);
$final->{$target} = $fin;
my $mod_group = PMG::ModGroup->new($entity, $msginfo->{targets});
+ my $processing_time = int(tv_interval($msginfo->{starttime}));
+ my $filter_timeout = $self->{pmg_cfg}->get('mail', 'filter-timeout');
+ die "processing took ${processing_time}s, longer than the timeout (${filter_timeout}s)\n"
+ if $processing_time > $filter_timeout;
+
foreach my $rule (@$rules) {
my $targets = $rule_targets{$rule->{id}};
next if !$targets;
- my $spaminfo;
- foreach my $t (@$targets) {
- if ($rule_marks{$rule->{id}}->{$t} && $rule_marks{$rule->{id}}->{$t}->{spaminfo}) {
- $spaminfo = $rule_marks{$rule->{id}}->{$t}->{spaminfo};
- # we assume spam info is the same for all matching targets
- last;
- }
- }
-
my $vars = $self->get_prox_vars (
- $queue, $entity, $msginfo, $rule, $rule_targets{$rule->{id}}, $spaminfo);
+ $queue, $entity, $msginfo, $rule, $rule_targets{$rule->{id}}, $rule_spaminfo{$rule->{id}});
my @sorted_actions = sort {$a->priority <=> $b->priority} @{$rule_actions{$rule->{id}}};
foreach my $action (@sorted_actions) {
$action->execute(
$queue, $self->{ruledb}, $mod_group, $rule_targets{$rule->{id}}, $msginfo, $vars,
- $rule_marks{$rule->{id}}->{marks}, $ldap
+ $rule_marks{$rule->{id}}, $ldap
);
last if $action->final;
}
my $prop = $self->{server};
if ($self->{ruledb}) {
- $self->log (0, "reloading configuration $database");
+ $self->log ('info', "reloading configuration $database");
$self->{ruledb}->close ();
}
$prop->{log_level} = 3;
- $self->log (0, "Filter daemon (re)started (max. $max_servers processes)");
+ $self->log ('info', "Filter daemon (re)started (max. $max_servers processes)");
eval { PMG::MailQueue::cleanup_active(); };
$self->log (0, "Cleanup failures: $@") if $@;
$self->log (2, "starting database maintenance");
- my ($csec, $usec) = gettimeofday ();
+ my $starttime = [ gettimeofday() ];
my $cinfo = PVE::INotify::read_file("cluster.conf");
if ($err) {
$self->log (0, $err);
} else {
- my ($csec_end, $usec_end) = gettimeofday ();
- my $ptime = int (($csec_end - $csec) * 1000 + ($usec_end - $usec) / 1000);
+ my $ptime = int(tv_interval($starttime) * 1000);
$self->log (2, "end database maintenance ($ptime ms)");
}
if (PMG::Unpack::is_archive ($magic)) {
$self->log (3, "$queue->{logid}: found archive '$filename' ($magic)");
- my $start = [gettimeofday];
+ my $start = [ gettimeofday() ];
$unpack->{mime} = {};
sub handle_smtp {
my ($self, $smtp) = @_;
- my ($csec, $usec) = gettimeofday ();
+ my $starttime = [ gettimeofday() ];
my $queue;
my $msginfo = {};
$msginfo->{fqdn} = $msginfo->{hostname};
$msginfo->{fqdn} .= ".$msginfo->{domain}" if $msginfo->{domain};
$msginfo->{lcid} = $lcid;
+ $msginfo->{starttime} = $starttime;
# $msginfo->{targets} is case sensitive,
# but pmail is always lower case!
my $maxfiles = $pmg_cfg->get('clamav', 'archivemaxfiles');
- my $entity = $queue->parse_mail($maxfiles);
+ my ($entity, $max_aid) = $queue->parse_mail($maxfiles);
+ $msginfo->{max_aid} = $max_aid;
$self->log (3, "$queue->{logid}: new mail message-id=%s", $queue->{msgid});
my $decdir = $queue->{dumpdir} . "/__decoded_archives";
mkdir $decdir;
- my $start = [gettimeofday];
+ my $start = [ gettimeofday() ];
my $unpack;
eval {
die $err if $err;
- my ($csec_end, $usec_end) = gettimeofday ();
- my $time_total =
- int (($csec_end-$csec)*1000 + ($usec_end - $usec)/1000);
+ my $time_total = int(tv_interval($starttime) * 1000);
# PHASE 5 - log statistics
# on error: log error messages
$server->run();
} else {
- my $sender ='sender@proxtest.com';
- my $targets = ['target1@proxtest.com',
- 'target2@proxtest.com',
- 'target3@proxtest.com'];
+ my $sender ='sender@pmg.example';
+ my $targets = [
+ 'target1@pmg.example',
+ 'target2@pmg.example',
+ 'target3@pmg.example',
+ ];
my $smtp;
while (!$smtp) {