diff options
Diffstat (limited to 'regress')
-rw-r--r-- | regress/usr.sbin/relayd/Client.pm | 61 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/Makefile | 43 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/Proc.pm | 167 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/Relayd.pm | 108 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/Server.pm | 67 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/args-default.pl | 11 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/args-reverse.pl | 17 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/args-ssl-client.pl | 17 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/args-ssl-server.pl | 17 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/args-ssl.pl | 21 | ||||
-rwxr-xr-x | regress/usr.sbin/relayd/direct.pl | 75 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/funcs.pl | 126 | ||||
-rw-r--r-- | regress/usr.sbin/relayd/relayd.pl | 99 |
13 files changed, 829 insertions, 0 deletions
diff --git a/regress/usr.sbin/relayd/Client.pm b/regress/usr.sbin/relayd/Client.pm new file mode 100644 index 00000000000..3b70147babe --- /dev/null +++ b/regress/usr.sbin/relayd/Client.pm @@ -0,0 +1,61 @@ +# $OpenBSD: Client.pm,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package Client; +use parent 'Proc'; +use Carp; +use Socket qw(IPPROTO_TCP TCP_NODELAY); +use Socket6; +use IO::Socket; +use IO::Socket::INET6; +use IO::Socket::SSL; + +sub new { + my $class = shift; + my %args = @_; + $args{logfile} ||= "client.log"; + $args{up} ||= "Connected"; + $args{down} ||= "Shutdown|Broken pipe|Connection reset by peer"; + my $self = Proc::new($class, %args); + $self->{connectdomain} + or croak "$class connect domain not given"; + $self->{connectaddr} + or croak "$class connect addr not given"; + $self->{connectport} + or croak "$class connect port not given"; + return $self; +} + +sub child { + my $self = shift; + + my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; + my $cs = $iosocket->new( + Proto => "tcp", + Domain => $self->{connectdomain}, + PeerAddr => $self->{connectaddr}, + PeerPort => $self->{connectport}, + ) or die ref($self), " socket connect failed: $!"; + print STDERR "connect sock: ",$cs->sockhost()," ",$cs->sockport(),"\n"; + print STDERR "connect peer: ",$cs->peerhost()," ",$cs->peerport(),"\n"; + + *STDIN = *STDOUT = $self->{cs} = $cs; +} + +1; diff --git a/regress/usr.sbin/relayd/Makefile b/regress/usr.sbin/relayd/Makefile new file mode 100644 index 00000000000..a471c10eeb8 --- /dev/null +++ b/regress/usr.sbin/relayd/Makefile @@ -0,0 +1,43 @@ +# $OpenBSD: Makefile,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# The following ports must be installed for the regression tests: +# p5-IO-Socket-INET6 object interface for AF_INET and AF_INET6 domain sockets +# p5-Socket6 Perl defines relating to AF_INET6 sockets +# p5-IO-Socket-SSL perl interface to SSL sockets + +ARGS != cd ${.CURDIR} && ls args-*.pl +TARGETS ?= ${ARGS} +REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/} +CLEANFILES = *.log *.pem relayd.conf ktrace.out + +# Set variables so that make runs with and without obj directory. +# Only do that if necessary to keep visible output short. + +.if ${.CURDIR} == ${.OBJDIR} +PERLINC = +PERLPATH = +.else +PERLINC = -I${.CURDIR} +PERLPATH = ${.CURDIR}/ +.endif + +# The arg tests take a perl hash with arguments controlling the +# test parameters. Generally they consist of client, relayd, server. + +.for a in ${ARGS} +run-regress-$a: $a + time SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}relayd.pl copy ${PERLPATH}$a + time SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}relayd.pl splice ${PERLPATH}$a +.endfor + +/etc/ssl/127.0.0.1.crt: + ${SUDO} openssl req -batch -new -nodes -newkey rsa -keyout /etc/ssl/private/127.0.0.1.key -subj /CN=127.0.0.1/ -x509 -out $@ + +server-cert.pem: + openssl req -batch -new -nodes -newkey rsa -keyout server-key.pem -subj /CN=localhost/ -x509 -out $@ + +${REGRESS_TARGETS:M*ssl-client*}: /etc/ssl/127.0.0.1.crt + +${REGRESS_TARGETS:M*ssl-server*}: server-cert.pem + +.include <bsd.regress.mk> diff --git a/regress/usr.sbin/relayd/Proc.pm b/regress/usr.sbin/relayd/Proc.pm new file mode 100644 index 00000000000..b43f13978bc --- /dev/null +++ b/regress/usr.sbin/relayd/Proc.pm @@ -0,0 +1,167 @@ +# $OpenBSD: Proc.pm,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package Proc; +use Carp; +use List::Util qw(first); +use POSIX; +use Time::HiRes qw(time alarm sleep); + +my %CHILDREN; + +sub kill_children { + my @pids = keys %CHILDREN + or return; + if (my $sudo = $ENV{SUDO}) { + local $?; # do not modify during END block + my @cmd = ($sudo, '/bin/kill', '-TERM', @pids); + system(@cmd); + } else { + kill TERM => @pids; + } + %CHILDREN = (); +} + +BEGIN { + $SIG{TERM} = $SIG{INT} = sub { + my $sig = shift; + kill_children(); + $SIG{TERM} = $SIG{INT} = 'DEFAULT'; + POSIX::raise($sig); + }; +} + +END { + kill_children(); + $SIG{TERM} = $SIG{INT} = 'DEFAULT'; +} + +sub new { + my $class = shift; + my $self = { @_ }; + $self->{down} ||= "Shutdown"; + $self->{func} && ref($self->{func}) eq 'CODE' + or croak "$class func not given"; + $self->{logfile} + or croak "$class log file not given"; + open(my $fh, '>', $self->{logfile}) + or die "$class log file $self->{logfile} create failed: $!"; + $self->{log} = $fh; + return bless $self, $class; +} + +sub run { + my $self = shift; + + defined(my $pid = fork()) + or die ref($self), " fork child failed"; + if ($pid) { + $CHILDREN{$pid} = 1; + $self->{pid} = $pid; + return $self; + } + %CHILDREN = (); + $SIG{TERM} = $SIG{INT} = 'DEFAULT'; + $SIG{__DIE__} = sub { + die @_ if $^S; + warn @_; + IO::Handle::flush(\*STDERR); + POSIX::_exit(255); + }; + open(STDERR, '>&', $self->{log}) + or die ref($self), " dup STDERR failed: $!"; + + $self->child(); + print STDERR $self->{up}, "\n"; + $self->{func}->($self); + print STDERR "Shutdown", "\n"; + IO::Handle::flush(\*STDOUT); + IO::Handle::flush(\*STDERR); + + POSIX::_exit(0); +} + +sub wait { + my $self = shift; + my $flags = shift; + + my $pid = $self->{pid} + or croak ref($self), " no child pid"; + my $kid = waitpid($pid, $flags); + if ($kid > 0) { + my $status = $?; + my $code; + $code = "exit: ". WEXITSTATUS($?) if WIFEXITED($?); + $code = "signal: ". WTERMSIG($?) if WIFSIGNALED($?); + $code = "stop: ". WSTOPSIG($?) if WIFSTOPPED($?); + delete $CHILDREN{$pid} if WIFEXITED($?) || WIFSIGNALED($?); + return wantarray ? ($kid, $status, $code) : $kid; + } + return $kid; +} + +sub loggrep { + my $self = shift; + my($regex, $timeout) = @_; + + my $end = time() + $timeout if $timeout; + + do { + my($kid, $status, $code) = $self->wait(WNOHANG); + if ($kid > 0 && $status != 0) { + # child terminated with failure + die ref($self), " child status: $status $code"; + } + open(my $fh, '<', $self->{logfile}) + or die ref($self), " log file open failed: $!"; + my $match = first { /$regex/ } <$fh>; + return $match if $match; + close($fh); + # pattern not found + if ($kid == 0) { + # child still running, wait for log data + sleep .1; + } else { + # child terminated, no new log data possible + return; + } + } while ($timeout and time() < $end); + + return; +} + +sub up { + my $self = shift; + my $timeout = shift || 10; + $self->loggrep(qr/$self->{up}/, $timeout) + or croak ref($self), " no $self->{up} in $self->{logfile} ". + "after $timeout seconds"; + return $self; +} + +sub down { + my $self = shift; + my $timeout = shift || 30; + $self->loggrep(qr/$self->{down}/, $timeout) + or croak ref($self), " no $self->{down} in $self->{logfile} ". + "after $timeout seconds"; + return $self; +} + +1; diff --git a/regress/usr.sbin/relayd/Relayd.pm b/regress/usr.sbin/relayd/Relayd.pm new file mode 100644 index 00000000000..9cd55d868be --- /dev/null +++ b/regress/usr.sbin/relayd/Relayd.pm @@ -0,0 +1,108 @@ +# $OpenBSD: Relayd.pm,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package Relayd; +use parent 'Proc'; +use Carp; +use File::Basename; + +sub new { + my $class = shift; + my %args = @_; + $args{logfile} ||= "relayd.log"; + $args{up} ||= "Started"; + $args{down} ||= "parent terminating"; + $args{func} = sub { Carp::confess "$class func may not be called" }; + $args{conffile} ||= "relayd.conf"; + $args{forward} + or croak "$class forward not given"; + my $self = Proc::new($class, %args); + ref($self->{protocol}) eq 'ARRAY' + or $self->{protocol} = [ split("\n", $self->{protocol} || "") ]; + ref($self->{relay}) eq 'ARRAY' + or $self->{relay} = [ split("\n", $self->{relay} || "") ]; + $self->{listenaddr} + or croak "$class listen addr not given"; + $self->{listenport} + or croak "$class listen port not given"; + $self->{connectaddr} + or croak "$class connect addr not given"; + $self->{connectport} + or croak "$class connect port not given"; + + open(my $fh, '>', $self->{conffile}) + or die ref($self), " conf file $self->{conffile} create failed: $!"; + my $test = basename($self->{test} || ""); + + my @protocol = @{$self->{protocol}}; + my $proto = shift @protocol; + $proto = defined($proto) ? "$proto " : ""; + unshift @protocol, + $self->{forward} eq "splice" ? "tcp splice" : + $self->{forward} eq "copy" ? "tcp no splice" : + die ref($self), " invalid forward $self->{forward}" + unless grep { /splice/ } @protocol; + print $fh "${proto}protocol proto-$test {"; + print $fh map { "\n\t$_" } @protocol; + print $fh "\n}\n"; + + my @relay = @{$self->{relay}}; + print $fh "relay relay-$test {"; + print $fh "\n\tprotocol proto-$test" + unless grep { /^protocol / } @relay; + my $ssl = $self->{listenssl} ? " ssl" : ""; + print $fh "\n\tlisten on $self->{listenaddr} ". + "port $self->{listenport}$ssl" unless grep { /^listen / } @relay; + my $withssl = $self->{forwardssl} ? " with ssl" : ""; + print $fh "\n\tforward$withssl to $self->{connectaddr} ". + "port $self->{connectport}" unless grep { /^forward / } @relay; + print $fh map { "\n\t$_" } @relay; + print $fh "\n}\n"; + + return $self; +} + +sub up { + my $self = Proc::up(shift, @_); + my $timeout = shift || 10; + my $lsock = $self->loggrep(qr/relay_launch: /, $timeout) + or croak ref($self), " no relay_launch in $self->{logfile} ". + "after $timeout seconds"; + return $self; +} + +sub down { + my $self = shift; + my @sudo = $ENV{SUDO} || (); + my @cmd = (@sudo, '/bin/kill', $self->{pid}); + system(@cmd); + return Proc::down($self, @_); +} + +sub child { + my $self = shift; + print STDERR $self->{up}, "\n"; + my @sudo = $ENV{SUDO} || (); + my $relayd = $ENV{RELAYD} || "relayd"; + my @cmd = (@sudo, $relayd, '-dvv', '-f', $self->{conffile}); + exec @cmd; + die "Exec @cmd failed: $!"; +} + +1; diff --git a/regress/usr.sbin/relayd/Server.pm b/regress/usr.sbin/relayd/Server.pm new file mode 100644 index 00000000000..2db2a276e1c --- /dev/null +++ b/regress/usr.sbin/relayd/Server.pm @@ -0,0 +1,67 @@ +# $OpenBSD: Server.pm,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package Server; +use parent 'Proc'; +use Carp; +use Socket qw(IPPROTO_TCP TCP_NODELAY); +use Socket6; +use IO::Socket; +use IO::Socket::INET6; +use IO::Socket::SSL; + +sub new { + my $class = shift; + my %args = @_; + $args{logfile} ||= "server.log"; + $args{up} ||= "Accepted"; + my $self = Proc::new($class, %args); + $self->{listendomain} + or croak "$class listen domain not given"; + my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; + my $ls = $iosocket->new( + Proto => "tcp", + ReuseAddr => 1, + Domain => $self->{listendomain}, + Listen => 1, + $self->{listenaddr} ? (LocalAddr => $self->{listenaddr}) : (), + $self->{listenport} ? (LocalPort => $self->{listenport}) : (), + SSL_key_file => "server-key.pem", + SSL_cert_file => "server-cert.pem", + ) or die ref($self), " socket failed: $!"; + my $log = $self->{log}; + print $log "listen sock: ",$ls->sockhost()," ",$ls->sockport(),"\n"; + $self->{listenaddr} = $ls->sockhost() unless $self->{listenaddr}; + $self->{listenport} = $ls->sockport() unless $self->{listenport}; + $self->{ls} = $ls; + return $self; +} + +sub child { + my $self = shift; + + my $as = $self->{ls}->accept() + or die ref($self), " socket accept failed: $!"; + print STDERR "accept sock: ",$as->sockhost()," ",$as->sockport(),"\n"; + print STDERR "accept peer: ",$as->peerhost()," ",$as->peerport(),"\n"; + + *STDIN = *STDOUT = $self->{as} = $as; +} + +1; diff --git a/regress/usr.sbin/relayd/args-default.pl b/regress/usr.sbin/relayd/args-default.pl new file mode 100644 index 00000000000..28e53a92126 --- /dev/null +++ b/regress/usr.sbin/relayd/args-default.pl @@ -0,0 +1,11 @@ +# test default values + +use strict; +use warnings; + +our %args = ( + len => 251, + md5 => "bc3a3f39af35fe5b1687903da2b00c7f", +); + +1; diff --git a/regress/usr.sbin/relayd/args-reverse.pl b/regress/usr.sbin/relayd/args-reverse.pl new file mode 100644 index 00000000000..d9005e6f00f --- /dev/null +++ b/regress/usr.sbin/relayd/args-reverse.pl @@ -0,0 +1,17 @@ +# test reverse sending from server to client + +use strict; +use warnings; + +our %args = ( + client => { + func => \&read_char, + }, + server => { + func => \&write_char, + }, + len => 251, + md5 => "bc3a3f39af35fe5b1687903da2b00c7f", +); + +1; diff --git a/regress/usr.sbin/relayd/args-ssl-client.pl b/regress/usr.sbin/relayd/args-ssl-client.pl new file mode 100644 index 00000000000..2c657a5f1bd --- /dev/null +++ b/regress/usr.sbin/relayd/args-ssl-client.pl @@ -0,0 +1,17 @@ +# test client ssl connection + +use strict; +use warnings; + +our %args = ( + client => { + ssl => 1, + }, + relay => { + listenssl => 1, + }, + len => 251, + md5 => "bc3a3f39af35fe5b1687903da2b00c7f", +); + +1; diff --git a/regress/usr.sbin/relayd/args-ssl-server.pl b/regress/usr.sbin/relayd/args-ssl-server.pl new file mode 100644 index 00000000000..629e46582cb --- /dev/null +++ b/regress/usr.sbin/relayd/args-ssl-server.pl @@ -0,0 +1,17 @@ +# test server ssl connection + +use strict; +use warnings; + +our %args = ( + relay => { + forwardssl => 1, + }, + server => { + ssl => 1, + }, + len => 251, + md5 => "bc3a3f39af35fe5b1687903da2b00c7f", +); + +1; diff --git a/regress/usr.sbin/relayd/args-ssl.pl b/regress/usr.sbin/relayd/args-ssl.pl new file mode 100644 index 00000000000..80653efb12d --- /dev/null +++ b/regress/usr.sbin/relayd/args-ssl.pl @@ -0,0 +1,21 @@ +# test both client and server ssl connection + +use strict; +use warnings; + +our %args = ( + client => { + ssl => 1, + }, + relay => { + forwardssl => 1, + listenssl => 1, + }, + server => { + ssl => 1, + }, + len => 251, + md5 => "bc3a3f39af35fe5b1687903da2b00c7f", +); + +1; diff --git a/regress/usr.sbin/relayd/direct.pl b/regress/usr.sbin/relayd/direct.pl new file mode 100755 index 00000000000..417a38a606b --- /dev/null +++ b/regress/usr.sbin/relayd/direct.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +# $OpenBSD: direct.pl,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; +use Socket; +use Socket6; + +use Client; +use Server; +require 'funcs.pl'; + +our %args; +if (my $test = pop) { + do $test + or die "Do test file $test failed: ", $@ || $!; +} + +@ARGV == 0 or die "usage: direct.pl [test-args.pl]\n"; + +my $s = Server->new( + func => \&read_char, + %{$args{server}}, + listendomain => AF_INET, + listenaddr => "127.0.0.1", +); +my $c = Client->new( + func => \&write_char, + %{$args{client}}, + connectdomain => AF_INET, + connectaddr => "127.0.0.1", + connectport => $s->{listenport}, +); + +$s->run; +$c->run->up; +$s->up; + +$c->down; +$s->down; + +exit if $args{nocheck} || $args{client}{nocheck}; + +my $clen = $c->loggrep(qr/^LEN: /) unless $args{client}{nocheck}; +my $slen = $s->loggrep(qr/^LEN: /) unless $args{server}{nocheck}; +!$clen || !$slen || $clen eq $slen + or die "client: $clen", "server: $slen", "len mismatch"; +!defined($args{len}) || !$clen || $clen eq "LEN: $args{len}\n" + or die "client: $clen", "len $args{len} expected"; +!defined($args{len}) || !$slen || $slen eq "LEN: $args{len}\n" + or die "server: $slen", "len $args{len} expected"; + +my $cmd5 = $c->loggrep(qr/^MD5: /) unless $args{client}{nocheck}; +my $smd5 = $s->loggrep(qr/^MD5: /) unless $args{server}{nocheck}; +!$cmd5 || !$smd5 || ref($args{md5}) eq 'ARRAY' || $cmd5 eq $smd5 + or die "client: $cmd5", "server: $smd5", "md5 mismatch"; +my $md5 = ref($args{md5}) eq 'ARRAY' ? join('|', @{$args{md5}}) : $args{md5}; +!$md5 || !$cmd5 || $cmd5 =~ /^MD5: ($md5)$/ + or die "client: $cmd5", "md5 $md5 expected"; +!$md5 || !$smd5 || $smd5 =~ /^MD5: ($md5)$/ + or die "server: $smd5", "md5 $md5 expected"; diff --git a/regress/usr.sbin/relayd/funcs.pl b/regress/usr.sbin/relayd/funcs.pl new file mode 100644 index 00000000000..c628e791194 --- /dev/null +++ b/regress/usr.sbin/relayd/funcs.pl @@ -0,0 +1,126 @@ +# $OpenBSD: funcs.pl,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; +use feature 'switch'; +use Errno; +use Digest::MD5; +use Socket; +use Socket6; +use IO::Socket; +use IO::Socket::INET6; + +sub find_ports { + my %args = @_; + my $num = delete $args{num} // 1; + my $domain = delete $args{domain} // AF_INET; + my $addr = delete $args{addr} // "127.0.0.1"; + + my @sockets = (1..$num); + foreach my $s (@sockets) { + $s = IO::Socket::INET6->new( + Proto => "tcp", + Domain => $domain, + $addr ? (LocalAddr => $addr) : (), + ) or die "find_ports: create and bind socket failed: $!"; + } + my @ports = map { $_->sockport() } @sockets; + + return @ports; +} + +######################################################################## +# Client funcs +######################################################################## + +sub write_char { + my $self = shift; + my $len = shift // $self->{len} // 251; + my $sleep = $self->{sleep}; + + my $ctx = Digest::MD5->new(); + my $char = '0'; + for (my $i = 1; $i < $len; $i++) { + $ctx->add($char); + print $char + or die ref($self), " print failed: $!"; + given ($char) { + when(/9/) { $char = 'A' } + when(/Z/) { $char = 'a' } + when(/z/) { $char = "\n" } + when(/\n/) { print STDERR "."; $char = '0' } + default { $char++ } + } + if ($self->{sleep}) { + IO::Handle::flush(\*STDOUT); + sleep $self->{sleep}; + } + } + if ($len) { + $char = "\n"; + $ctx->add($char); + print $char + or die ref($self), " print failed: $!"; + print STDERR ".\n"; + } + IO::Handle::flush(\*STDOUT); + + print STDERR "LEN: ", $len, "\n"; + print STDERR "MD5: ", $ctx->hexdigest, "\n"; +} + +sub errignore { + $SIG{PIPE} = 'IGNORE'; + $SIG{__DIE__} = sub { + die @_ if $^S; + warn @_; + my $soerror; + $soerror = getsockopt(STDIN, SOL_SOCKET, SO_ERROR); + print STDERR "ERROR IN: ", unpack('i', $soerror), "\n"; + $soerror = getsockopt(STDOUT, SOL_SOCKET, SO_ERROR); + print STDERR "ERROR OUT: ", unpack('i', $soerror), "\n"; + IO::Handle::flush(\*STDERR); + POSIX::_exit(0); + }; +} + +######################################################################## +# Server funcs +######################################################################## + +sub read_char { + my $self = shift; + my $max = $self->{max}; + + my $ctx = Digest::MD5->new(); + my $len = 0; + while (<STDIN>) { + $len += length($_); + $ctx->add($_); + print STDERR "."; + if ($max && $len >= $max) { + print STDERR "\nMax"; + last; + } + } + print STDERR "\n"; + + print STDERR "LEN: ", $len, "\n"; + print STDERR "MD5: ", $ctx->hexdigest, "\n"; +} + +1; diff --git a/regress/usr.sbin/relayd/relayd.pl b/regress/usr.sbin/relayd/relayd.pl new file mode 100644 index 00000000000..9ebbc5298a1 --- /dev/null +++ b/regress/usr.sbin/relayd/relayd.pl @@ -0,0 +1,99 @@ +#!/usr/bin/perl +# $OpenBSD: relayd.pl,v 1.1 2011/09/01 17:33:17 bluhm Exp $ + +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; +use Socket; +use Socket6; + +use Client; +use Relayd; +use Server; +require 'funcs.pl'; + +sub usage { + die "usage: relay.pl copy|splice [test-args.pl]\n"; +} + +my $test; +our %args; +if (@ARGV and -f $ARGV[-1]) { + $test = pop; + do $test + or die "Do test file $test failed: ", $@ || $!; +} +@ARGV == 1 or usage(); + +my($sport, $rport) = find_ports(num => 2); +my $s = Server->new( + func => \&read_char, + listendomain => AF_INET, + listenaddr => "127.0.0.1", + listenport => $sport, + %{$args{server}}, +); +my $r = Relayd->new( + forward => $ARGV[0], + listendomain => AF_INET, + listenaddr => "127.0.0.1", + listenport => $rport, + connectdomain => AF_INET, + connectaddr => "127.0.0.1", + connectport => $sport, + %{$args{relay}}, + test => $test, +); +my $c = Client->new( + func => \&write_char, + connectdomain => AF_INET, + connectaddr => "127.0.0.1", + connectport => $rport, + %{$args{client}}, +); + +$s->run; +$r->run; +$r->up; +$c->run->up; +$s->up; + +$c->down; +$s->down; +$r->down; + +exit if $args{nocheck}; + +my $clen = $c->loggrep(qr/^LEN: /) // die "no client len" + unless $args{client}{nocheck}; +my $slen = $s->loggrep(qr/^LEN: /) // die "no server len" + unless $args{server}{nocheck}; +!$clen || !$slen || $clen eq $slen + or die "client: $clen", "server: $slen", "len mismatch"; +!defined($args{len}) || !$clen || $clen eq "LEN: $args{len}\n" + or die "client: $clen", "len $args{len} expected"; +!defined($args{len}) || !$slen || $slen eq "LEN: $args{len}\n" + or die "server: $slen", "len $args{len} expected"; + +my $cmd5 = $c->loggrep(qr/^MD5: /) unless $args{client}{nocheck}; +my $smd5 = $s->loggrep(qr/^MD5: /) unless $args{server}{nocheck}; +!$cmd5 || !$smd5 || ref($args{md5}) eq 'ARRAY' || $cmd5 eq $smd5 + or die "client: $cmd5", "server: $smd5", "md5 mismatch"; +my $md5 = ref($args{md5}) eq 'ARRAY' ? join('|', @{$args{md5}}) : $args{md5}; +!$md5 || !$cmd5 || $cmd5 =~ /^MD5: ($md5)$/ + or die "client: $cmd5", "md5 $md5 expected"; +!$md5 || !$smd5 || $smd5 =~ /^MD5: ($md5)$/ + or die "server: $smd5", "md5 $md5 expected"; |