summaryrefslogtreecommitdiff
path: root/regress/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2021-01-09 15:39:38 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2021-01-09 15:39:38 +0000
commitb0e648e721006f8c068bdc99132f12395d2ba062 (patch)
tree27ec4a575e3705776b10e33aa38d721b3f458302 /regress/sys
parent77ef35081ba0e02d76f77b9fbeed7f6b533187e6 (diff)
Test that local UDP broadcast packets to 255.255.255.255 are handled
correctly by socket splicing. They generate an ELOOP error.
Diffstat (limited to 'regress/sys')
-rw-r--r--regress/sys/kern/sosplice/loop/Makefile10
-rw-r--r--regress/sys/kern/sosplice/loop/bcast.pl104
2 files changed, 110 insertions, 4 deletions
diff --git a/regress/sys/kern/sosplice/loop/Makefile b/regress/sys/kern/sosplice/loop/Makefile
index 80425ca36f1..d3811b627f2 100644
--- a/regress/sys/kern/sosplice/loop/Makefile
+++ b/regress/sys/kern/sosplice/loop/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.2 2021/01/03 12:33:00 bluhm Exp $
+# $OpenBSD: Makefile,v 1.3 2021/01/09 15:39:37 bluhm Exp $
# Create chains and loops of spliced tcp and udp sockets.
# Send data through them and check that MAXLOOP is triggered in kernel.
@@ -13,19 +13,21 @@ v = -v
.for i in 4 6
.for p in tcp udp
-
.for c in 1 2 3 127 128 129 200
REGRESS_TARGETS += run-chain-ipv$i-proto$p-count$c
run-chain-ipv$i-proto$p-count$c: chain.pl
- ulimit -n 511; \
+ ulimit -n 500; \
SUDO=${SUDO} ${KTRACE} perl ${PERLPATH}chain.pl -$i -c $c -p $p $v
.endfor
REGRESS_TARGETS += run-loop-ipv$i-proto$p
run-loop-ipv$i-proto$p: loop.pl
SUDO=${SUDO} ${KTRACE} perl ${PERLPATH}loop.pl -$i -p $p $v
-
.endfor
.endfor
+REGRESS_TARGETS += run-bcast
+run-bcast: bcast.pl
+ SUDO=${SUDO} ${KTRACE} perl ${PERLPATH}bcast.pl $v
+
.include <bsd.regress.mk>
diff --git a/regress/sys/kern/sosplice/loop/bcast.pl b/regress/sys/kern/sosplice/loop/bcast.pl
new file mode 100644
index 00000000000..97511bb638d
--- /dev/null
+++ b/regress/sys/kern/sosplice/loop/bcast.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+# $OpenBSD: bcast.pl,v 1.1 2021/01/09 15:39:37 bluhm Exp $
+
+# Copyright (c) 2021 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 BSD::Socket::Splice qw(setsplice geterror);
+use Errno;
+use Getopt::Std;
+use IO::Socket::IP;
+use Socket qw(getnameinfo AI_PASSIVE NI_NUMERICHOST NI_NUMERICSERV);
+
+# from /usr/include/sys/mbuf.h
+use constant M_MAXLOOP => 128;
+
+my %opts;
+getopts('b:v', \%opts) or do {
+ print STDERR <<"EOF";
+usage: $0 [-v] [-b bcast]
+ -b bcast broadcast address, default 255.255.255.255
+ -v verbose
+EOF
+ exit(2);
+};
+
+my $broadcast = $opts{b} || "255.255.255.255";
+my $verbose = $opts{v};
+
+my $timeout = 10;
+$SIG{ALRM} = sub { die "Timeout triggered after $timeout seconds" };
+alarm($timeout);
+
+my $ls = IO::Socket::IP->new(
+ Broadcast => $opts{b} ? 1 : undef,
+ GetAddrInfoFlags => AI_PASSIVE,
+ LocalHost => $broadcast,
+ Proto => "udp",
+ Type => SOCK_DGRAM,
+) or die "Listen socket failed: $@";
+my ($host, $service) = $ls->sockhost_service(1);
+print "listen on host '$host' service '$service'\n" if $verbose;
+
+my $cs = IO::Socket::IP->new(
+ PeerHost => $host,
+ PeerService => $service,
+ Proto => "udp",
+ Type => SOCK_DGRAM,
+) or die "Connect socket failed: $@";
+print "connect to host '$host' service '$service'\n" if $verbose;
+
+my $as = $ls;
+my $peer = $cs->sockname();
+$as->connect($peer)
+ or die "Connect passive socket failed: $!";
+if ($verbose) {
+ my ($err, $peerhost, $peerservice) = getnameinfo($peer,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ $err and die "Getnameinfo failed: $err";
+ print "accept from host '$peerhost' service '$peerservice'\n";
+}
+
+setsplice($as, $cs)
+ or die "Splice accept to connect socket failed: $!";
+setsplice($cs, $as)
+ or die "Splice connect to accept socket failed: $!";
+
+system("\${SUDO} fstat -n -p $$") if $verbose;
+my ($msg, $buf) = "foo";
+$cs->send($msg, 0)
+ or die "Send to connect socket failed: $!";
+defined $as->recv($buf, 100, 0)
+ or die "Recv from accept socket failed: $!";
+$msg eq $buf
+ or die "Value modified in splice chain";
+$! = geterror($as)
+ or die "No error at accept socket";
+$!{ELOOP}
+ or die "Errno at accept socket is not ELOOP: $!";
+
+# addresses are asymmetric, try it the other way around
+$msg = "bar";
+$as->send($msg, 0)
+ or die "Send to accept socket failed: $!";
+defined $cs->recv($buf, 100, 0)
+ or die "Recv from connect socket failed: $!";
+$msg eq $buf
+ or die "Value modified in splice chain";
+$! = geterror($cs)
+ or die "No error at connect socket";
+$!{ELOOP}
+ or die "Errno at connect socket is not ELOOP: $!";