You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by mm...@apache.org on 2010/03/30 16:20:03 UTC
svn commit: r929150 - in /spamassassin/trunk/lib/Mail/SpamAssassin: Conf.pm
DnsResolver.pm
Author: mmartinec
Date: Tue Mar 30 14:20:03 2010
New Revision: 929150
URL: http://svn.apache.org/viewvc?rev=929150&view=rev
Log:
Bug 6221: DnsResolver.pm attempts to bind ports at random:
make auxilliary data structures initializations more
self-contained to avoid undef warnings in t/dnsbl_subtests.t;
save about 10 kB when port allocation task is delegated to OS
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm?rev=929150&r1=929149&r2=929150&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Tue Mar 30 14:20:03 2010
@@ -1381,36 +1381,6 @@ directive, falling back to Net::DNS -sup
}
});
-=item dns_local_ports_none
-
-Is a comfortable and faster-to-execute shorthand for:
-
- dns_local_ports_avoid 1-65535
-
-leaving the set of available DNS query local port numbers empty. In all
-respects (apart from speed) it is equivalent to the shown directive, and can
-be freely mixed with I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
-
-If the resulting set of port numbers is empty, then SpamAssassin does not
-apply its ports randomization logic, but instead leaves the operating system
-to choose a suitable free local port number.
-
-See also directives I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
-
-=cut
-
- push (@cmds, {
- setting => 'dns_local_ports_none',
- type => $CONF_TYPE_NOARGS,
- code => sub {
- my ($self, $key, $value, $line) = @_;
- unless (!defined $value || $value eq '') {
- return $INVALID_VALUE;
- }
- wipe_ports_range(\$self->{dns_available_ports_bitset}, 0);
- }
- });
-
=item dns_local_ports_permit ranges...
Add the specified ports or ports ranges to the set of allowed port numbers
@@ -1460,6 +1430,7 @@ See also directives I<dns_local_ports_pe
}
}
foreach my $p (@port_ranges) {
+ undef $self->{dns_available_portscount}; # invalidate derived data
set_ports_range(\$self->{dns_available_ports_bitset},
$p->[0], $p->[1], 1);
}
@@ -1494,12 +1465,44 @@ Please see directive I<dns_local_ports_p
}
}
foreach my $p (@port_ranges) {
+ undef $self->{dns_available_portscount}; # invalidate derived data
set_ports_range(\$self->{dns_available_ports_bitset},
$p->[0], $p->[1], 0);
}
}
});
+=item dns_local_ports_none
+
+Is a fast shorthand for:
+
+ dns_local_ports_avoid 1-65535
+
+leaving the set of available DNS query local port numbers empty. In all
+respects (apart from speed) it is equivalent to the shown directive, and can
+be freely mixed with I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
+
+If the resulting set of port numbers is empty, then SpamAssassin does not
+apply its ports randomization logic, but instead leaves the operating system
+to choose a suitable free local port number.
+
+See also directives I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
+
+=cut
+
+ push (@cmds, {
+ setting => 'dns_local_ports_none',
+ type => $CONF_TYPE_NOARGS,
+ code => sub {
+ my ($self, $key, $value, $line) = @_;
+ unless (!defined $value || $value eq '') {
+ return $INVALID_VALUE;
+ }
+ undef $self->{dns_available_portscount}; # invalidate derived data
+ wipe_ports_range(\$self->{dns_available_ports_bitset}, 0);
+ }
+ });
+
=item dns_test_interval n (default: 600 seconds)
If dns_available is set to 'test' (which is the default), the dns_test_interval
@@ -3730,9 +3733,6 @@ sub new {
$self->{encapsulated_content_description} = 'original message before SpamAssassin';
- # ensure the ports bitset is initialized
- set_ports_range(\$self->{conf}->{dns_available_ports_bitset}, 0, 0, 0);
-
$self;
}
@@ -3941,6 +3941,8 @@ sub set_ports_range {
if (!defined $$bitset_ref) { # provide a sensible default
wipe_ports_range($bitset_ref, 1); # turn on all bits 0..65535
vec($$bitset_ref,$_,1) = 0 for 0..1023; # avoid 0 and privileged ports
+ } elsif ($$bitset_ref eq '') { # repopulate the bitset (late configuration)
+ wipe_ports_range($bitset_ref, 0); # turn off all bits 0..65535
}
$value = !$value ? 0 : 1;
for (my $j = $port_range_lo; $j <= $port_range_hi; $j++) {
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm?rev=929150&r1=929149&r2=929150&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm Tue Mar 30 14:20:03 2010
@@ -203,7 +203,7 @@ sub disable_available_port {
my($self, $lport) = @_;
if ($lport >= 0 && $lport <= 65535) {
my $conf = $self->{conf};
- if (!$conf->{dns_available_portscount_buckets}) {
+ if (!defined $conf->{dns_available_portscount}) {
$self->pick_random_available_port(); # initialize
}
if (vec($conf->{dns_available_ports_bitset}, $lport, 1)) {
@@ -220,11 +220,15 @@ sub pick_random_available_port {
my $port_number; # resulting port number, or undef if none available
my $conf = $self->{conf};
- my $ports_bitset = $conf->{dns_available_ports_bitset};
my $available_portscount = $conf->{dns_available_portscount};
- # initialize when here for the first time
+ # initialize when called for the first time or after a config change
if (!defined $available_portscount) {
+ my $ports_bitset = $conf->{dns_available_ports_bitset};
+ if (!defined $ports_bitset) { # ensure it is initialized
+ Mail::SpamAssassin::Conf::set_ports_range(\$ports_bitset, 0, 0, 0);
+ $conf->{dns_available_ports_bitset} = $ports_bitset;
+ }
# prepare auxilliary data structure to speed up further free-port lookups;
# 256 buckets, each accounting for 256 ports: 8+8 = 16 bit port numbers;
# each bucket holds a count of available ports in its range
@@ -245,12 +249,18 @@ sub pick_random_available_port {
$bucket_counts[$bucket] = $cnt;
}
$conf->{dns_available_portscount} = $available_portscount;
- $conf->{dns_available_portscount_buckets} = \@bucket_counts;
+ if ($available_portscount) {
+ $conf->{dns_available_portscount_buckets} = \@bucket_counts;
+ } else { # save some storage
+ $conf->{dns_available_portscount_buckets} = undef;
+ $conf->{dns_available_ports_bitset} = '';
+ }
}
# find the n-th port number from the ordered set of available port numbers
dbg("dns: %d configured local ports for DNS queries", $available_portscount);
if ($available_portscount > 0) {
+ my $ports_bitset = $conf->{dns_available_ports_bitset};
my $n = int(rand($available_portscount));
my $bucket_counts_ref = $conf->{dns_available_portscount_buckets};
my $ind = 0;