From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 8B6E41F4B6 for ; Mon, 24 Jun 2019 02:58:07 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 41/57] nntp: call SSL_shutdown in normal cases Date: Mon, 24 Jun 2019 02:52:42 +0000 Message-Id: <20190624025258.25592-42-e@80x24.org> In-Reply-To: <20190624025258.25592-1-e@80x24.org> References: <20190624025258.25592-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This is in accordance with TLS standards and will be needed to support session caching/reuse in the future. However, we don't issue shutdown(2) since we know not to inadvertantly share our sockets with other processes. --- lib/PublicInbox/DS.pm | 24 ++++++++++++++++++++++++ lib/PublicInbox/NNTP.pm | 12 +++++++++--- t/nntpd-tls.t | 2 ++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index 2c886b4e..2aa9e3d2 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -621,6 +621,30 @@ sub accept_tls_step ($) { drop($self, 'BUG? EAGAIN but '.PublicInbox::TLS::err()); } +sub shutdn_tls_step ($) { + my ($self) = @_; + my $sock = $self->{sock} or return; + return $self->close if $sock->stop_SSL(SSL_fast_shutdown => 1); + return $self->close if $! != EAGAIN; + if (my $ev = PublicInbox::TLS::epollbit()) { + unshift @{$self->{wbuf} ||= []}, \&shutdn_tls_step; + return watch($self, $ev | EPOLLONESHOT); + } + drop($self, 'BUG? EAGAIN but '.PublicInbox::TLS::err()); +} + +# don't bother with shutdown($sock, 2), we don't fork+exec w/o CLOEXEC +# or fork w/o exec, so no inadvertant socket sharing +sub shutdn ($) { + my ($self) = @_; + my $sock = $self->{sock} or return; + if (ref($sock) eq 'IO::Socket::SSL') { + shutdn_tls_step($self); + } else { + $self->close; + } +} + package PublicInbox::DS::Timer; # [$abs_float_firetime, $coderef]; sub cancel { diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 8840adbb..53de2bca 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -74,11 +74,17 @@ sub expire_old () { my $exp = $EXPTIME; my $old = $now - $exp; my $nr = 0; + my $closed = 0; my %new; while (my ($fd, $v) = each %$EXPMAP) { my ($idle_time, $nntp) = @$v; if ($idle_time < $old) { - $nntp->close; # idempotent + if ($nntp->shutdn) { + $closed++; + } else { + ++$nr; + $new{$fd} = $v; + } } else { ++$nr; $new{$fd} = $v; @@ -91,7 +97,7 @@ sub expire_old () { $expt = undef; # noop to kick outselves out of the loop ASAP so descriptors # really get closed - PublicInbox::EvCleanup::asap(sub {}); + PublicInbox::EvCleanup::asap(sub {}) if $closed; } } @@ -410,7 +416,7 @@ sub cmd_post ($) { sub cmd_quit ($) { my ($self) = @_; res($self, '205 closing connection - goodbye!'); - $self->close; + $self->shutdn; undef; } diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t index 4727ee5b..00b03b66 100644 --- a/t/nntpd-tls.t +++ b/t/nntpd-tls.t @@ -118,6 +118,8 @@ for my $args ( my $c = Net::NNTP->new($nntps_addr, %o); 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}; -- EW