summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-11-07 22:06:18 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-11-07 22:06:18 +0000
commit3dc4a242a13bc6a1b41ae3cde031d13716cb045e (patch)
tree3bbbfcb277f43d3b35ff555e9cb20884a16b7f26
parentfda0f93db2eb45780e55b241dd9c93b086955434 (diff)
Test more variations of TCP packets in the scapy splicing tests.
Delay connect and SYN+ACK to splice data into a connecting socket.
-rw-r--r--regress/sys/kern/sosplice/LICENSE2
-rw-r--r--regress/sys/kern/sosplice/Relay.pm14
-rw-r--r--regress/sys/kern/sosplice/scapy/scapy-oobinline-delay-connect.py106
-rw-r--r--regress/sys/kern/sosplice/scapy/scapy-payload-delay-connect.py106
-rw-r--r--regress/sys/kern/sosplice/scapy/scapy.pl4
5 files changed, 228 insertions, 4 deletions
diff --git a/regress/sys/kern/sosplice/LICENSE b/regress/sys/kern/sosplice/LICENSE
index a6e1dd38fcf..52b251631b7 100644
--- a/regress/sys/kern/sosplice/LICENSE
+++ b/regress/sys/kern/sosplice/LICENSE
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
+# Copyright (c) 2010-2017 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
diff --git a/regress/sys/kern/sosplice/Relay.pm b/regress/sys/kern/sosplice/Relay.pm
index a4f79733c7c..41c8575ed45 100644
--- a/regress/sys/kern/sosplice/Relay.pm
+++ b/regress/sys/kern/sosplice/Relay.pm
@@ -1,6 +1,6 @@
-# $OpenBSD: Relay.pm,v 1.1 2013/01/03 17:36:37 bluhm Exp $
+# $OpenBSD: Relay.pm,v 1.2 2017/11/07 22:06:17 bluhm Exp $
-# Copyright (c) 2010 Alexander Bluhm <bluhm@openbsd.org>
+# Copyright (c) 2010-2017 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
@@ -96,6 +96,16 @@ sub child {
or die ref($self), " dup STDIN failed: $!";
print STDERR "Accepted\n";
+ if ($self->{clientreadable}) {
+ my $idle = 15; # timeout
+ my $rin = '';
+ vec($rin, fileno($as), 1) = 1;
+ defined(my $n = select($rin, undef, undef, $idle))
+ or die ref($self), " select failed: $!";
+ $idle && $n == 0
+ and die ref($self), " select timeout";
+ }
+
my $cs = IO::Socket::INET6->new(
Proto => $self->{protocol},
Domain => $self->{connectdomain},
diff --git a/regress/sys/kern/sosplice/scapy/scapy-oobinline-delay-connect.py b/regress/sys/kern/sosplice/scapy/scapy-oobinline-delay-connect.py
new file mode 100644
index 00000000000..10dafa78c65
--- /dev/null
+++ b/regress/sys/kern/sosplice/scapy/scapy-oobinline-delay-connect.py
@@ -0,0 +1,106 @@
+#!/usr/local/bin/python2.7
+# send urgent data from client to relay before connecting to server
+
+import os
+import sys
+import threading
+from addr import *
+from scapy.all import *
+
+client=os.getpid() & 0xffff
+relay=int(sys.argv[2])
+server=int(sys.argv[1])
+
+class Sniff1(threading.Thread):
+ filter = None
+ captured = None
+ packet = None
+ def run(self):
+ self.captured = sniff(iface=LOCAL_IF, filter=self.filter,
+ count=1, timeout=5)
+ if self.captured:
+ self.packet = self.captured[0]
+
+ip=IP(src=FAKE_NET_ADDR, dst=REMOTE_ADDR)
+
+print "Send SYN packet, receive SYN+ACK"
+syn=TCP(sport=client, dport=relay, seq=0, flags='S', window=(2**16)-1)
+synack=sr1(ip/syn, iface=LOCAL_IF, timeout=5)
+
+if synack is None:
+ print "ERROR: No matching SYN+ACK packet received"
+ exit(1)
+
+print "Send ACK packet to finish handshake"
+ack=TCP(sport=synack.dport, dport=synack.sport,
+ seq=1, ack=synack.seq+1, flags='A')
+send(ip/ack, iface=LOCAL_IF)
+
+print "Expect spliced SYN"
+sniffer = Sniff1();
+sniffer.filter = "src %s and dst %s and tcp port %u " \
+ "and tcp[tcpflags] = tcp-syn" % (ip.dst, ip.src, server)
+sniffer.start()
+time.sleep(1)
+
+print "Send 20 bytes payload and one urgent byte"
+data="0123456789Xabcdefghij"
+payload=TCP(sport=synack.dport, dport=synack.sport, urgptr=11,
+ seq=1, ack=synack.seq+1, flags='APU')/data
+payload_ack=sr1(ip/payload, iface=LOCAL_IF)
+
+if payload_ack is None:
+ print "ERROR: No payload ACK packet received"
+ exit(1)
+if payload_ack.ack != len(data)+1:
+ print "ERROR: Expected ack %d, got %d in payload ACK" % \
+ (len(data)+1, payload_ack.ack)
+ exit(1)
+
+sniffer.join(timeout=7)
+spliced_syn = sniffer.packet
+
+if spliced_syn is None:
+ print "ERROR: No spliced SYN packet received"
+ exit(1)
+
+print "Expect spliced urgent payload"
+sniffer = Sniff1();
+sniffer.filter = "src %s and dst %s and tcp port %u " \
+ "and tcp[tcpflags] = tcp-ack|tcp-urg" % (ip.dst, ip.src, server)
+sniffer.start()
+time.sleep(1)
+
+print "Send spliced SYN+ACK packet to finish handshake"
+spliced_synack=TCP(sport=spliced_syn.dport, dport=spliced_syn.sport,
+ seq=0, ack=spliced_syn.seq+1, flags='SA')
+spliced_ack=sr1(ip/spliced_synack, iface=LOCAL_IF)
+
+if spliced_ack is None:
+ print "ERROR: No spliced ACK packet received"
+ exit(1)
+
+sniffer.join(timeout=7)
+spliced_payload = sniffer.packet
+
+if spliced_payload is None:
+ print "ERROR: No spliced urgent payload packet received"
+ exit(1)
+if spliced_payload.seq != spliced_ack.seq:
+ print "ERROR: Expected seq %d, got %d in spliced payload" % \
+ (spliced_ack.seq, spliced_payload.seq)
+ exit(1)
+if spliced_payload.urgptr != 11:
+ print "ERROR: Expected urgptr %d, got %d in spliced payload" % \
+ (11, spliced_payload.urgptr)
+ exit(1)
+
+print "Kill connections with RST"
+spliced_rst=TCP(sport=spliced_ack.dport, dport=spliced_ack.sport,
+ seq=1, ack=spliced_ack.seq, flags='RA')
+send(ip/spliced_rst, iface=LOCAL_IF)
+rst=TCP(sport=synack.dport, dport=synack.sport,
+ seq=payload_ack.ack, ack=synack.seq+1, flags='RA')
+send(ip/rst, iface=LOCAL_IF)
+
+exit(0)
diff --git a/regress/sys/kern/sosplice/scapy/scapy-payload-delay-connect.py b/regress/sys/kern/sosplice/scapy/scapy-payload-delay-connect.py
new file mode 100644
index 00000000000..28d2423ef44
--- /dev/null
+++ b/regress/sys/kern/sosplice/scapy/scapy-payload-delay-connect.py
@@ -0,0 +1,106 @@
+#!/usr/local/bin/python2.7
+# send payload from client to relay before connecting to server
+
+import os
+import sys
+import threading
+from addr import *
+from scapy.all import *
+
+client=os.getpid() & 0xffff
+relay=int(sys.argv[2])
+server=int(sys.argv[1])
+
+class Sniff1(threading.Thread):
+ filter = None
+ captured = None
+ packet = None
+ def run(self):
+ self.captured = sniff(iface=LOCAL_IF, filter=self.filter,
+ count=1, timeout=5)
+ if self.captured:
+ self.packet = self.captured[0]
+
+ip=IP(src=FAKE_NET_ADDR, dst=REMOTE_ADDR)
+
+print "Send SYN packet, receive SYN+ACK"
+syn=TCP(sport=client, dport=relay, seq=0, flags='S', window=(2**16)-1)
+synack=sr1(ip/syn, iface=LOCAL_IF, timeout=5)
+
+if synack is None:
+ print "ERROR: No matching SYN+ACK packet received"
+ exit(1)
+
+print "Send ACK packet to finish handshake"
+ack=TCP(sport=synack.dport, dport=synack.sport,
+ seq=1, ack=synack.seq+1, flags='A')
+send(ip/ack, iface=LOCAL_IF)
+
+print "Expect spliced SYN"
+sniffer = Sniff1();
+sniffer.filter = "src %s and dst %s and tcp port %u " \
+ "and tcp[tcpflags] = tcp-syn" % (ip.dst, ip.src, server)
+sniffer.start()
+time.sleep(1)
+
+print "Send 10 bytes payload"
+data="0123456789"
+payload=TCP(sport=synack.dport, dport=synack.sport,
+ seq=1, ack=synack.seq+1, flags='APU')/data
+payload_ack=sr1(ip/payload, iface=LOCAL_IF)
+
+if payload_ack is None:
+ print "ERROR: No payload ACK packet received"
+ exit(1)
+if payload_ack.ack != len(data)+1:
+ print "ERROR: Expected ack %d, got %d in payload ACK" % \
+ (len(data)+1, payload_ack.ack)
+ exit(1)
+
+sniffer.join(timeout=7)
+spliced_syn = sniffer.packet
+
+if spliced_syn is None:
+ print "ERROR: No spliced SYN packet received"
+ exit(1)
+
+print "Expect spliced payload"
+sniffer = Sniff1();
+sniffer.filter = "src %s and dst %s and tcp port %u " \
+ "and tcp[tcpflags] = tcp-ack|tcp-push" % (ip.dst, ip.src, server)
+sniffer.start()
+time.sleep(1)
+
+print "Send spliced SYN+ACK packet to finish handshake"
+spliced_synack=TCP(sport=spliced_syn.dport, dport=spliced_syn.sport,
+ seq=0, ack=spliced_syn.seq+1, flags='SA')
+spliced_ack=sr1(ip/spliced_synack, iface=LOCAL_IF)
+
+if spliced_ack is None:
+ print "ERROR: No spliced ACK packet received"
+ exit(1)
+
+sniffer.join(timeout=7)
+spliced_payload = sniffer.packet
+
+if spliced_payload is None:
+ print "ERROR: No spliced payload packet received"
+ exit(1)
+if spliced_payload.seq != spliced_ack.seq:
+ print "ERROR: Expected seq %d, got %d in spliced payload" % \
+ (spliced_ack.seq, spliced_payload.seq)
+ exit(1)
+if spliced_payload.len-20-20 != len(data):
+ print "ERROR: Expected len %d, got %d in spliced payload" % \
+ (len(data), spliced_payload.len-20-20)
+ exit(1)
+
+print "Kill connections with RST"
+spliced_rst=TCP(sport=spliced_ack.dport, dport=spliced_ack.sport,
+ seq=1, ack=spliced_ack.seq, flags='RA')
+send(ip/spliced_rst, iface=LOCAL_IF)
+rst=TCP(sport=synack.dport, dport=synack.sport,
+ seq=payload_ack.ack, ack=synack.seq+1, flags='RA')
+send(ip/rst, iface=LOCAL_IF)
+
+exit(0)
diff --git a/regress/sys/kern/sosplice/scapy/scapy.pl b/regress/sys/kern/sosplice/scapy/scapy.pl
index facb4da5b51..3af41f960c5 100644
--- a/regress/sys/kern/sosplice/scapy/scapy.pl
+++ b/regress/sys/kern/sosplice/scapy/scapy.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $OpenBSD: scapy.pl,v 1.1 2017/10/27 16:59:14 bluhm Exp $
+# $OpenBSD: scapy.pl,v 1.2 2017/11/07 22:06:17 bluhm Exp $
# Copyright (c) 2010-2017 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -71,6 +71,8 @@ if ($mode eq "relay") {
rcvbuf => 2**12,
sndbuf => 2**12,
down => "Broken pipe|Connection reset by peer",
+ clientreadable => $testfile =~ /delay-connect/ ? 1 : 0,
+ nonblocking => 1,
);
open(my $log, '<', $r->{logfile})
or die "Remote log file open failed: $!";