From 2c05d8f1f019508c385658e9b4985a7b09c4fb7a Mon Sep 17 00:00:00 2001 From: vgross Date: Wed, 14 Oct 2015 12:38:52 +0000 Subject: [PATCH] add regress tests for automatic port allocation --- regress/sys/netinet6/autoport/Makefile | 9 ++ regress/sys/netinet6/autoport/autoport.pl | 157 ++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 regress/sys/netinet6/autoport/Makefile create mode 100644 regress/sys/netinet6/autoport/autoport.pl diff --git a/regress/sys/netinet6/autoport/Makefile b/regress/sys/netinet6/autoport/Makefile new file mode 100644 index 00000000000..01c5cb89885 --- /dev/null +++ b/regress/sys/netinet6/autoport/Makefile @@ -0,0 +1,9 @@ +# $OpenBSD: Makefile,v 1.1 2015/10/14 12:38:52 vgross Exp $ + +REGRESS_TARGETS= run-regress-autoport +REGRESS_ROOT_TARGETS= $(REGRESS_TARGETS) + +run-regress-autoport: + ./autoport.pl 6 30000 31000 64 + +.include diff --git a/regress/sys/netinet6/autoport/autoport.pl b/regress/sys/netinet6/autoport/autoport.pl new file mode 100644 index 00000000000..57d16a8987d --- /dev/null +++ b/regress/sys/netinet6/autoport/autoport.pl @@ -0,0 +1,157 @@ +#!/usr/bin/perl -w + +use strict; +use Socket qw(inet_pton PF_INET PF_INET6 SOCK_STREAM SOMAXCONN sockaddr_in sockaddr_in6); +use Errno; + +my @socka = (); +my ($pf, $host, $sin, $sock, $badsock); + + +if (@ARGV < 3 or @ARGV > 4) { + die "usage: $0 [count]\n" +} + +if ($> != 0) { + die "run this script as root\n" +} + +my ($af, $test_listen, $test_first, $test_count) = @ARGV; + +$test_count = SOMAXCONN if (not defined $test_count); + +my $test_last = $test_first + $test_count; + +if ($test_first <= 0 || 65536 <= $test_first || + $test_last <= 0 || 65536 <= $test_last || + $test_listen <= 0 || 65536 <= $test_listen) { + die "invalid port number\n"; +} + +if ($test_first > $test_last) { + die "first must be lower than last\n"; +} + +if ($test_listen >= $test_first && $test_listen <= $test_last) { + die "listen must be outside the [first..last] range\n"; +} + +if ($af == "4") { + $pf = PF_INET; + $sin = sockaddr_in($test_listen, inet_pton($pf,"127.0.0.1")); +} +elsif ($af == "6") { + $pf = PF_INET6; + $sin = sockaddr_in6($test_listen, inet_pton($pf,"::1")); +} +else { + die "af must be 4 or 6\n"; +} + + +my $orig_first = qx( sysctl -n net.inet.ip.portfirst ); +chomp $orig_first; +my $orig_last = qx( sysctl -n net.inet.ip.portlast ); +chomp $orig_last; + + +# first < last + +socket(SERVSOCK, $pf, SOCK_STREAM, getprotobyname("tcp")); +bind(SERVSOCK, $sin); +listen(SERVSOCK, SOMAXCONN); + +my $rc_f = 0; + +print "testing with portfirst < portlast\n"; + +system("sysctl net.inet.ip.portfirst=$test_first > /dev/null"); +system("sysctl net.inet.ip.portlast=$test_last > /dev/null"); + +for ($test_first .. $test_last) { + socket($sock, $pf, SOCK_STREAM, getprotobyname("tcp")); + unless (connect($sock, $sin)) { + print "failed to connect with errno $!\n"; + $rc_f = 1; + } + push @socka, $sock; +} + +socket($badsock, $pf, SOCK_STREAM, getprotobyname("tcp")); +if (connect($badsock, $sin)) { + print "connect() succeeded but should have failed\n"; + $rc_f = 1; +} +elsif (not $!{EADDRNOTAVAIL}) { + print "connect() failed with errno $!, should have been EADDRNOTAVAIL\n"; + $rc_f = 1; +} +close($badsock); + +while ($sock = pop @socka) { + close($sock); +} + +close(SERVSOCK); + +sleep 1; + +if ($rc_f == 0) { + print "test OK\n" +} +else { + print "test failed\n" +} + +# first > last + +socket(SERVSOCK, $pf, SOCK_STREAM, getprotobyname("tcp")); +bind(SERVSOCK, $sin); +listen(SERVSOCK, SOMAXCONN); + +my $rc_b = 0; + +print "testing with portfirst > portlast\n"; + +system("sysctl net.inet.ip.portfirst=$test_last > /dev/null"); +system("sysctl net.inet.ip.portlast=$test_first > /dev/null"); + +for ($test_first .. $test_last) { + socket($sock, $pf, SOCK_STREAM, getprotobyname("tcp")); + unless (connect($sock, $sin)) { + print "failed to connect with errno $!\n"; + $rc_b = 1; + } + push @socka, $sock; +} + +socket($badsock, $pf, SOCK_STREAM, getprotobyname("tcp")); +if (connect($badsock, $sin)) { + print "connect() succeeded but should have failed\n"; + $rc_b = 1; +} +elsif (not $!{EADDRNOTAVAIL}) { + print "connect() failed with errno $!, should have been EADDRNOTAVAIL\n"; + $rc_b = 1; +} +close($badsock); + +while ($sock = pop @socka) { + close($sock); +} + +close(SERVSOCK); + +sleep 1; + +if ($rc_b == 0) { + print "test OK\n" +} +else { + print "test failed\n" +} + +system("sysctl net.inet.ip.portfirst=$orig_first > /dev/null"); +system("sysctl net.inet.ip.portlast=$orig_last > /dev/null"); + +exit ($rc_f || $rc_b); -- 2.20.1