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/04/06 01:54:42 UTC
svn commit: r930986 - /spamassassin/trunk/t/dnsbl_subtests.t
Author: mmartinec
Date: Mon Apr 5 23:54:41 2010
New Revision: 930986
URL: http://svn.apache.org/viewvc?rev=930986&view=rev
Log:
Bug 6362: let t/dnsbl_subtests.t choose a random free port
instead of using a fixed preconfigured port number for the
spawned test DNS server
Modified:
spamassassin/trunk/t/dnsbl_subtests.t
Modified: spamassassin/trunk/t/dnsbl_subtests.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/dnsbl_subtests.t?rev=930986&r1=930985&r2=930986&view=diff
==============================================================================
--- spamassassin/trunk/t/dnsbl_subtests.t (original)
+++ spamassassin/trunk/t/dnsbl_subtests.t Mon Apr 5 23:54:41 2010
@@ -25,12 +25,23 @@ if (-e 'test_dir') { # runnin
$prefix = '..';
}
+use Errno qw(EADDRINUSE EACCES);
+use IO::Socket::INET;
+use Net::DNS::Nameserver;
+use Mail::SpamAssassin;
+
# Bug 5761 (no 127.0.0.1 in jail, use SPAMD_LOCALHOST if specified)
my $dns_server_localaddr = $ENV{'SPAMD_LOCALHOST'};
$dns_server_localaddr = '127.0.0.1' if !$dns_server_localaddr;
-$dns_server_localaddr = '::1' if !$dns_server_localaddr;
-my $dns_server_localport = '5353'; # some port (mdns), hopefully free
+sub find_free_port($); # prototype
+my($dns_server_localport, $sock_udp, $sock_tcp) =
+ find_free_port($dns_server_localaddr);
+
+$dns_server_localport or die "Failed to obtain a free port number";
+
+printf("Using [%s]:%s for a spawned test DNS server\n",
+ $dns_server_localaddr, $dns_server_localport);
# test zones
my $z = 'sa1-dbl-test.spamassassin.org';
@@ -170,8 +181,6 @@ EOD
# ---------------------------------------------------------------------------
-use Net::DNS::Nameserver;
-
sub reply_handler {
my($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
my($rcode, @ans, @auth, @add);
@@ -215,9 +224,26 @@ sub dns_server($$) {
$ns->main_loop;
}
+sub find_free_port($) {
+ my($addr) = @_;
+ my($port, $sock_udp, $sock_tcp);
+ for (1..20) { # choose a pair of free tcp & udp ports
+ $port = 11001 + int(rand(65536-11001));
+ my %args = (LocalAddr => $addr, LocalPort => $port);
+ $sock_udp = IO::Socket::INET->new(%args, Proto => 'udp');
+ $sock_udp || $! == EADDRINUSE || $! == EACCES
+ or printf("Error creating UDP socket [%s]:%s: %s\n", $addr, $port, $!);
+ $sock_tcp = IO::Socket::INET->new(%args, Proto => 'tcp');
+ $sock_tcp || $! == EADDRINUSE || $! == EACCES
+ or printf("Error creating TCP socket [%s]:%s: %s\n", $addr, $port, $!);
+ last if $sock_tcp && $sock_udp;
+ }
+ undef $port if !$sock_tcp || !$sock_udp;
+ return ($port, $sock_udp, $sock_tcp);
+}
+
# ---------------------------------------------------------------------------
-use Mail::SpamAssassin;
my $spamassassin_obj;
sub process_sample_urls(@) {
@@ -267,6 +293,18 @@ sub test_samples($$) {
join(', ',@$url_list_ref), $spam_report) if !$status;
}
+
+# there is a time gap between closing sockets and reusing them by a spawned
+# DNS server - if we are very unlucky and the port is acquired by some other
+# process during this short interval, our spawned DNS server will fail to start
+#
+if ($sock_udp) {
+ $sock_udp->close() or die "Error closing UDP socket: $!";
+}
+if ($sock_tcp) {
+ $sock_tcp->close() or die "Error closing TCP socket: $!";
+}
+
# detach a DNS server process
my $pid = fork();
defined $pid or die "Cannot fork: $!";