From ba799b8ac9feef688cff478a4006399b6dfc183f Mon Sep 17 00:00:00 2001 From: Dirk Koopman Date: Thu, 26 Jun 2008 20:25:21 +0100 Subject: [PATCH] send talks to every node a user is logged in to If a user is on more than one node, a talk will be sent to each of those nodes. Before it would only go to the first node in the routing table. --- perl/DXProtHandle.pm | 75 +++++++++++++++++++++++++++----------------- perl/Route.pm | 20 +++++++----- perl/Version.pm | 2 +- 3 files changed, 59 insertions(+), 38 deletions(-) diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index 166d5643..e19688bb 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -1836,6 +1836,42 @@ sub handle_92 $self->broadcast_route_pc9x($pcall, undef, $line, 0); } +# get all the routes for a thing, bearing in mind that the thing (e.g. a user) +# might be on two or more nodes at the same time or that there may be more than +# one equal distance neighbour to a node. +# +# What this means that if sh/route g1tlh shows that he is on (say) two nodes, then +# a Route::findroutes is done on each of those two nodes, the best route(s) taken from +# each and then combined to give a set of dxchans to send the PC9x record down +# +sub find_pc9x_routes +{ + my $to = shift; + my $ref = Route::get($to); + my @parent; + my %cand; + + if ($ref->isa('Route::User')) { + my $dxchan = DXChannel::get($to); + push @parent, $to if $dxchan; + push @parent, @{$ref->parent}; + } else { + @parent = $to; + } + foreach my $p (@parent) { + my $lasthops; + my @routes = Route::findroutes($p); + foreach my $r (@routes) { + $lasthops = $r->[0] unless defined $lasthops; + if ($r->[0] == $lasthops) { + $cand{$r->[1]->call} = $r->[1]; + } else { + last; + } + } + } + return values %cand; +} sub handle_93 { @@ -1896,45 +1932,26 @@ sub handle_93 # if it is routeable then then treat it like a talk my $ref = Route::get($to); if ($ref) { - # local talks my $dxchan; - $dxchan = DXChannel::get($main::myalias) if $to eq $main::mycall; - $dxchan = DXChannel::get($to) unless $dxchan; - # check it... - if ($dxchan) { - if (ref $dxchan && $dxchan->isa('DXChannel')) { - if ($dxchan->is_user) { - $dxchan->talk($from, $to, $via, $text, $onode); - return; - } - } else { - dbg("ERROR: $to -> $dxchan is not a DXChannel! (local talk)"); - } - } - # convert to PC10 talks where appropriate + # convert to PC10 or local talks where appropriate # PC93 capable nodes of the same hop count all get a copy # if there is a PC10 node then it will get a copy and that # will be it. Hopefully such a node will not figure highly # in the route list, unless it is local, 'cos it don't issue PC92s! - my @routes = Route::findroutes($to); + # note that both local and PC93s at the same time are possible if the + # user on more than one node. + my @routes = find_pc9x_routes($to); my $lasthops; - foreach my $r (@routes) { - $lasthops = $r->[0] unless defined $lasthops; - if ($r->[0] == $lasthops) { - $dxchan = $r->[1]; - if (ref $dxchan && $dxchan->isa('DXChannel')) { - if ($dxchan->{do_pc9x}) { - $dxchan->send($line); - } else { - $dxchan->talk($from, $to, $via, $text, $onode); - last; - } + foreach $dxchan (@routes) { + if (ref $dxchan && $dxchan->isa('DXChannel')) { + if ($dxchan->{do_pc9x}) { + $dxchan->send($line); } else { - dbg("ERROR: $to -> $dxchan is not a DXChannel! (convert to pc10)"); + $dxchan->talk($from, $to, $via, $text, $onode); } } else { - last; + dbg("ERROR: $to -> $dxchan is not a DXChannel! (convert to pc10)"); } } return; diff --git a/perl/Route.pm b/perl/Route.pm index 3c1c453e..eb83af11 100644 --- a/perl/Route.pm +++ b/perl/Route.pm @@ -289,29 +289,33 @@ sub get sub findroutes { my $call = shift; + my %cand; my @out; dbg("ROUTE: findroutes $call") if isdbg('findroutes'); - # return immediately if we are directly connected + my $nref = Route::get($call); + return () unless $nref; + + # we are directly connected, force "best possible" priority, but + # carry on in case user is connected on other nodes. my $dxchan = DXChannel::get($call); if ($dxchan) { dbg("ROUTE: findroutes $call -> directly connected") if isdbg('findroutes'); - return [99, $dxchan]; + $cand{$call} = 99; } - my $nref = Route::get($call); - return () unless $nref; - # obtain the dxchannels that have seen this thingy my @parent = $nref->isa('Route::User') ? @{$nref->{parent}} : $call; - my %cand; foreach my $p (@parent) { - # return immediately if we are directly connected or a user's parent node is + next if $p eq $main::mycall; # this is dealt with above + + # deal with directly connected nodes, again "best priority" $dxchan = DXChannel::get($p); if ($dxchan) { dbg("ROUTE: findroutes $call -> connected direct via parent $p") if isdbg('findroutes'); - return [99, $dxchan]; + $cand{$p} = 99; + next; } my $r = Route::Node::get($p); diff --git a/perl/Version.pm b/perl/Version.pm index 2a1927aa..96e37485 100644 --- a/perl/Version.pm +++ b/perl/Version.pm @@ -11,6 +11,6 @@ use vars qw($version $subversion $build); $version = '1.55'; $subversion = '0'; -$build = '22'; +$build = '23'; 1; -- 2.34.1