+ # STARTTLS with bad hostname
+ $o{SSL_hostname} = $o{SSL_verifycn_name} = 'server.invalid';
+ $c = Net::NNTP->new($starttls_addr, %o);
+ like(get_capa($c), qr/\bSTARTTLS\r\n/, 'STARTTLS advertised');
+ $list = $c->list;
+ is_deeply($list, $expect, 'plain LIST works again');
+ ok(!$c->starttls, 'STARTTLS fails with bad hostname');
+ $c = Net::NNTP->new($starttls_addr, %o);
+ $list = $c->list;
+ is_deeply($list, $expect, 'not broken after bad negotiation');
+
+ # NNTPS with bad hostname
+ $c = Net::NNTP->new($nntps_addr, %o, SSL => 1);
+ is($c, undef, 'NNTPS fails with bad hostname');
+ $o{SSL_hostname} = $o{SSL_verifycn_name} = 'server.local';
+ $c = Net::NNTP->new($nntps_addr, %o, SSL => 1);
+ ok($c, 'NNTPS succeeds again with valid hostname');
+
+ # slow TLS connection did not block the other fast clients while
+ # connecting, finish it off:
+ until ($slow_done) {
+ IO::Poll::_poll(-1, @poll);
+ $slow_done = $slow->connect_SSL and last;
+ @poll = (fileno($slow), PublicInbox::TLS::epollbit());
+ }
+ $slow->blocking(1);
+ ok(sysread($slow, my $greet, 4096) > 0, 'slow got greeting');
+ like($greet, qr/\A201 /, 'got expected greeting');
+ is(syswrite($slow, "QUIT\r\n"), 6, 'slow wrote QUIT');
+ ok(sysread($slow, my $end, 4096) > 0, 'got EOF');
+ is(sysread($slow, my $eof, 4096), 0, 'got EOF');
+ $slow = undef;
+
+ test_lei(sub {
+ lei_ok qw(ls-mail-source), "nntp://$starttls_addr",
+ \'STARTTLS not used by default';
+ ok(!lei(qw(ls-mail-source -c nntp.starttls=true),
+ "nntp://$starttls_addr"), 'STARTTLS verify fails');
+ diag $lei_err;
+ });
+
+ SKIP: {
+ skip 'TCP_DEFER_ACCEPT is Linux-only', 2 if $^O ne 'linux';
+ my $var = eval { Socket::TCP_DEFER_ACCEPT() } // 9;
+ defined(my $x = getsockopt($nntps, IPPROTO_TCP, $var)) or die;
+ ok(unpack('i', $x) > 0, 'TCP_DEFER_ACCEPT set on NNTPS');
+ defined($x = getsockopt($starttls, IPPROTO_TCP, $var)) or die;
+ 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 PublicInbox::Daemon;
+ my $x = getsockopt($nntps, SOL_SOCKET,
+ $PublicInbox::Daemon::SO_ACCEPTFILTER);
+ like($x, qr/\Adataready\0+\z/, 'got dataready accf for NNTPS');
+ $x = getsockopt($starttls, IPPROTO_TCP,
+ $PublicInbox::Daemon::SO_ACCEPTFILTER);
+ is($x, undef, 'no BSD accept filter for plain NNTP');
+ };
+