From 74923a7cb6ace0369455e2155cbf63dfa4be33ea Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 6 Dec 2018 02:40:06 +0000 Subject: nntp: prevent event_read from firing twice in a row When a client starts pipelining requests to us which trigger long responses, we need to keep socket readiness checks disabled and only enable them when our socket rbuf is drained. Failure to do this caused aborted clients with "BUG: nested long response" when Danga::Socket calls event_read for read-readiness after our "next_tick" sub fires in the same event loop iteration. Reported-by: Jonathan Corbet cf. https://public-inbox.org/meta/20181013124658.23b9f9d2@lwn.net/ --- t/nntpd.t | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 't') diff --git a/t/nntpd.t b/t/nntpd.t index 9c1d0762..ffed4376 100644 --- a/t/nntpd.t +++ b/t/nntpd.t @@ -252,6 +252,27 @@ EOF ok($date <= $t1, 'valid date before stop'); } + # pipelined requests: + { + my $nreq = 90; + syswrite($s, "GROUP $group\r\n"); + my $res = <$s>; + my $rdr = fork; + if ($rdr == 0) { + use POSIX qw(_exit); + for (1..$nreq) { + <$s> =~ /\A224 / or _exit(1); + <$s> =~ /\A1/ or _exit(2); + <$s> eq ".\r\n" or _exit(3); + } + _exit(0); + } + for (1..$nreq) { + syswrite($s, "XOVER 1\r\n"); + } + is($rdr, waitpid($rdr, 0), 'reader done'); + is($? >> 8, 0, 'no errors'); + } { setsockopt($s, IPPROTO_TCP, TCP_NODELAY, 1); syswrite($s, 'HDR List-id 1-'); -- cgit v1.2.3-24-ge0c7