change node disconnection code to improve node clearouts
authorDirk Koopman <djk@tobit.co.uk>
Thu, 12 Jul 2007 14:54:04 +0000 (15:54 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Thu, 12 Jul 2007 14:54:04 +0000 (15:54 +0100)
Changes
cmd/show/node.pl
perl/DXProt.pm
perl/DXProtHandle.pm
perl/Route.pm
perl/Route/Node.pm
perl/Version.pm

diff --git a/Changes b/Changes
index 760164bef6b8ebaeb758fea29c613e3d270b39df..d1d688c8e211a4adafb84f44dc0bc35f487e7dc7 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,6 @@
+12Jul07=======================================================================
+1. Change disconnection code so that nodes that are no longer routable are
+(all) cleared out.
 11Jul07=======================================================================
 1. improve speed of sh/c/n
 2. remove all $Id$ strings from cmd tree
index a1ab8eca18136b25070ca697901d0a3def9c98b7..4e8125514c48a73dddc7d683e246304490151641 100644 (file)
@@ -23,7 +23,9 @@ my @out;
 my $count;
 
 # search thru the user for nodes
-if ($call[0] eq 'ALL') {
+if (@call == 0) {
+       @call = map {$_->call} DXChannel::get_all_nodes();
+} elsif ($call[0] eq 'ALL') {
        shift @call;
        my ($action, $key, $data) = (0,0,0);
        for ($action = DXUser::R_FIRST, $count = 0; !$DXUser::dbm->seq($key, $data, $action); $action = DXUser::R_NEXT) {
@@ -31,9 +33,7 @@ if ($call[0] eq 'ALL') {
                    push @call, $key;
                        ++$count;
                }
-       } 
-} elsif (@call == 0) {
-       @call = map {$_->call} DXChannel::get_all_nodes();  
+       }
 }
 
 my $call;
index af28b19244877fabde913352b2da767bbb51ceac..ea41c08317e98bb1477d7ecaa6213b01c7bc7140 100644 (file)
@@ -1144,16 +1144,6 @@ sub disconnect
 
        # do routing stuff, remove me from routing table
        my $node = Route::Node::get($call);
-       my @rout;
-       if ($node) {
-               @rout = $node->del($main::routeroot);
-
-               # and all my ephemera as well
-               for (@rout) {
-                       my $c = $_->call;
-                       eph_del_regex("^PC1[679].*$c");
-               }
-       }
 
        RouteDB::delete_interface($call);
 
@@ -1161,12 +1151,6 @@ sub disconnect
        my $mref = DXMsg::get_busy($call);
        $mref->stop_msg($call) if $mref;
 
-       # broadcast to all other nodes that all the nodes connected to via me are gone
-       unless ($pc39flag && $pc39flag == 2)  {
-               $self->route_pc21($main::mycall, undef, @rout) if @rout;
-               $self->route_pc92d($main::mycall, undef, $main::routeroot, $node) if $node;
-       }
-
        # remove outstanding pings
        delete $pings{$call};
 
@@ -1179,6 +1163,43 @@ sub disconnect
        Log('DXProt', $call . " Disconnected");
 
        $self->SUPER::disconnect;
+
+       # here we determine what needs to go out of the routing table
+       my @rout;
+       if ($node) {
+               dbg('%Route::Node::List = ' . join(',', sort keys %Route::Node::list)) if isdbg('routedisc');
+
+               @rout = $node->del($main::routeroot);
+
+               dbg('@rout = ' . join(',', sort map {$_->call} @rout)) if isdbg('routedisc');
+
+               # now we need to see what can't be routed anymore and came
+               # in via this node (probably).
+               my $n = 0;
+               while ($n != @rout) {
+                       $n = @rout;
+                       for (Route::Node::get_all()) {
+                               unless ($_->dxchan) {
+                                       push @rout, $_->delete;
+                               }
+                       }
+                       dbg('@rout = ' . join(',', sort map {$_->call} @rout)) if isdbg('routedisc');
+               }
+
+               dbg('%Route::Node::List = ' . join(',', sort keys %Route::Node::list)) if isdbg('routedisc');
+
+               # and all my ephemera as well
+               for (@rout) {
+                       my $c = $_->call;
+                       eph_del_regex("^PC1[679].*$c");
+               }
+       }
+
+       # broadcast to all other nodes that all the nodes connected to via me are gone
+       unless ($pc39flag && $pc39flag == 2)  {
+               $self->route_pc21($main::mycall, undef, @rout) if @rout;
+               $self->route_pc92d($main::mycall, undef, $main::routeroot, $node) if $node;
+       }
 }
 
 
index e2e8e983998a75f2b137a313f9b043af65714a25..eacd9225d7ca197a9c0acf4b3accbd9968574d35 100644 (file)
@@ -1430,7 +1430,7 @@ sub check_pc9x_t
        } elsif ($create) {
                $parent = Route::Node->new($call);
        }
-       $parent->lastid->{$pc} = $t;
+       $parent->lastid->{$pc} = $t if $parent;
 
        return $parent;
 }
@@ -1526,6 +1526,9 @@ sub handle_92
                }
        } elsif ($sort eq 'A' || $sort eq 'D' || $sort eq 'C') {
 
+               # remember the last channel we arrived on
+               $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
+
                # this is the main route section
                # here is where all the routes are created and destroyed
 
@@ -1570,6 +1573,7 @@ sub handle_92
                                                }
                                                $parent = check_pc9x_t($call, $t, 92) || return;
                                                $parent->via_pc92(1);
+                                               $parent->PC92C_dxchan($self->{call});
                                        }
                                } else {
                                        dbg("PCPROT: must be mycall or external node as first entry, ignored") if isdbg('chanerr');
@@ -1578,6 +1582,7 @@ sub handle_92
                                $parent->here(Route::here($here));
                                $parent->version($version) if $version && $version > $parent->version;
                                $parent->build($build) if $build && $build > $parent->build;
+                               $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
                                shift @ent;
                        }
                }
@@ -1606,11 +1611,9 @@ sub handle_92
 
                        # we only reset obscounts on config records
                        $oparent->reset_obs;
-                       $oparent->PC92C_dxchan($self->{call}) unless $self->{call} eq $oparent->call;
                        dbg("ROUTE: reset obscount on $pcall now " . $oparent->obscount) if isdbg('obscount');
                        if ($oparent != $parent) {
                                $parent->reset_obs;
-                               $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
                                dbg("ROUTE: reset obscount on $parent->{call} now " . $parent->obscount) if isdbg('obscount');
                        }
 
index 51fceff5928a7b58b8232cb60043b8a904ce2f47..290cd7628f10823e61611398bf48a8b95de9ba2c 100644 (file)
@@ -305,6 +305,7 @@ sub findroutes
 
        # deal with more nodes
        my $nref = Route::get($call);
+       return () unless $nref;
        foreach my $ncall (@{$nref->{parent}}) {
                unless ($seen->{$ncall}) {
                        dbg("recursing from $call -> $ncall") if isdbg('routec');
index 3fa7a09750402ec49db1e5c7d3f28745478519cd..d2105f8f6b6bcf57aea77391344f243c7af3681e 100644 (file)
@@ -107,23 +107,35 @@ sub del
                        push @nodes, $r->del($self, $ncall, @_) if $r;
                }
                $self->_del_users;
-               delete $list{$self->{call}};
+               delete $list{$ncall};
                push @nodes, $self;
        }
        return @nodes;
 }
 
 # this deletes this node completely by grabbing the parents
-# and deleting me from them
+# and deleting me from them, then deleting me from all the
+# dependent nodes.
 sub delete
 {
        my $self = shift;
        my @out;
+       my $ncall = $self->{call};
 
+       # get rid of users and parents
        $self->_del_users;
-       foreach my $call (@{$self->{parent}}) {
-               my $parent = Route::Node::get($call);
-               push @out, $parent->del($self) if $parent;
+       if (@{$self->{parent}}) {
+               foreach my $call (@{$self->{parent}}) {
+                       my $parent = Route::Node::get($call);
+                       push @out, $parent->del($self) if $parent;
+               }
+       }
+       # get rid of my nodes
+       push @out, $self->del_nodes;
+       # this only happens if we a orphan with no parents
+       if ($list{$ncall}) {
+               push @out, $self;
+               delete $list{$ncall};
        }
        return @out;
 }
@@ -275,6 +287,7 @@ sub new
        $self->{users} = [];
        $self->{nodes} = [];
        $self->{lastid} = {};
+       $self->{PC92C_dxchan} = '';
        $self->reset_obs;                       # by definition
 
        $list{$call} = $self;
index 353fc11aa00c68ff8fa85a510885d4b260ec4561..280eb1d1c84afb93912cab99ac3f125c3b41173e 100644 (file)
@@ -11,6 +11,6 @@ use vars qw($version $subversion $build);
 
 $version = '1.54';
 $subversion = '0';
-$build = '115';
+$build = '116';
 
 1;