From: minima Date: Mon, 7 Mar 2005 14:36:18 +0000 (+0000) Subject: start ping work X-Git-Tag: R_1_52~123 X-Git-Url: http://dxcluster.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=57740a288c82793988be72c9b5666087d636344f;p=spider.git start ping work --- diff --git a/perl/Aranea.pm b/perl/Aranea.pm index 75fcee8e..e31b7984 100644 --- a/perl/Aranea.pm +++ b/perl/Aranea.pm @@ -247,7 +247,7 @@ sub disconnect DXProt::route_pc21($self, $main::mycall, undef, @rout) if @rout; # remove outstanding pings -# delete $pings{$call}; + Thingy::Ping::forget($call); # I was the last node visited $self->user->node($main::mycall); diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm index 753f59f7..9b3b09e3 100644 --- a/perl/DXCommandmode.pm +++ b/perl/DXCommandmode.pm @@ -559,6 +559,9 @@ sub disconnect # send info to all logged in thingies $self->tell_login('logoutu'); + # remove any outstanding pings I have sent + Thingy::Ping::forget($call); + Log('DXCommand', "$call disconnected"); $self->SUPER::disconnect; diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 1d28e402..78c39f16 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -1540,70 +1540,16 @@ sub handle_51 my $pcno = shift; my $line = shift; my $origin = shift; - my $to = $_[1]; - my $from = $_[2]; - my $flag = $_[3]; - - # is it for us? - if ($to eq $main::mycall) { - if ($flag == 1) { - $self->send(pc51($from, $to, '0')); - } else { - # it's a reply, look in the ping list for this one - my $ref = $pings{$from}; - if ($ref) { - my $tochan = DXChannel::get($from); - while (@$ref) { - my $r = shift @$ref; - my $dxchan = DXChannel::get($r->{call}); - next unless $dxchan; - my $t = tv_interval($r->{t}, [ gettimeofday ]); - if ($dxchan->is_user) { - my $s = sprintf "%.2f", $t; - my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t; - $dxchan->send($dxchan->msg('pingi', $from, $s, $ave)) - } elsif ($dxchan->is_node) { - if ($tochan) { - my $nopings = $tochan->user->nopings || $obscount; - push @{$tochan->{pingtime}}, $t; - shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6; - - # cope with a missed ping, this means you must set the pingint large enough - if ($t > $tochan->{pingint} && $t < 2 * $tochan->{pingint} ) { - $t -= $tochan->{pingint}; - } - - # calc smoothed RTT a la TCP - if (@{$tochan->{pingtime}} == 1) { - $tochan->{pingave} = $t; - } else { - $tochan->{pingave} = $tochan->{pingave} + (($t - $tochan->{pingave}) / 6); - } - $tochan->{nopings} = $nopings; # pump up the timer - if (my $ivp = Investigate::get($from, $origin)) { - $ivp->handle_ping; - } - } elsif (my $rref = Route::Node::get($r->{call})) { - if (my $ivp = Investigate::get($from, $origin)) { - $ivp->handle_ping; - } - } - } - } - } - } - } else { - - RouteDB::update($from, $origin); - - if (eph_dup($line)) { - dbg("PCPROT: dup PC51 detected") if isdbg('chanerr'); - return; - } - # route down an appropriate thingy - $self->route($to, $line); + if (eph_dup($line)) { + dbg("PCPROT: dup PC51 detected") if isdbg('chanerr'); + return; } + + my $thing = Thingy::Ping->new(origin=>$main::mycall); + $thing->from_DXProt(user=>$_[2], group=>$_[1], out=>$_[3], DXProt=>$line); + $thing->process($self); + } # dunno but route it @@ -2159,22 +2105,9 @@ sub load_hops sub addping { my ($from, $to, $via) = @_; - my $ref = $pings{$to} || []; - my $r = {}; - $r->{call} = $from; - $r->{t} = [ gettimeofday ]; - if ($via && (my $dxchan = DXChannel::get($via))) { - $dxchan->send(pc51($to, $main::mycall, 1)); - } else { - route(undef, $to, pc51($to, $main::mycall, 1)); - } - push @$ref, $r; - $pings{$to} = $ref; - my $u = DXUser->get_current($to); - if ($u) { - $u->lastping(($via || $from), $main::systime); - $u->put; - } + my $thing = Thingy::Ping->new_ping($from eq $main::mycall ? () : (user=>$from), $via ? (touser=> $to, group => $via) : (group => $to)); + $thing->remember; + $thing->broadcast; } sub process_rcmd @@ -2328,7 +2261,7 @@ sub disconnect } # remove outstanding pings - delete $pings{$call}; + Thingy::Ping::forget($call); # I was the last node visited $self->user->node($main::mycall); diff --git a/perl/Thingy.pm b/perl/Thingy.pm index 2361561a..6ab36080 100644 --- a/perl/Thingy.pm +++ b/perl/Thingy.pm @@ -132,10 +132,12 @@ sub queue sub process { my $thing; + if (@_ == 2) { $thing = shift; $thing->queue(shift); } + while (@queue) { $thing = shift @queue; my $dxchan = DXChannel::get($thing->{dxchan}); @@ -205,5 +207,26 @@ sub add_auth $thing->{auth} = $auth->challenge($main::me->user->passphrase); } +# +# create a generalised reply to a passed thing, if it isn't replyable +# to then undef is returned +# +sub new_reply +{ + my $thing = shift; + my $out; + + if ($thing->{group} eq $main::mycall) { + $out = $thing->new; + $out->{touser} = $thing->{user} if $thing->{user}; + } elsif (DXChannel::get($thing->{group})) { + $out = $thing->new(user => $thing->{group}); + $out->{touser} = $thing->{user} if $thing->{user}; + } elsif ($thing->{touser} && DXChannel->{$thing->{touser}}) { + $out = $thing->new(user => $thing->{touser}); + $out->{group} = $thing->{group}; + } + return $out; +} 1; diff --git a/perl/Thingy/Ping.pm b/perl/Thingy/Ping.pm index 6fe808b5..09d0e592 100644 --- a/perl/Thingy/Ping.pm +++ b/perl/Thingy/Ping.pm @@ -20,9 +20,11 @@ use DXUtil; use Thingy; use Spot; -use vars qw(@ISA); +use vars qw(@ISA @ping); @ISA = qw(Thingy); +my $id; + sub gen_Aranea { my $thing = shift; @@ -57,7 +59,8 @@ sub gen_DXCommandmode sub from_DXProt { - my $thing = shift; + my $thing = ref $_[0] ? shift : $thing->SUPER::new(); + while (@_) { my $k = shift; $thing->{$k} = shift; @@ -70,7 +73,128 @@ sub handle my $thing = shift; my $dxchan = shift; - $thing->broadcast($dxchan); + # is it for us? + if ($thing->{group} eq $main::mycall) { + if ($thing->{out} == 1) { + my $repthing; + if ($thing->{touser}) { + if (my $dxchan = DXChannel::get($thing->{touser})) { + if ($dxchan->is_node) { + $thing->send($dxchan); + } else { + $repthing = Thingy::Ping->new_reply($thing); + } + } + } else { + $repthing = Thingy::Ping->new_reply($thing); + } + $repthing->send($dxchan) if $repthing; + } else { + + # it's a reply, look in the ping list for this one + my $ref = $pings{$from}; + if ($ref) { + my $tochan = DXChannel::get($from); + while (@$ref) { + my $r = shift @$ref; + my $dxchan = DXChannel::get($r->{call}); + next unless $dxchan; + my $t = tv_interval($r->{t}, [ gettimeofday ]); + if ($dxchan->is_user) { + my $s = sprintf "%.2f", $t; + my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t; + $dxchan->send($dxchan->msg('pingi', $from, $s, $ave)) + } elsif ($dxchan->is_node) { + if ($tochan) { + my $nopings = $tochan->user->nopings || $obscount; + push @{$tochan->{pingtime}}, $t; + shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6; + + # cope with a missed ping, this means you must set the pingint large enough + if ($t > $tochan->{pingint} && $t < 2 * $tochan->{pingint} ) { + $t -= $tochan->{pingint}; + } + + # calc smoothed RTT a la TCP + if (@{$tochan->{pingtime}} == 1) { + $tochan->{pingave} = $t; + } else { + $tochan->{pingave} = $tochan->{pingave} + (($t - $tochan->{pingave}) / 6); + } + $tochan->{nopings} = $nopings; # pump up the timer + if (my $ivp = Investigate::get($from, $origin)) { + $ivp->handle_ping; + } + } elsif (my $rref = Route::Node::get($r->{call})) { + if (my $ivp = Investigate::get($from, $origin)) { + $ivp->handle_ping; + } + } + } + } + } + } + } else { + $thing->broadcast($dxchan); + } +} + +# this just creates a ping for onward transmission +# remember it if you want to ping someone from here +sub new_ping +{ + my $pkg = shift; + my $thing = $pkg->SUPER::new(@_); } +# do this for pings we generate ourselves +sub remember +{ + my $thing = shift; + $thing->{t} = [ gettimeofday ]; + $thing->{out} = 1; + $thing->{id} = ++$id; + my $u = DXUser->get_current($thing->{to}); + if ($u) { + $u->lastping(($thing->{group} || $thing->{user}), $main::systime); + $u->put; + } + push @ping, $thing; +} + +# remove any pings outstanding that we have remembered for this +# callsign, return the number of forgotten pings +sub forget +{ + my $call = shift; + my $count = 0; + my @out; + for (@ping) { + if ($thing->{user} eq $call) { + $count++; + } else { + push @out, $_; + } + } + @ping = @out; + return $count; +} + +sub find +{ + my $from = shift; + my $to = shift; + my $via = shift; + + for (@ping) { + if ($_->{user} eq $from && $_->{to} eq $to) { + if ($via) { + return $_ if $_->{group} eq $via; + } else { + return $_; + } + } + } + return undef; +} 1;