package Foo::FloodBlocker; use strict; use warnings; use Apache2::Connection; use Apache2::Const -compile => qw/FORBIDDEN OK/; use IPC::Shareable ':all'; use constant { FILTERGLUE => 'PIFt', FILTERSHMEM => 1048576 }; sub handler { my $c = shift; return Apache2::Const::OK if $c->keepalives; my $ip = $c->remote_ip; my $time = time; no warnings 'untie'; my ($shmem, %hash); $shmem = tie %hash, 'IPC::Shareable', FILTERGLUE, { create => 0, mode => 0666, size => FILTERSHMEM, exclusive => 0, destroy => 0 }; $ip =~ s/\./_/g; my $block; $shmem->shlock(LOCK_EX); if (exists $hash{$ip}) { if ($hash{$ip} < $time) { delete $hash{$ip}; } else { $block = 1; } } else { $hash{$ip} = $time; } $shmem->shunlock; untie %hash; undef $shmem; return Apache2::Const::FORBIDDEN if $block; Apache2::Const::OK; }