-
-# disable commands with easy DoS potential:
-my %DISABLED; # = map { $_ => 1 } qw(xover list_overview_fmt newnews xhdr);
-
-my $EXPMAP; # fd -> [ idle_time, $self ]
-my $expt;
-our $EXPTIME = 180; # 3 minutes
-my $nextt;
-
-my $nextq = [];
-sub next_tick () {
- $nextt = undef;
- my $q = $nextq;
- $nextq = [];
- foreach my $nntp (@$q) {
- # for request && response protocols, always finish writing
- # before finishing reading:
- if (my $long_cb = $nntp->{long_res}) {
- $nntp->write($long_cb);
- } else {
- # pipelined request, we bypassed socket-readiness
- # checks to get here:
- event_read($nntp);
-
- # maybe there's more pipelined data, or we'll have
- # to register it for socket-readiness notifications
- if (!$nntp->{long_res} && !$nntp->{closed}) {
- check_read($nntp);
- }
- }
- }
-}
-
-sub update_idle_time ($) {
- my ($self) = @_;
- my $fd = $self->{fd};
- defined $fd and $EXPMAP->{$fd} = [ now(), $self ];
-}
-
-sub expire_old () {
- my $now = now();
- my $exp = $EXPTIME;
- my $old = $now - $exp;
- my $nr = 0;
- my %new;
- while (my ($fd, $v) = each %$EXPMAP) {
- my ($idle_time, $nntp) = @$v;
- if ($idle_time < $old) {
- $nntp->close; # idempotent
- } else {
- ++$nr;
- $new{$fd} = $v;
- }
- }
- $EXPMAP = \%new;
- if ($nr) {
- $expt = PublicInbox::EvCleanup::later(*expire_old);
- } else {
- $expt = undef;
- # noop to kick outselves out of the loop ASAP so descriptors
- # really get closed
- PublicInbox::EvCleanup::asap(sub {});
- }
-}