From 9be94eda4e31b39a9a41e0893d7f7022295de236 Mon Sep 17 00:00:00 2001 From: jake Date: Wed, 17 Aug 2022 15:45:27 -0400 Subject: Add 'timeout' config option --- config.toml.sample | 6 +++++- gmi.pl | 26 ++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/config.toml.sample b/config.toml.sample index ca6313f..adcc44b 100644 --- a/config.toml.sample +++ b/config.toml.sample @@ -22,9 +22,13 @@ cert_key_dir = "certs" # avoid putting final '/' # Setting the following to 'false' will not emit an error. cert_key_dir_write_warning = true # For each accepted connection a fork() is called. This toggles if that should happen or not. -# For debugging or memory reasons, it may help to set this to false, though it may result in clients timing out if your server is busy serving a client. +# For debugging or memory reasons, it may help to set this to false, though it may result in clients timing out # if your server is busy serving a client. # Will cause 'timed-out' and 'sysread failed' to appear at the same time in log files. fork = true +# When the server accept()s the client needs to send, per the Gemini spec: '' +# This timeout option determines how long the server will wait before timing them out. +# 0 is equivalent to 'do not timeout'. Naughty bots/people sit there doing nothing but clogging the ports. +timeout = 5 ## These are not specific to default and can be used with vhost ## Vhost options will override default options diff --git a/gmi.pl b/gmi.pl index e8bf265..4248d9a 100755 --- a/gmi.pl +++ b/gmi.pl @@ -7,7 +7,7 @@ use warnings; use 5.010; #use diagnostics; -our $VERSION = 'v0.0.10'; +our $VERSION = 'v0.0.11'; # Modules use IO::Socket::SSL; # CPAN @@ -57,7 +57,7 @@ const our %GEM_RES_CODES => ( const our @VALID_DEFAULT_SETTINGS => qw/bind ports tls assume_index dir_listing root working_dir cert_key_dir - log_file log_to_stdout default_mime cert_key_dir_write_warning fork/; + log_file log_to_stdout default_mime cert_key_dir_write_warning fork timeout/; const our @VALID_VHOST_SETTINGS => qw/auto_cert assume_index dir_listing root cert key default_mime/; @@ -71,6 +71,7 @@ my %ssl_config = ssl_config($config); my $working_dir = working_dir($config); my $cert_key_dir = cert_key_dir($config); my $out = logging($config); +my $timeout = timeout_secs($config); select $out; ## no critic (InputOutput::ProhibitOneArgSelect) local $OUTPUT_AUTOFLUSH = 1; ssl_vhost_cert_key(\%ssl_config); @@ -110,7 +111,7 @@ while () { # We do this because 'naughty' people/bots can clog up the ports doing nothing. local $SIG{ALRM} = sub { timeout($cl, $clhost, $cl_sni) }; - alarm 5; # TODO make magic number not magic. + alarm $timeout; # TODO make magic number not magic. if (! sysread $cl, $data, $KBYTE) { $log = "$clhost - ($cl_sni) sysread failed"; alarm 0; @@ -509,7 +510,8 @@ sub ssl_config { SSL_version => '!SSLv2:!SSLv3:!TLSv1:!TLSv1_1', SSL_fast_shutdown => 1, - Timeout => 2, + Timeout => 2, # !! Nothing to do with the config option !! + # used if /no/ SSL connection was established SSL_error_trap => 1, #SSL_server => 1, ); @@ -755,4 +757,20 @@ sub maybe_fork { } } +sub timeout_secs { + my ($cert_ref) = @_; + if (exists $cert_ref->{default}{timeout}) { + if ($cert_ref->{default}{timeout} =~ /^(\d*)$/) { + return $1; + } + else { + serr("Timeout value ($cert_ref->{default}{timeout}) is invalid. Using 5 seconds."); + return 5; + } + } + else { + return 5; + } +} + 1; -- cgit v1.2.3