From e30bd8928e466b1b7b33440352af079779bd0611 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 Apr 2007 14:32:57 +0200 Subject: [PATCH] Make survey functionality for MBD. --- mbd/mbd.pl | 96 ++++++++++++++++++++++++++++++++++++++++++++++++--- mbd/survey.pl | 10 ++++++ 2 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 mbd/survey.pl diff --git a/mbd/mbd.pl b/mbd/mbd.pl index dcc25fe..4843b0b 100644 --- a/mbd/mbd.pl +++ b/mbd/mbd.pl @@ -7,6 +7,7 @@ use Net::RawIP; use Time::HiRes; require './access_list.pl'; require './nets.pl'; +require './survey.pl'; require './mbd.pm'; sub fhbits { @@ -20,6 +21,10 @@ sub fhbits { # used for rate limiting my %last_sent = (); +# for own surveying +my %active_surveys = (); +my %last_survey = (); + my %cidrcache = (); sub cache_cidrlookup { my ($addr, $net) = @_; @@ -44,7 +49,7 @@ sub cache_cidrrange { open LOG, ">>", "mbd.log"; -my @ports = mbd::find_all_ports(); +my @ports = ( mbd::find_all_ports() , $Config::survey_port_low, $Config::survey_port_high ); # Open a socket for each port my @socks = (); @@ -66,6 +71,21 @@ while (1) { my $rout; my $nfound = select($rout=$rin, undef, undef, undef); + my $now = [Time::HiRes::gettimeofday]; + + # First of all, close any surveys that are due. + for my $sport (keys %active_surveys) { + my $age = Time::HiRes::tv_interval($active_surveys{$sport}{start}, $now); + if ($age > $Config::survey_time && $active_surveys{$sport}{active}) { + print "Survey for port " . $active_surveys{$sport}{dport} . ": " . + $active_surveys{$sport}{num} . " active servers.\n"; + $active_surveys{$sport}{active} = 0; + } + if ($age > $Config::survey_time * 3.0) { + delete $active_surveys{$sport}; + } + } + for my $sock (@socks) { next unless (vec($rout, fileno($sock), 1) == 1); @@ -75,8 +95,23 @@ while (1) { my ($dport, $daddr) = sockaddr_in(getsockname($sock)); my $size = length($data); + # Check if this is a survey reply + if ($dport >= $Config::survey_port_low && $dport <= $Config::survey_port_high) { + if (!exists($active_surveys{$dport})) { + print "WARNING: Unknown survey port $dport, ignoring\n"; + next; + } + if (!$active_surveys{$dport}{active}) { + # remains + next; + } + + ++$active_surveys{$dport}{num}; + + next; + } + # 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) { @@ -110,8 +145,40 @@ while (1) { $last_sent{$saddr}{$dport} = $now; - my $num_nets = 0; + # The packet is OK! Do we already have a recent enough survey + # for this port, or should we use this packet? + my $survey = 1; + if (exists($last_survey{$dport})) { + my $age = Time::HiRes::tv_interval($last_survey{$dport}, $now); + if ($age < $Config::survey_freq) { + $survey = 0; + } + } + + # New survey; find an unused port + my $survey_sport; + for my $port ($Config::survey_port_low..$Config::survey_port_high) { + if (!exists($active_surveys{$port})) { + $survey_sport = $port; + + $active_surveys{$port} = { + start => $now, + active => 1, + dport => $dport, + num => 0 + }; + $last_survey{$dport} = $now; + + last; + } + } + + if (!defined($survey_sport)) { + print "WARNING: no free survey source ports, not surveying.\n"; + $survey = 0; + } + my $num_nets = 0; for my $net (@Config::networks) { next if (cache_cidrlookup(inet_ntoa($saddr), $net)); @@ -131,9 +198,30 @@ while (1) { } }); $sendsock->send; + + if ($survey) { + $sendsock->set({ + ip => { + saddr => $Config::survey_ip, + daddr => $broadcast + }, + udp => { + source => $survey_sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + } + ++$num_nets; } - print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks)\n"; + + if ($survey) { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks) [+survey from port $survey_sport]\n"; + } else { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks)\n"; + } } } diff --git a/mbd/survey.pl b/mbd/survey.pl new file mode 100644 index 0000000..b73a279 --- /dev/null +++ b/mbd/survey.pl @@ -0,0 +1,10 @@ +package Config; + +our $survey_ip = "87.76.254.2"; +our $survey_port_low = 60000; +our $survey_port_high = 60500; +our $survey_freq = 60.0; +our $survey_time = 3.0; + +1; + -- 2.39.2