diff options
author | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2016-10-19 16:56:37 +0200 |
---|---|---|
committer | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2016-10-20 00:48:28 +0200 |
commit | df613eb4a1b386c3b57baf09a25511894460b9b1 (patch) | |
tree | 1262448a6a1757d96c7ea7ce58266dba7cf25ba3 | |
parent | 8bcf560784a5a3e55d9f33e5c4b6cbb77467f70e (diff) |
Testsuite: Add PORT_DYNAMIC (Bug 1775)
This avoids problems on OpenBSD with SO_REUSEADDR.
On OpenBSD SO_REUSEADDR only works if the IP address AND the EUID
of the bind(2) calls match. In 0562 Exim binds to 1225 as euid=0,
in 0564 runtest tries to bind to 01225 as the user running the tests.
Thanks to Kirill Miazine for working this out.
-rwxr-xr-x | test/runtest | 40 | ||||
-rw-r--r-- | test/scripts/0000-Basic/0564 | 4 | ||||
-rw-r--r-- | test/stdout/0564 | 2 |
3 files changed, 29 insertions, 17 deletions
diff --git a/test/runtest b/test/runtest index ce03fb7d1..a66c589f8 100755 --- a/test/runtest +++ b/test/runtest @@ -17,6 +17,7 @@ #use 5.010; use Errno; use FileHandle; +use IO::Socket::INET; use Socket; use Time::Local; use Cwd; @@ -81,6 +82,7 @@ $parm_port_d = 1225; # Used for the Exim daemon $parm_port_d2 = 1226; # Additional for daemon $parm_port_d3 = 1227; # Additional for daemon $parm_port_d4 = 1228; # Additional for daemon +my $dynamic_socket; # allocated later for PORT_DYNAMIC # Manually set locale $ENV{LC_ALL} = 'C'; @@ -142,6 +144,7 @@ s?\bPORT_S\b?$parm_port_s?g; s?\bTESTNUM\b?$_[0]?g; s?(\b|_)V4NET([\._])?$1$parm_ipv4_test_net$2?g; s?\bV6NET:?$parm_ipv6_test_net:?g; +s?\bPORT_DYNAMIC\b?$dynamic_socket->sockport()?eg; } @@ -676,6 +679,10 @@ RESET_AFTER_EXTRA_LINE_READ: # Port in host address in spool file output from -Mvh s/^-host_address (.*)\.\d+/-host_address $1.9999/; + if ($dynamic_socket and $dynamic_socket->opened and my $port = $dynamic_socket->sockport) { + s/^Connecting to 127\.0\.0\.1 port \K$port/<dynamic port>/; + } + # ======== Local IP addresses ======== # The amount of space between "host" and the address in verification output @@ -2226,31 +2233,24 @@ elsif (/^((?i:[A-Z\d_]+=\S+\s+)+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+ } elsif ($cmd =~ /\s-DSERVER=wait:(\d+)\s/) { + + # The port and the $dynamic_socket was already allocated while parsing the + # script file, where -DSERVER=wait:PORT_DYNAMIC was encountered. + my $listen_port = $1; - my $waitmode_sock = new FileHandle; if ($debug) { printf ">> wait-mode daemon: $cmd\n"; } run_system("sudo mkdir spool/log 2>/dev/null"); run_system("sudo chown $parm_eximuser:$parm_eximgroup spool/log"); - my ($s_ip,$s_port) = ('127.0.0.1', $listen_port); - my $sin = sockaddr_in($s_port, inet_aton($s_ip)) - or die "** Failed packing $s_ip:$s_port\n"; - socket($waitmode_sock, PF_INET, SOCK_STREAM, getprotobyname('tcp')) - or die "** Unable to open socket $s_ip:$s_port: $!\n"; - setsockopt($waitmode_sock, SOL_SOCKET, SO_REUSEADDR, 1) - or die "** Unable to setsockopt(SO_REUSEADDR): $!\n"; - bind($waitmode_sock, $sin) - or die "** Unable to bind socket ($s_port): $!\n"; - listen($waitmode_sock, 5); my $pid = fork(); if (not defined $pid) { die "** fork failed: $!\n" } if (not $pid) { close(STDIN); - open(STDIN, "<&", $waitmode_sock) or die "** dup sock to stdin failed: $!\n"; - close($waitmode_sock); + open(STDIN, '<&', $dynamic_socket) or die "** dup sock to stdin failed: $!\n"; + close($dynamic_socket); print "[$$]>> ${cmd}-server\n" if ($debug); exec "exec ${cmd}-server"; - exit(1); + die "Can't exec ${cmd}-server: $!\n"; } while (<SCRIPT>) { $lineno++; last if /^\*{4}\s*$/; } # Ignore any input select(undef, undef, undef, 0.3); # Let the daemon get going @@ -3596,6 +3596,8 @@ foreach $test (@test_list) my($docheck) = 1; my($thistestdir) = substr($test, 0, -5); + $dynamic_socket->close() if $dynamic_socket; + if ($lasttestdir ne $thistestdir) { $gnutls = 0; @@ -3664,6 +3666,16 @@ foreach $test (@test_list) if (/^no_stdout_check/) { $stdout_skip = 1; next; } if (/^rmfiltertest/) { $rmfiltertest = 1; next; } if (/^sortlog/) { $sortlog = 1; next; } + if (/\bPORT_DYNAMIC\b/) { + for (my $port = 1024; $port < 65000; $port++) { + $dynamic_socket = IO::Socket::INET->new( + LocalHost => '127.0.0.1', + LocalPort => $port, + Listen => 10, + ReuseAddr => 1, + ) and last; + } + } } # Reset to beginning of file for per test interpreting/processing seek(SCRIPT, 0, 0); diff --git a/test/scripts/0000-Basic/0564 b/test/scripts/0000-Basic/0564 index 68fb607ec..26acd66d2 100644 --- a/test/scripts/0000-Basic/0564 +++ b/test/scripts/0000-Basic/0564 @@ -1,9 +1,9 @@ # testing -bw inetd wait mode need_ipv4 # -exim -DSERVER=wait:PORT_D -bw +exim -DSERVER=wait:PORT_DYNAMIC -bw **** -client 127.0.0.1 PORT_D +client 127.0.0.1 PORT_DYNAMIC ??? 220 ehlo abcd ??? 250- diff --git a/test/stdout/0564 b/test/stdout/0564 index 6f4f06bdb..33492a729 100644 --- a/test/stdout/0564 +++ b/test/stdout/0564 @@ -1,4 +1,4 @@ -Connecting to 127.0.0.1 port 1225 ... connected +Connecting to 127.0.0.1 port <dynamic port> ... connected ??? 220 <<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 >>> ehlo abcd |