]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/TLS.pm
No ext_urls
[public-inbox.git] / lib / PublicInbox / TLS.pm
1 # Copyright (C) all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3
4 # IO::Socket::SSL support code
5 package PublicInbox::TLS;
6 use strict;
7 use IO::Socket::SSL;
8 use PublicInbox::Syscall qw(EPOLLIN EPOLLOUT);
9 use Carp qw(carp croak);
10
11 sub err () { $SSL_ERROR }
12
13 # returns the EPOLL event bit which matches the existing SSL error
14 sub epollbit () {
15         return EPOLLIN if $SSL_ERROR == SSL_WANT_READ;
16         return EPOLLOUT if $SSL_ERROR == SSL_WANT_WRITE;
17         carp "unexpected SSL error: $SSL_ERROR";
18         undef;
19 }
20
21 sub _ctx_new ($) {
22         my ($tlsd) = @_;
23         my $ctx = IO::Socket::SSL::SSL_Context->new(
24                                 @{$tlsd->{ssl_ctx_opt}}, SSL_server => 1) or
25                 croak "SSL_Context->new: $SSL_ERROR";
26
27         # save ~34K per idle connection (cf. SSL_CTX_set_mode(3ssl))
28         # RSS goes from 346MB to 171MB with 10K idle NNTPS clients on amd64
29         # cf. https://rt.cpan.org/Ticket/Display.html?id=129463
30         my $mode = eval { Net::SSLeay::MODE_RELEASE_BUFFERS() };
31         if ($mode && $ctx->{context}) {
32                 eval { Net::SSLeay::CTX_set_mode($ctx->{context}, $mode) };
33                 warn "W: $@ (setting SSL_MODE_RELEASE_BUFFERS)\n" if $@;
34         }
35         $ctx;
36 }
37
38 sub start {
39         my ($io, $tlsd) = @_;
40         IO::Socket::SSL->start_SSL($io, SSL_server => 1,
41                 SSL_reuse_ctx => ($tlsd->{ssl_ctx} //= _ctx_new($tlsd)),
42                 SSL_startHandshake => 0);
43 }
44
45 1;