Skip to content

Commit c18012f

Browse files
committed
hack/test-port-forwarding.pl: support socat as listener and writer
support `socat` as a listener and writer. ```console $ ./hack/test-port-forwarding.pl default [nc|socat] [nc|socat] ``` The `nc` command always sets `SO_REUSEPORT` on the listening TCP port. The `socat` command provides a `reuseport` option that enables `SO_REUSEPORT` on the listening TCP port. Ref: #4160 (comment) Signed-off-by: Norio Nomura <[email protected]> hack/test-port-forwarding.pl: Add a connection timeout option and relax it from 1 second to 2 seconds. Signed-off-by: Norio Nomura <[email protected]>
1 parent fdee71c commit c18012f

File tree

3 files changed

+76
-28
lines changed

3 files changed

+76
-28
lines changed

.github/workflows/test.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ jobs:
189189
- name: Integration tests (WSL2, Windows host)
190190
run: |
191191
$env:PATH = "$pwd\_output\bin;" + 'C:\msys64\usr\bin;' + $env:PATH
192-
pacman -Sy --noconfirm openbsd-netcat diffutils
192+
pacman -Sy --noconfirm openbsd-netcat diffutils socat
193193
$env:MSYS2_ENV_CONV_EXCL = 'HOME_HOST;HOME_GUEST;_LIMA_WINDOWS_EXTRA_PATH'
194194
$env:HOME_HOST = $(cygpath.exe "$env:USERPROFILE")
195195
$env:HOME_GUEST = "/mnt$env:HOME_HOST"
@@ -218,7 +218,7 @@ jobs:
218218
- name: Integration tests (QEMU, Windows host)
219219
run: |
220220
$env:PATH = "$pwd\_output\bin;" + 'C:\msys64\usr\bin;' + 'C:\Program Files\QEMU;' + $env:PATH
221-
pacman -Sy --noconfirm openbsd-netcat diffutils
221+
pacman -Sy --noconfirm openbsd-netcat diffutils socat
222222
$env:MSYS2_ENV_CONV_EXCL = 'HOME_HOST;HOME_GUEST;_LIMA_WINDOWS_EXTRA_PATH'
223223
$env:HOME_HOST = $(cygpath.exe "$env:USERPROFILE")
224224
$env:HOME_GUEST = "$env:HOME_HOST"
@@ -251,7 +251,8 @@ jobs:
251251
# bash: required by test-templates.sh (OS version of bash is too old)
252252
# coreutils: required by test-templates.sh for the "timeout" command
253253
# w3m : required by test-templates.sh for port forwarding tests
254-
run: brew install qemu bash coreutils w3m
254+
# socat: required by test-templates.sh for port forwarding tests
255+
run: brew install qemu bash coreutils w3m socat
255256
- name: "Adjust LIMACTL_CREATE_ARGS"
256257
run: echo "LIMACTL_CREATE_ARGS=${LIMACTL_CREATE_ARGS} --vm-type=qemu" >>$GITHUB_ENV
257258
- name: "Inject `no_timer_check` to kernel cmdline"
@@ -316,7 +317,7 @@ jobs:
316317
run: |
317318
sudo apt-get update
318319
sudo ./hack/install-qemu.sh
319-
sudo apt-get install -y --no-install-recommends w3m
320+
sudo apt-get install -y --no-install-recommends socat w3m
320321
- name: Install ansible-playbook
321322
run: |
322323
sudo apt-get install -y --no-install-recommends ansible
@@ -438,7 +439,7 @@ jobs:
438439
with:
439440
template: templates/default.yaml
440441
- name: Install test dependencies
441-
run: brew install qemu bash coreutils w3m
442+
run: brew install qemu bash coreutils w3m socat
442443
- name: Install socket_vmnet
443444
env:
444445
SOCKET_VMNET_VERSION: v1.2.0
@@ -533,7 +534,7 @@ jobs:
533534
with:
534535
template: templates/${{ matrix.template }}
535536
- name: Install test dependencies
536-
run: brew install bash coreutils w3m
537+
run: brew install bash coreutils w3m socat
537538
- name: Uninstall qemu
538539
run: brew uninstall --ignore-dependencies --force qemu
539540
- name: Test

hack/test-port-forwarding.pl

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# ./hack/test-port-forwarding.pl templates/default.yaml
99
# limactl --tty=false start templates/default.yaml
1010
# git restore templates/default.yaml
11-
# ./hack/test-port-forwarding.pl default
11+
# ./hack/test-port-forwarding.pl default [nc|socat [nc|socat]] [timeout]
1212
#
1313
# TODO: support for ipv6 host addresses
1414

@@ -21,7 +21,23 @@
2121
use Socket qw(inet_ntoa);
2222
use Sys::Hostname qw(hostname);
2323

24+
my $connectionTimeout = 1; # seconds
25+
2426
my $instance = shift;
27+
my $listener;
28+
my $writer;
29+
while (my $arg = shift) {
30+
if ($arg eq "nc" || $arg eq "socat") {
31+
$listener = $arg unless defined $listener;
32+
$writer = $arg if defined $listener && !defined $writer;
33+
} elsif ($arg =~ /^\d+$/) {
34+
$connectionTimeout = $arg;
35+
} else {
36+
die "Usage: $0 [instance|yaml-file] [nc|socat [nc|socat]] [timeout]\n";
37+
}
38+
}
39+
$listener ||= "nc";
40+
$writer ||= $listener;
2541

2642
my $addr = scalar gethostbyname(hostname());
2743
# If hostname address cannot be determines, use localhost to trigger fallback to system_profiler lookup
@@ -146,7 +162,8 @@
146162
set -e
147163
cd $HOME
148164
sudo pkill -x nc || true
149-
rm -f nc.*
165+
sudo pkill -x socat || true
166+
rm -f nc.* socat.*
150167
EOF
151168

152169
# Give the hostagent some time to remove any port forwards from a previous (crashed?) test run
@@ -161,13 +178,19 @@
161178
# Setup a netcat listener on the guest for each test
162179
foreach my $id (0..@test-1) {
163180
my $test = $test[$id];
164-
my $nc = "nc -l $test->{guest_ip} $test->{guest_port}";
165-
if ($instance =~ /^alpine/) {
166-
$nc = "nc -l -s $test->{guest_ip} -p $test->{guest_port}";
181+
my $cmd;
182+
if ($listener eq "nc") {
183+
$cmd = "nc -l $test->{guest_ip} $test->{guest_port}";
184+
if ($instance =~ /^alpine/) {
185+
$cmd = "nc -l -s $test->{guest_ip} -p $test->{guest_port}";
186+
}
187+
} elsif ($listener eq "socat") {
188+
my $proto = $test->{guest_ip} =~ /:/ ? "TCP6" : "TCP";
189+
$cmd = "socat -u $proto-LISTEN:$test->{guest_port},bind=$test->{guest_ip} STDOUT";
167190
}
168191

169192
my $sudo = $test->{guest_port} < 1024 ? "sudo " : "";
170-
print $lima "${sudo}${nc} >nc.${id} 2>/dev/null &\n";
193+
print $lima "${sudo}${cmd} >$listener.${id} 2>/dev/null &\n";
171194
}
172195

173196
# Make sure the guest- and hostagents had enough time to set up the forwards
@@ -176,8 +199,15 @@
176199
# Try to reach each listener from the host
177200
foreach my $test (@test) {
178201
next if $test->{host_port} == $sshLocalPort;
179-
my $nc = $test->{host_socket} eq "" ? "nc -w 1 $test->{host_ip} $test->{host_port}" : "nc -w 1 -U $test->{host_socket}";
180-
open(my $netcat, "| $nc") or die "Can't run '$nc': $!";
202+
my $cmd;
203+
if ($writer eq "nc") {
204+
$cmd = $test->{host_socket} eq "" ? "nc -w $connectionTimeout $test->{host_ip} $test->{host_port}" : "nc -w $connectionTimeout -U $test->{host_socket}";
205+
} elsif ($writer eq "socat") {
206+
my $tcp_dest = $test->{host_ip} =~ /:/ ? "TCP6:[$test->{host_ip}]:$test->{host_port}" : "TCP:$test->{host_ip}:$test->{host_port}";
207+
$cmd = $test->{host_socket} eq "" ? "socat -u STDIN $tcp_dest,connect-timeout=$connectionTimeout" : "socat -u STDIN UNIX-CONNECT:$test->{host_socket}";
208+
}
209+
print "Running: $cmd\n";
210+
open(my $netcat, "| $cmd") or die "Can't run '$cmd': $!";
181211
print $netcat "$test->{log_msg}\n";
182212
# Don't check for errors on close; macOS nc seems to return non-zero exit code even on success
183213
close($netcat);
@@ -204,7 +234,7 @@
204234
unless ($seen{$test->{log_msg}}) {
205235
$err .= "\n Message missing from ha.stderr.log";
206236
}
207-
my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat nc.$id");
237+
my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat $listener.$id");
208238
chomp $log;
209239
if ($test->{mode} eq "forward" && $test->{log_msg} ne $log) {
210240
$err .= "\n Guest received: '$log'";
@@ -241,7 +271,7 @@
241271
}
242272

243273
# Cleanup remaining netcat instances (and port forwards)
244-
print $lima "sudo pkill -x nc";
274+
print $lima "sudo pkill -x $listener";
245275

246276
exit $rc;
247277

hack/test-templates.sh

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -432,24 +432,41 @@ if [[ -n ${CHECKS["container-engine"]} ]]; then
432432
fi
433433

434434
if [[ -n ${CHECKS["port-forwards"]} ]]; then
435-
INFO "Testing port forwarding rules using netcat"
435+
PORT_FORWARDING_CONNECTION_TIMEOUT=2
436+
INFO "Testing port forwarding rules using netcat and socat with connection timeout ${PORT_FORWARDING_CONNECTION_TIMEOUT}s"
436437
set -x
437-
if [ "${NAME}" = "archlinux" ]; then
438-
limactl shell "$NAME" sudo pacman -Syu --noconfirm openbsd-netcat
438+
if [[ ${NAME} == "alpine"* ]]; then
439+
limactl shell "${NAME}" sudo apk add socat
439440
fi
440-
if [ "${NAME}" = "debian" ]; then
441-
limactl shell "$NAME" sudo apt-get install -y netcat-openbsd
441+
if [[ ${NAME} == "archlinux" ]]; then
442+
limactl shell "${NAME}" sudo pacman -Syu --noconfirm openbsd-netcat socat
442443
fi
443-
if [ "${NAME}" == "fedora" ]; then
444-
limactl shell "$NAME" sudo dnf install -y nc
444+
if [[ ${NAME} == "debian" || ${NAME} == "default" || ${NAME} == "docker" || ${NAME} == "test-misc" ]]; then
445+
limactl shell "${NAME}" sudo apt-get install -y netcat-openbsd socat
445446
fi
446-
if [ "${NAME}" = "opensuse" ]; then
447-
limactl shell "$NAME" sudo zypper in -y netcat-openbsd
447+
if [[ ${NAME} == "fedora" || ${NAME} == "wsl2" ]]; then
448+
limactl shell "${NAME}" sudo dnf install -y nc socat
448449
fi
449-
if limactl shell "$NAME" command -v dnf; then
450-
limactl shell "$NAME" sudo dnf install -y nc
450+
if [[ ${NAME} == "opensuse" ]]; then
451+
limactl shell "${NAME}" sudo zypper in -y netcat-openbsd socat
452+
fi
453+
if limactl shell "${NAME}" command -v dnf; then
454+
limactl shell "${NAME}" sudo dnf install -y nc socat
455+
fi
456+
if "${scriptdir}/test-port-forwarding.pl" "${NAME}" $PORT_FORWARDING_CONNECTION_TIMEOUT; then
457+
if "${scriptdir}/test-port-forwarding.pl" "${NAME}" socat $PORT_FORWARDING_CONNECTION_TIMEOUT; then
458+
INFO "Port forwarding rules work"
459+
else
460+
ERROR "Port forwarding rules do not work with socat"
461+
diagnose "$NAME"
462+
exit 1
463+
fi
464+
else
465+
"${scriptdir}/test-port-forwarding.pl" "${NAME}" socat $PORT_FORWARDING_CONNECTION_TIMEOUT
466+
ERROR "Port forwarding rules do not work"
467+
diagnose "$NAME"
468+
exit 1
451469
fi
452-
"${scriptdir}/test-port-forwarding.pl" "${NAME}"
453470

454471
if [[ -n ${CHECKS["container-engine"]} || ${NAME} == "alpine"* ]]; then
455472
INFO "Testing that \"${CONTAINER_ENGINE} run\" binds to 0.0.0.0 and is forwarded to the host (non-default behavior, configured via test-port-forwarding.pl)"

0 commit comments

Comments
 (0)