about summary refs log tree commit homepage
path: root/t/nntpd-tls.t
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-06-24 02:52:43 +0000
committerEric Wong <e@80x24.org>2019-06-24 05:26:27 +0000
commit1dc4d2f75a387c9113fc7646c463e3aac2d3de1f (patch)
tree5e8de49680d200a7d631a4b679735e7edced0fa6 /t/nntpd-tls.t
parent595854982a59f369ab605794f05c046c86253468 (diff)
downloadpublic-inbox-1dc4d2f75a387c9113fc7646c463e3aac2d3de1f.tar.gz
We need to ensure slowly negotiating TLS clients don't block
the event loop.  This is why I added the size check of
{wbuf} before and after calling the CODE ref in DS::flush_write.
Diffstat (limited to 't/nntpd-tls.t')
-rw-r--r--t/nntpd-tls.t36
1 files changed, 32 insertions, 4 deletions
diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t
index 00b03b66..e8fb63b4 100644
--- a/t/nntpd-tls.t
+++ b/t/nntpd-tls.t
@@ -5,7 +5,9 @@ use warnings;
 use Test::More;
 use File::Temp qw(tempdir);
 use Socket qw(SOCK_STREAM);
-foreach my $mod (qw(DBD::SQLite IO::Socket::SSL Net::NNTP)) {
+# IO::Poll and Net::NNTP are part of the standard library, but
+# distros may split them off...
+foreach my $mod (qw(DBD::SQLite IO::Socket::SSL Net::NNTP IO::Poll)) {
         eval "require $mod";
         plan skip_all => "$mod missing for $0" if $@;
 }
@@ -108,21 +110,32 @@ for my $args (
         my %o = (
                 SSL_hostname => 'server.local',
                 SSL_verifycn_name => 'server.local',
-                SSL => 1,
                 SSL_verify_mode => SSL_VERIFY_PEER(),
                 SSL_ca_file => 'certs/test-ca.pem',
         );
         my $expect = { $group => [qw(1 1 n)] };
 
+        # start negotiating a slow TLS connection
+        my $slow = IO::Socket::INET->new(
+                Proto => 'tcp',
+                PeerAddr => $nntps_addr,
+                Type => SOCK_STREAM,
+                Blocking => 0,
+        );
+        $slow = IO::Socket::SSL->start_SSL($slow, SSL_startHandshake => 0, %o);
+        my $slow_done = $slow->connect_SSL;
+        diag('W: connect_SSL early OK, slow client test invalid') if $slow_done;
+        my @poll = (fileno($slow), PublicInbox::TLS::epollbit());
+        # we should call connect_SSL much later...
+
         # NNTPS
-        my $c = Net::NNTP->new($nntps_addr, %o);
+        my $c = Net::NNTP->new($nntps_addr, %o, SSL => 1);
         my $list = $c->list;
         is_deeply($list, $expect, 'NNTPS LIST works');
         is($c->command('QUIT')->response(), Net::Cmd::CMD_OK(), 'QUIT works');
         is(0, sysread($c, my $buf, 1), 'got EOF after QUIT');
 
         # STARTTLS
-        delete $o{SSL};
         $c = Net::NNTP->new($starttls_addr, %o);
         $list = $c->list;
         is_deeply($list, $expect, 'plain LIST works');
@@ -154,6 +167,21 @@ for my $args (
         $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;
+
         $c = undef;
         kill('TERM', $pid);
         is($pid, waitpid($pid, 0), 'nntpd exited successfully');