X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FRoute%2FNode.pm;h=0880622ea538c9739fe1bb958f95d8cec45bc450;hb=07f2e6cff3523ababee9c42008568cb469befe9d;hp=38e7f3e4b246f4b2008966412b6be2cff1e82b5f;hpb=05a7fdd4a58c51e21b55b0509b054b625839290c;p=spider.git diff --git a/perl/Route/Node.pm b/perl/Route/Node.pm index 38e7f3e4..0880622e 100644 --- a/perl/Route/Node.pm +++ b/perl/Route/Node.pm @@ -25,10 +25,12 @@ use vars qw(%list %valid @ISA $max $filterdef); %valid = ( dxchan => '0,DXChannel List,parray', - nodes => '0,Nodes,parray', - users => '0,Users,parray', + nodes => '0,Node List,parray', + users => '0,User List,parray', usercount => '0,User Count', version => '0,Version', + newroute => '0,New Routing?,yesno', + pingtime => '0,Ping Time', ); $filterdef = $Route::filterdef; @@ -58,12 +60,11 @@ sub link_node { my ($self, $neighbour, $dxchan) = @_; - my $r = $self->is_empty('dxchan'); + my $r = $neighbour->is_empty('dxchan'); $self->_addlist('nodes', $neighbour); $neighbour->_addlist('nodes', $self); - $self->_addlist('dxchan', $dxchan); $neighbour->_addlist('dxchan', $dxchan); - return $r ? ($self) : (); + return $r ? ($neighbour) : (); } # unlink a node from a neighbour and remove any @@ -76,9 +77,49 @@ sub unlink_node my ($self, $neighbour, $dxchan) = @_; $self->_dellist('nodes', $neighbour); $neighbour->_dellist('nodes', $self); - $self->_dellist('dxchan', $dxchan); - $neighbour->_dellist('dxchan', $dxchan); - return $self->is_empty('dxchan') ? ($self) : (); + $neighbour->_dellist('dxchan', $dxchan) if $dxchan; + return $neighbour->is_empty('dxchan') ? ($neighbour) : (); +} + +sub remove_route +{ + my ($self, $neighbour, $dxchan) = @_; + + # cut the dxchan link + # cut the node link + my @rout; + push @rout, $self->unlink_node($neighbour, $dxchan); + dbg("Orphanning $neighbour->{call}") if isdbg('routelow'); + + # then run down the tree removing this dxchan link from + # all the referenced nodes that use this interface + my %visited; + my @in = map { Route::Node::get($_) } $neighbour->nodes; + foreach my $r (@in) { + next unless $r; + next if $visited{$r->call}; + my ($o) = $r->del_dxchan($dxchan); + if ($o) { + dbg("Orphanning $o->{call}") if isdbg('routelow'); + push @rout, $o; + } + push @in, map{ Route::Node::get($_) } $r->nodes; + $visited{$r->call} = $r; + } + + # in @rout there should be a list of orphaned (in dxchan terms) + # nodes. Now go thru and make sure that all their links are + # broken (they should be, but this is to check). + + foreach my $r (@rout) { + my @nodes = map { Route::Node::get($_)} $r->nodes; + for (@nodes) { + next unless $_; + dbg("Orphaned node $_->{call}: breaking link to $_->{call}") if isdbg('routelow'); + $r->unlink_node($_); + } + } + return @rout; } # add a user to this node @@ -104,6 +145,21 @@ sub del_user return $uref->is_empty('nodes') ? ($uref) : (); } +# add a single dxchan link +sub add_dxchan +{ + my ($self, $dxchan) = @_; + return $self->_addlist('dxchan', $dxchan); +} + +# remove a single dxchan link +sub del_dxchan +{ + my ($self, $dxchan) = @_; + $self->_dellist('dxchan', $dxchan); + return $self->is_empty('dxchan') ? ($self) : (); +} + sub usercount { my $self = shift; @@ -128,10 +184,12 @@ sub nodes sub unlink_all_users { my $self = shift; - foreach my $u (${$self->{nodes}}) { + my @rout; + foreach my $u (@{$self->{users}}) { my $uref = Route::User::get($u); - $self->unlink_user($uref) if $uref; + push @rout, $self->del_user($uref) if $uref; } + return @rout; } sub new @@ -142,12 +200,11 @@ sub new confess "already have $call in $pkg" if $list{$call}; my $self = $pkg->SUPER::new($call); - $self->{dxchan} = ref $pkg ? [ $pkg->{call} ] : [ ]; - $self->{version} = shift; - $self->{flags} = shift; + $self->{dxchan} = [ ]; + $self->{version} = shift || 5000; + $self->{flags} = shift || Route::here(1); $self->{users} = []; $self->{nodes} = []; - $self->{lid} = 0; $list{$call} = $self; dbg("creating Route::Node $self->{call}") if isdbg('routelow'); @@ -158,7 +215,10 @@ sub new sub delete { my $self = shift; - dbg("deleting Route::Node $self->{call}") if isdbg('routelow'); + dbg("Deleting Route::Node $self->{call}") if isdbg('routelow'); + for ($self->unlink_all_users) { + $_->delete; + } delete $list{$self->{call}}; }