From d78bd171f28f56c6f064b22899792aaf3286127c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 Apr 2007 13:31:27 +0200 Subject: [PATCH] Implement rate limiting in mbd, and fix some logging. --- mbd/mbd.pl | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/mbd/mbd.pl b/mbd/mbd.pl index 44dd334..dcc25fe 100644 --- a/mbd/mbd.pl +++ b/mbd/mbd.pl @@ -4,6 +4,7 @@ use warnings; use Socket; use Net::CIDR; use Net::RawIP; +use Time::HiRes; require './access_list.pl'; require './nets.pl'; require './mbd.pm'; @@ -16,6 +17,9 @@ sub fhbits { return $bits; } +# used for rate limiting +my %last_sent = (); + my %cidrcache = (); sub cache_cidrlookup { my ($addr, $net) = @_; @@ -71,6 +75,17 @@ while (1) { my ($dport, $daddr) = sockaddr_in(getsockname($sock)); my $size = length($data); + # Rate limiting + my $now = [Time::HiRes::gettimeofday]; + if (exists($last_sent{$saddr}{$dport})) { + my $elapsed = Time::HiRes::tv_interval($last_sent{$saddr}{$dport}, $now); + if ($elapsed < 1.0) { + print LOG "$dport $size 2\n"; + print inet_ntoa($saddr), ", $dport, $size bytes => rate-limited ($elapsed secs since last)\n"; + } + next; + } + # We don't get the packet's destination address, but I guess this should do... # Check against the ACL. my $pass = 0; @@ -89,10 +104,11 @@ while (1) { print LOG "$dport $size $pass\n"; if (!$pass) { - print "$dport, $size bytes => filtered\n"; + print inet_ntoa($saddr), ", $dport, $size bytes => filtered\n"; + next; } - next unless $pass; + $last_sent{$saddr}{$dport} = $now; my $num_nets = 0; -- 2.39.2