]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
daemon: warn on setsockopt failures
authorEric Wong <e@80x24.org>
Sat, 9 Nov 2024 01:13:41 +0000 (01:13 +0000)
committerEric Wong <e@80x24.org>
Sat, 9 Nov 2024 19:35:11 +0000 (19:35 +0000)
While actually dying is too harsh for platform-specific
features, having a warning may be useful in case the system is
misconfigured somehow.

lib/PublicInbox/Daemon.pm

index fa4314b4da0cb6819f8a5f1f21dde57f15385ece..8e6ddbb9e98e5e1be2b2bc5dfd0b698661d05da4 100644 (file)
@@ -6,7 +6,7 @@
 # and/or lossy connections.
 package PublicInbox::Daemon;
 use v5.12;
-use autodie qw(chdir open pipe);
+use autodie qw(chdir open pipe setsockopt);
 use Getopt::Long qw(:config gnu_getopt no_ignore_case auto_abbrev);
 use IO::Handle; # ->autoflush
 use IO::Socket;
@@ -644,20 +644,26 @@ sub tls_cb {
 
 sub defer_accept ($$) {
        my ($s, $af_name) = @_;
-       return unless defined $af_name;
-       if ($^O eq 'linux') {
-               my $TCP_DEFER_ACCEPT = 9; # Socket::TCP_DEFER_ACCEPT is in 5.14+
-               my $x = getsockopt($s, IPPROTO_TCP, $TCP_DEFER_ACCEPT);
-               return unless defined $x; # may be Unix socket
-               my $sec = unpack('i', $x);
-               return if $sec > 0; # systemd users may set a higher value
-               setsockopt($s, IPPROTO_TCP, $TCP_DEFER_ACCEPT, 1);
-       } elsif ($^O =~ /\A(?:freebsd|netbsd|dragonfly)\z/) {
-               my $x = getsockopt($s, SOL_SOCKET, $SO_ACCEPTFILTER);
-               return if ($x // "\0") =~ /[^\0]/s; # don't change if set
-               my $accf_arg = pack('a16a240', $af_name, '');
-               setsockopt($s, SOL_SOCKET, $SO_ACCEPTFILTER, $accf_arg);
-       }
+       $af_name // return;
+       eval {
+               if ($^O eq 'linux') {
+                       # Socket::TCP_DEFER_ACCEPT is only in 5.14+
+                       my $TCP_DEFER_ACCEPT = 9;
+                       my $x = getsockopt($s, IPPROTO_TCP, $TCP_DEFER_ACCEPT)
+                               // return; # may be Unix socket
+                       my $sec = unpack('i', $x);
+                       return if $sec > 0; # systemd users may this higher
+                       setsockopt $s, IPPROTO_TCP, $TCP_DEFER_ACCEPT, 1;
+               } elsif ($^O =~ /\A(?:freebsd|netbsd|dragonfly)\z/) {
+                       # getsockopt can EINVAL if SO_ACCEPTFILTER is unset:
+                       my $x = getsockopt($s, SOL_SOCKET, $SO_ACCEPTFILTER);
+                       return if ($x // '') =~ /[^\0]/s; # don't change if set
+                       my $accf_arg = pack('a16a240', $af_name, '');
+                       setsockopt $s, SOL_SOCKET, $SO_ACCEPTFILTER, $accf_arg;
+               }
+       };
+       my $err = $@; # sockname() clobbers $@
+       warn 'W: ', sockname($s), ' ', $err, "\n" if $err;
 }
 
 sub daemon_loop () {