my $sec = unpack('i', $x);
return if $sec > 0; # systemd users may set a higher value
setsockopt($s, IPPROTO_TCP, $TCP_DEFER_ACCEPT, 1);
- } elsif ($^O eq 'freebsd') {
+ } elsif ($^O =~ /\A(?:freebsd|netbsd)\z/) {
my $x = getsockopt($s, SOL_SOCKET, $SO_ACCEPTFILTER);
return if defined $x; # don't change if set
my $accf_arg = pack('a16a240', $af_name, '');
'Net::POP3' => 2.32,
);
+sub need_accept_filter ($) {
+ my ($af) = @_;
+ return if $^O eq 'netbsd'; # since NetBSD 5.0
+ skip 'SO_ACCEPTFILTER is FreeBSD/NetBSD-only' if $^O ne 'freebsd';
+ state $tried = {};
+ ($tried->{$af} //= system("kldstat -m $af >/dev/null")) and
+ skip "$af not loaded: kldload $af";
+}
+
sub require_mods {
my @mods = @_;
my $maybe = pop @mods if $mods[-1] =~ /\A[0-9]+\z/;
push @need, $msg;
next;
}
+ } elsif ($mod =~ /\A\+(accf_.*)\z/) {
+ need_accept_filter($1);
+ next
} elsif (index($mod, '||') >= 0) { # "Foo||Bar"
my $ok;
for my $m (split(/\Q||\E/, $mod)) {
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# note: our HTTP server should be standalone and capable of running
# generic PSGI/Plack apps.
-use strict; use v5.10.1; use PublicInbox::TestCommon;
+use v5.12; use PublicInbox::TestCommon;
use Time::HiRes qw(gettimeofday tv_interval);
+use autodie qw(getsockopt setsockopt);
use PublicInbox::Spawn qw(spawn popen_rd);
require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
use PublicInbox::SHA qw(sha1_hex);
# Make sure we don't clobber socket options set by systemd or similar
# using socket activation:
my ($defer_accept_val, $accf_arg, $TCP_DEFER_ACCEPT);
-if ($^O eq 'linux') {
+SKIP: {
+ skip 'TCP_DEFER_ACCEPT is Linux-only' if $^O ne 'linux';
$TCP_DEFER_ACCEPT = eval { Socket::TCP_DEFER_ACCEPT() } // 9;
- setsockopt($sock, IPPROTO_TCP, $TCP_DEFER_ACCEPT, 5) or die;
+ setsockopt($sock, IPPROTO_TCP, $TCP_DEFER_ACCEPT, 5);
my $x = getsockopt($sock, IPPROTO_TCP, $TCP_DEFER_ACCEPT);
- defined $x or die "getsockopt: $!";
$defer_accept_val = unpack('i', $x);
- if ($defer_accept_val <= 0) {
- die "unexpected TCP_DEFER_ACCEPT value: $defer_accept_val";
- }
-} elsif ($^O eq 'freebsd' && system('kldstat -m accf_data >/dev/null') == 0) {
+ ok($defer_accept_val > 0, 'TCP_DEFER_ACCEPT val non-zero') or
+ xbail "unexpected TCP_DEFER_ACCEPT value: $defer_accept_val";
+}
+SKIP: {
+ require_mods '+accf_data';
require PublicInbox::Daemon;
my $var = $PublicInbox::Daemon::SO_ACCEPTFILTER;
$accf_arg = pack('a16a240', 'dataready', '');
- setsockopt($sock, SOL_SOCKET, $var, $accf_arg) or die "setsockopt: $!";
+ setsockopt($sock, SOL_SOCKET, $var, $accf_arg);
}
sub unix_server ($) {
SKIP: {
skip 'TCP_DEFER_ACCEPT is Linux-only', 1 if $^O ne 'linux';
my $var = $TCP_DEFER_ACCEPT;
- defined(my $x = getsockopt($sock, IPPROTO_TCP, $var)) or die;
+ my $x = getsockopt($sock, IPPROTO_TCP, $var);
is(unpack('i', $x), $defer_accept_val,
'TCP_DEFER_ACCEPT unchanged if previously set');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 1 if $^O ne 'freebsd';
- skip 'accf_data not loaded: kldload accf_data' if !defined $accf_arg;
+ require_mods '+accf_data';
my $var = $PublicInbox::Daemon::SO_ACCEPTFILTER;
- defined(my $x = getsockopt($sock, SOL_SOCKET, $var)) or die;
+ my $x = getsockopt($sock, SOL_SOCKET, $var);
is($x, $accf_arg, 'SO_ACCEPTFILTER unchanged if previously set');
};
ok(unpack('i', $x) > 0, 'TCP_DEFER_ACCEPT set on https');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 2 if $^O ne 'freebsd';
- if (system('kldstat -m accf_data >/dev/null')) {
- skip 'accf_data not loaded? kldload accf_data', 2;
- }
+ require_mods '+accf_data';
require PublicInbox::Daemon;
ok(defined($PublicInbox::Daemon::SO_ACCEPTFILTER),
'SO_ACCEPTFILTER defined');
ok(unpack('i', $x) > 0, 'TCP_DEFER_ACCEPT set');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 1 if $^O ne 'freebsd';
- if (system('kldstat -m accf_http >/dev/null') != 0) {
- skip 'accf_http not loaded: kldload accf_http', 1;
- }
+ require_mods '+accf_http';
require PublicInbox::Daemon;
ok(defined($PublicInbox::Daemon::SO_ACCEPTFILTER),
'SO_ACCEPTFILTER defined');
is(unpack('i', $x), 0, 'TCP_DEFER_ACCEPT is 0 on plain IMAP');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 2 if $^O ne 'freebsd';
- if (system('kldstat -m accf_data >/dev/null')) {
- skip 'accf_data not loaded? kldload accf_data', 2;
- }
+ require_mods '+accf_data';
require PublicInbox::Daemon;
my $x = getsockopt($imaps, SOL_SOCKET,
$PublicInbox::Daemon::SO_ACCEPTFILTER);
is(unpack('i', $x), 0, 'TCP_DEFER_ACCEPT is 0 on plain NNTP');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 2 if $^O ne 'freebsd';
- if (system('kldstat -m accf_data >/dev/null')) {
- skip 'accf_data not loaded? kldload accf_data', 2;
- }
+ require_mods '+accf_data';
require PublicInbox::Daemon;
my $x = getsockopt($nntps, SOL_SOCKET,
$PublicInbox::Daemon::SO_ACCEPTFILTER);
is(unpack('i', $x), 0, 'TCP_DEFER_ACCEPT is 0 on plain POP3');
};
SKIP: {
- skip 'SO_ACCEPTFILTER is FreeBSD-only', 2 if $^O ne 'freebsd';
- system('kldstat -m accf_data >/dev/null') and
- skip 'accf_data not loaded? kldload accf_data', 2;
+ require_mods '+accf_data';
require PublicInbox::Daemon;
my $x = getsockopt($pop3s, SOL_SOCKET,
$PublicInbox::Daemon::SO_ACCEPTFILTER);