On 05/13/12 10:05, Nigel Kukard wrote:
On 05/10/12 15:04, Gerardo Herzig wrote:El mié, 09-05-2012 a las 22:44 +0000, Nigel Kukard escribió:On 05/09/12 13:05, Gerardo Herzig wrote:Hi all. This is my intented scenario:For all INCOMING mail: - If count (for a given user@domain) reach, say, 10, put it on HOLD - If count (for the same user@domain) reach, say, 20, DEFER it back For that, i have configured 2 policies, like this one sqlite> select * from policies; ID|Name |Priority|Description |Disabled 3 |Default Inbound |10 |Default Inbound System|0 9 |Default Inbound Prio 5|5 |Higher priority |0 And two quotas asociated with that policies: sqlite> select id,policyid,track,verdict,disabled from quotas; ID|PolicyID|Track |Verdict|Disabled 6 |3 |Sender:user@domain|HOLD |0 11|9 |Sender:user@domain|DEFER |0 The limits asociated with that quotas are: sqlite> select * from quotas_limits; ID|QuotasID|Type |CounterLimit|Disabled 7 |6 |MessageCount|3 |0 12|11 |MessageCount|5 |0 As im sending messages, both counters to increase, as expected: sqlite> select * from quotas_tracking; QuotasLimitsID|TrackKey |LastUpdate|Counter 12 |Sender:[email protected]|1336569907|1.99027777777778 7 |Sender:[email protected]|1336569907|1.99027777777778 When quota of id 6 reach its limits, it begins to HOLD (again, as expected)But...counter of quota of id 11 gets no more updated!! And that is *not*what i want. I want to HOLD only *some* emails, if there is too much mail from that user@domain, i want to DEFER (or REJECT maybe, im not shure). So....there is a way to get this thing done?Your configuration looks good. You're right, lower prio's get matched first. What you say above should work as you expect. Could you enable full debugging with all log detail and attach to a reply? Please don't exclude anything, I need to see the version of policyd you using along with each log line.(sent again without sqlite database) Hi Nigel, and thanks for the reply: Here is a complete DEBUG log after sending 8 emails from my gmail account to the test server. Im also attaching the sqlite file (in case you need/want to see anything) Thanks again for your time!I had Robert look over this on Friday, he is able to reproduce it. I can also confirm things should work exactly as yo expecting.We know why its happening, I'm just busy working on a fix.Hoping to have something for Robert to test tomorrow.
Could you try the attached patch against v2.0.12? Regards Nigel
diff --git a/cbp/modules/Quotas.pm b/cbp/modules/Quotas.pm
index e78823e..799606e 100644
--- a/cbp/modules/Quotas.pm
+++ b/cbp/modules/Quotas.pm
@@ -118,9 +118,6 @@ sub check {
# Loop with each policyID
foreach my $policyID (@{$sessionData->{'Policy'}->{$priority}}) {
- # Last if we've exceeded
- last if ($hasExceeded);
-
# Get quota object
my $quotas = getQuotas($server,$policyID);
# Check if we got a quota or not
@@ -133,9 +130,6 @@ sub check {
# Exceeded limit
my $exceededLimit;
- # Last if we've exceeded
- last if ($hasExceeded);
-
# Grab tracking keys
my $key = getKey($server,$quota,$sessionData);
if (!defined($key)) {
@@ -185,37 +179,46 @@ sub check {
# Limit type
my $limitType = lc($limit->{'Type'});
- # Make sure its the MessageCount counter
- if ($limitType eq "messagecount") {
+ # Have we exceeded?
+ if (!$hasExceeded) {
# Check for violation
if ($currentCounter > $limit->{'CounterLimit'}) {
- $hasExceeded = "Policy rejection; Message count quota exceeded";
+ # Check type of violation & set message accordingly
+ if ($limitType eq "messagecount") {
+ $hasExceeded = "Policy rejection; Message count quota exceeded";
+ } elsif ($limitType eq "messagecumulativesize") {
+ $hasExceeded = "Policy rejection; Cumulative message size quota exceeded";
+ }
+ # Set the qtrack that exceeded the limit
+ $exceededQtrack = $qtrack;
}
- # Bump up limit
- $newCounters{$qtrack->{'QuotasLimitsID'}}++;
-
- # Check for cumulative size violation
- } elsif ($limitType eq "messagecumulativesize") {
- # Check for violation
- if ($currentCounter > $limit->{'CounterLimit'}) {
- $hasExceeded = "Policy rejection; Cumulative message size quota exceeded";
+ }
+
+ # Update if not exceeded
+ if (!$hasExceeded) {
+ # If we counting messages, we need to bump if we didn't exceed
+ if ($limitType eq "messagecount") {
+ # Bump message count
+ $newCounters{$qtrack->{'QuotasLimitsID'}}++;
}
}
-
+
} else {
$qtrack->{'QuotasLimitsID'} = $limit->{'ID'};
$qtrack->{'TrackKey'} = $key;
$qtrack->{'Counter'} = 0;
$qtrack->{'LastUpdate'} = $now;
- # Work out the difference to the DB value, we ONLY DO THIS ONCE!!! so if its defined, leave it alone!
+ # We effectively set the counter to 0, if there is no counter already.
+ # This means for message size, its 0 until we hit DATA stage and for message count,
+ # its 0 until like 5 lines below when we bump it.
if (!defined($newCounters{$qtrack->{'QuotasLimitsID'}})) {
$newCounters{$qtrack->{'QuotasLimitsID'}} = $qtrack->{'Counter'};
}
# Check if this is a message counter
if (lc($limit->{'Type'}) eq "messagecount") {
- # Bump up limit
+ # Bump message counter
$newCounters{$qtrack->{'QuotasLimitsID'}}++;
}
}
@@ -230,11 +233,6 @@ sub check {
$qtrack->{'Verdict'} = $quota->{'Verdict'};
$qtrack->{'VerdictData'} = $quota->{'Data'};
- # If we've exceeded setup the qtrack which was exceeded
- if ($hasExceeded) {
- $exceededQtrack = $qtrack;
- }
-
# Save quota tracking info
push(@trackingList,$qtrack);
@@ -243,72 +241,73 @@ sub check {
} # foreach my $quota (@{$quotas})
} # foreach my $priority (sort {$a <=> $b} keys %{$sessionData->{'Policy'}})
- # If we have not exceeded, update
- if (!$hasExceeded) {
-
- # Loop with tracking ID's and update
- foreach my $qtrack (@trackingList) {
+ # Loop with tracking ID's and update
+ foreach my $qtrack (@trackingList) {
- # Percent used
- my $pused = sprintf('%.1f', ( ($newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}) / $qtrack->{'CounterLimit'} ) * 100);
-
- # Update database
+ # Percent used
+ my $pused = sprintf('%.1f', ( ($newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}) / $qtrack->{'CounterLimit'} ) * 100);
+
+ # Update database
+ my $sth = DBDo("
+ UPDATE
+ quotas_tracking
+ SET
+ Counter = Counter + ".DBQuote($newCounters{$qtrack->{'QuotasLimitsID'}}).",
+ LastUpdate = ".DBQuote($now)."
+ WHERE
+ QuotasLimitsID = ".DBQuote($qtrack->{'QuotasLimitsID'})."
+ AND TrackKey = ".DBQuote($qtrack->{'TrackKey'})."
+ ");
+ if (!$sth) {
+ $server->log(LOG_ERR,"[QUOTAS] Failed to update quota_tracking item: ".cbp::dblayer::Error());
+ return $server->protocol_response(PROTO_DB_ERROR);
+ }
+
+ # If nothing updated, then insert our record
+ if ($sth eq "0E0") {
+ # Insert into database
my $sth = DBDo("
- UPDATE
- quotas_tracking
- SET
- Counter = Counter + ".DBQuote($newCounters{$qtrack->{'QuotasLimitsID'}}).",
- LastUpdate = ".DBQuote($now)."
- WHERE
- QuotasLimitsID = ".DBQuote($qtrack->{'QuotasLimitsID'})."
- AND TrackKey = ".DBQuote($qtrack->{'TrackKey'})."
+ INSERT INTO quotas_tracking
+ (QuotasLimitsID,TrackKey,LastUpdate,Counter)
+ VALUES
+ (
+ ".DBQuote($qtrack->{'QuotasLimitsID'}).",
+ ".DBQuote($qtrack->{'TrackKey'}).",
+ ".DBQuote($qtrack->{'LastUpdate'}).",
+ ".DBQuote($newCounters{$qtrack->{'QuotasLimitsID'}})."
+ )
");
if (!$sth) {
- $server->log(LOG_ERR,"[QUOTAS] Failed to update quota_tracking item: ".cbp::dblayer::Error());
+ $server->log(LOG_ERR,"[QUOTAS] Failed to insert quota_tracking item: ".cbp::dblayer::Error());
return $server->protocol_response(PROTO_DB_ERROR);
}
-
- # If nothing updated, then insert our record
- if ($sth eq "0E0") {
- # Insert into database
- my $sth = DBDo("
- INSERT INTO quotas_tracking
- (QuotasLimitsID,TrackKey,LastUpdate,Counter)
- VALUES
- (
- ".DBQuote($qtrack->{'QuotasLimitsID'}).",
- ".DBQuote($qtrack->{'TrackKey'}).",
- ".DBQuote($qtrack->{'LastUpdate'}).",
- ".DBQuote($newCounters{$qtrack->{'QuotasLimitsID'}})."
- )
- ");
- if (!$sth) {
- $server->log(LOG_ERR,"[QUOTAS] Failed to insert quota_tracking item: ".cbp::dblayer::Error());
- return $server->protocol_response(PROTO_DB_ERROR);
- }
- # Log create to mail log
- $server->maillog("module=Quotas, mode=create, host=%s, helo=%s, from=%s, to=%s, reason=quota_create, policy=%s, quota=%s, limit=%s, "
- ."track=%s, counter=%s, quota=%s/%s (%s%%)",
- $sessionData->{'ClientAddress'},
- $sessionData->{'Helo'},
- $sessionData->{'Sender'},
- $sessionData->{'Recipient'},
- $qtrack->{'PolicyID'},
- $qtrack->{'QuotaID'},
- $qtrack->{'LimitID'},
- $qtrack->{'DBKey'},
- $qtrack->{'LimitType'},
- sprintf('%.2f',$newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}),
- $qtrack->{'CounterLimit'},
- $pused);
-
-
- # If we updated ...
- } else {
+ # Log create to mail log
+ $server->maillog("module=Quotas, mode=create, host=%s, helo=%s, from=%s, to=%s, reason=quota_create, policy=%s, quota=%s, limit=%s, "
+ ."track=%s, counter=%s, quota=%s/%s (%s%%)",
+ $sessionData->{'ClientAddress'},
+ $sessionData->{'Helo'},
+ $sessionData->{'Sender'},
+ $sessionData->{'Recipient'},
+ $qtrack->{'PolicyID'},
+ $qtrack->{'QuotaID'},
+ $qtrack->{'LimitID'},
+ $qtrack->{'DBKey'},
+ $qtrack->{'LimitType'},
+ sprintf('%.2f',$newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}),
+ $qtrack->{'CounterLimit'},
+ $pused);
+
+
+ # If we updated ... and customize response if we exceeded
+ } else {
+
+ # Is this the one that exceeded?
+ if (!defined($exceededQtrack) || defined($exceededQtrack->{'LimitID'}) &&
+ $qtrack->{'LimitID'} != $exceededQtrack->{'LimitID'}) {
# Log update to mail log
- $server->maillog("module=Quotas, mode=update, host=%s, helo=%s, from=%s, to=%s, reason=quota_update, policy=%s, quota=%s, limit=%s, "
- ."track=%s, counter=%s, quota=%s/%s (%s%%)",
+ $server->maillog("module=Quotas, mode=update, host=%s, helo=%s, from=%s, to=%s, reason=quota_update, "
+ ."policy=%s, quota=%s, limit=%s, track=%s, counter=%s, quota=%s/%s (%s%%)",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
@@ -321,38 +320,30 @@ sub check {
sprintf('%.2f',$newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}),
$qtrack->{'CounterLimit'},
$pused);
-
+ } else {
+ # Log rejection to mail log
+ $server->maillog("module=Quotas, action=%s, host=%s, helo=%s, from=%s, to=%s, reason=quota_match, "
+ ."policy=%s, quota=%s, limit=%s, track=%s, "
+ ."counter=%s, quota=%s/%s (%s%%)",
+ lc($qtrack->{'Verdict'}),
+ $sessionData->{'ClientAddress'},
+ $sessionData->{'Helo'},
+ $sessionData->{'Sender'},
+ $sessionData->{'Recipient'},
+ $qtrack->{'PolicyID'},
+ $qtrack->{'QuotaID'},
+ $qtrack->{'LimitID'},
+ $qtrack->{'DBKey'},
+ $qtrack->{'LimitType'},
+ sprintf('%.2f',$newCounters{$qtrack->{'QuotasLimitsID'}} + $qtrack->{'Counter'}),
+ $qtrack->{'CounterLimit'},
+ $pused);
+ # Set verdict
+ $verdict = $qtrack->{'Verdict'};
+ $verdict_data = (defined($qtrack->{'VerdictData'}) && $qtrack->{'VerdictData'} ne "")
+ ? $qtrack->{'VerdictData'} : $hasExceeded;
}
-
-
- # Remove limit
- delete($newCounters{$qtrack->{'QuotasLimitsID'}});
}
-
- # If we have exceeded, set verdict
- } else {
- # Percent used
- my $pused = sprintf('%.1f', ( ($newCounters{$exceededQtrack->{'QuotasLimitsID'}} + $exceededQtrack->{'Counter'}) / $exceededQtrack->{'CounterLimit'} ) * 100);
-
- # Log rejection to mail log
- $server->maillog("module=Quotas, action=%s, host=%s, helo=%s, from=%s, to=%s, reason=quota_match, policy=%s, quota=%s, limit=%s, track=%s, "
- ."counter=%s, quota=%s/%s (%s%%)",
- lc($exceededQtrack->{'Verdict'}),
- $sessionData->{'ClientAddress'},
- $sessionData->{'Helo'},
- $sessionData->{'Sender'},
- $sessionData->{'Recipient'},
- $exceededQtrack->{'PolicyID'},
- $exceededQtrack->{'QuotaID'},
- $exceededQtrack->{'LimitID'},
- $exceededQtrack->{'DBKey'},
- $exceededQtrack->{'LimitType'},
- sprintf('%.2f',$newCounters{$exceededQtrack->{'QuotasLimitsID'}} + $exceededQtrack->{'Counter'}),
- $exceededQtrack->{'CounterLimit'},
- $pused);
- $verdict = $exceededQtrack->{'Verdict'};
- $verdict_data = (defined($exceededQtrack->{'VerdictData'}) && $exceededQtrack->{'VerdictData'} ne "")
- ? $exceededQtrack->{'VerdictData'} : $hasExceeded;
}
#
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Users mailing list [email protected] http://lists.policyd.org/mailman/listinfo/users
