From 9a31104f31ce5d80a659dea3de9dbf9a5d46ef8e Mon Sep 17 00:00:00 2001 From: minima Date: Tue, 6 Jul 2004 18:07:18 +0000 Subject: [PATCH] more wip and a nearly working basic thing --- perl/DXCommandmode.pm | 8 +++-- perl/DXProt.pm | 57 +++++++++++++++++++------------- perl/Route.pm | 6 ++-- perl/Route/Node.pm | 77 ++++++++++++++++++++++++++++++++++++------- perl/Route/User.pm | 2 +- perl/cluster.pl | 27 ++++----------- 6 files changed, 118 insertions(+), 59 deletions(-) diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm index aa6f743d..7025f683 100644 --- a/perl/DXCommandmode.pm +++ b/perl/DXCommandmode.pm @@ -64,11 +64,13 @@ sub new # routing, this must go out here to prevent race condx my $pkg = shift; my $call = shift; - my @rout = $main::routeroot->add_user($call, Route::here(1)); + my $uref = Route::User::get($call) || Route::User->new($call); + $uref->here(1); + $uref->conf(0); + $main::routeroot->add_user($uref); # ALWAYS output the user - my $ref = Route::User::get($call); - $main::me->route_pc16($main::mycall, undef, $main::routeroot, $ref) if $ref; + $main::me->route_pc16($main::mycall, undef, $main::routeroot, $uref); return $self; } diff --git a/perl/DXProt.pm b/perl/DXProt.pm index e2722165..51bdc8ef 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -199,6 +199,19 @@ sub init { do "$main::data/hop_table.pl" if -e "$main::data/hop_table.pl"; confess $@ if $@; + + my $user = DXUser->get($main::mycall); + $DXProt::myprot_version += $main::version*100; + $main::me = DXProt->SUPER::alloc($main::mycall, 0, $user); + $main::me->{here} = 1; + $main::me->{state} = "indifferent"; + $main::me->{sort} = 'S'; # S for spider + $main::me->{priv} = 9; + $main::me->{metric} = 0; + $main::me->{pingave} = 0; + $main::me->{registered} = 1; + $main::me->{version} = $main::version; + $main::me->{build} = $main::build; } # @@ -212,8 +225,12 @@ sub new # add this node to the table, the values get filled in later my $pkg = shift; my $call = shift; - $main::routeroot->add($call, '5000', Route::here(1)) if $call ne $main::mycall; + my $uref = Route::Node::get($call) || Route::Node->new($call); + $uref->here(1); + $uref->conf(0); + $uref->version(5000); + $main::routeroot->link_node($uref, $self); return $self; } @@ -1402,6 +1419,7 @@ sub handle_59 # now do it properly for actions my $node = Route::Node::get($ncall) || Route::Node::new($ncall); + $node->newroute(1); # find each of the entries (or create new ones) my @refs; @@ -1454,7 +1472,7 @@ sub handle_59 next; } $ref->here($ehere); # might as well set this here - $ref->lastheard($main::systime); + $ref->lastseen($main::systime); push @refs, $ref; } @@ -1519,7 +1537,6 @@ sub handle_59 push @adduser, $node->add_user($_) for @au; } - $self->route_pc21($origin, $line, @delnode) if @delnode; $self->route_pc19($origin, $line, @addnode) if @addnode; $self->route_pc17($origin, $line, @deluser) if @deluser; @@ -1957,7 +1974,7 @@ sub send_local_config if ($self->{newroute}) { my @nodes = $self->{isolate} ? ($main::routeroot) : grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} } DXChannel::get_all_nodes(); my @users = DXChannel::get_all_users(); - $self->send_route($main::mycall, \&pc59c, @nodes+@users+1, (grep { Route::get($_) } $main::routeroot, @nodes, @users)); + $self->send_route($main::mycall, \&pc59, @nodes+@users+4, 'C', 0, $main::mycall, (grep { Route::get($_) } $main::routeroot, @nodes, @users)); } else { # send our nodes if ($self->{isolate}) { @@ -2219,29 +2236,23 @@ sub disconnect # do routing stuff, remove me from routing table my $node = Route::Node::get($call); my @rout; + my @rusers; if ($node) { - @rout = $node->del($main::routeroot); + + # remove the route from this node and return a list + # of nodes that have become orphanned as a result. + push @rout, $main::routeroot->remove_route($node, $self); + + # remove all consequently orphanned users from these nodes + push @rusers, $_->unlink_all_users for @rout; - # and all my ephemera as well + # remove all my ephemera as well for (@rout) { my $c = $_->call; eph_del_regex("^PC1[679].*$c"); } } - # remove them from the pc19list as well - while (my ($k,$v) = each %pc19list) { - my @l = grep {$_->[0] ne $call} @{$pc19list{$k}}; - if (@l) { - $pc19list{$k} = \@l; - } else { - delete $pc19list{$k}; - } - - # and the ephemera - eph_del_regex("^PC1[679].*$k"); - } - # unbusy and stop and outgoing mail my $mref = DXMsg::get_busy($call); $mref->stop_msg($call) if $mref; @@ -2249,8 +2260,12 @@ sub disconnect # 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_pc59('D', 0, $main::mycall, $node); } + # delete all the unwanted nodes + $_->delete for @rout, @rusers; + # remove outstanding pings delete $pings{$call}; @@ -2297,7 +2312,6 @@ sub send_route # deal with non routing parameters unless (ref $r && $r->isa('Route')) { push @rin, $r; - $no++; next; } @@ -2419,8 +2433,7 @@ sub route_pc59 my $origin = shift; my $line = shift; - # @_ - 2 because we start with [ACD], hexstamp - broadcast_route($self, $origin, \&pc59, $line, scalar @_ - 2, @_); + broadcast_route($self, $origin, \&pc59, $line, scalar @_, @_); } sub in_filter_route diff --git a/perl/Route.pm b/perl/Route.pm index 388aed2e..45bd7213 100644 --- a/perl/Route.pm +++ b/perl/Route.pm @@ -152,7 +152,8 @@ sub here my $r = shift; return $self ? 2 : 0 unless ref $self; return ($self->{flags} & 2) ? 1 : 0 unless defined $r; - $self->{flags} = (($self->{flags} & ~2) | ($r ? 2 : 0)); + $self->{flags} &= ~2; + $self->{flags} |= $r ? 2 : 0; return $r ? 1 : 0; } @@ -162,7 +163,8 @@ sub conf my $r = shift; return $self ? 1 : 0 unless ref $self; return ($self->{flags} & 1) ? 1 : 0 unless defined $r; - $self->{flags} = (($self->{flags} & ~1) | ($r ? 1 : 0)); + $self->{flags} &= ~1; + $self->{flags} |= $r ? 1 : 0; return $r ? 1 : 0; } diff --git a/perl/Route/Node.pm b/perl/Route/Node.pm index 38e7f3e4..6f8de6de 100644 --- a/perl/Route/Node.pm +++ b/perl/Route/Node.pm @@ -29,6 +29,7 @@ use vars qw(%list %valid @ISA $max $filterdef); users => '0,Users,parray', usercount => '0,User Count', version => '0,Version', + newroute => '0,New Routing?,yesno', ); $filterdef = $Route::filterdef; @@ -58,12 +59,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 +76,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($self); + if ($o) { + dbg("Orphanning $_->{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 +144,20 @@ 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) = @_; + return $self->_dellist('dxchan', $dxchan); +} + sub usercount { my $self = shift; @@ -128,10 +182,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 @@ -143,11 +199,10 @@ sub new my $self = $pkg->SUPER::new($call); $self->{dxchan} = ref $pkg ? [ $pkg->{call} ] : [ ]; - $self->{version} = shift; - $self->{flags} = shift; + $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'); diff --git a/perl/Route/User.pm b/perl/Route/User.pm index ebccba9b..b8d5fb36 100644 --- a/perl/Route/User.pm +++ b/perl/Route/User.pm @@ -48,7 +48,7 @@ sub new my $pkg = shift; my $call = uc shift; my $ncall = uc shift; - my $flags = shift; + my $flags = shift || Route::here(1); confess "already have $call in $pkg" if $list{$call}; my $self = $pkg->SUPER::new($call); diff --git a/perl/cluster.pl b/perl/cluster.pl index 68f40e1a..8f5070ce 100755 --- a/perl/cluster.pl +++ b/perl/cluster.pl @@ -68,7 +68,6 @@ use DXCommandmode; use DXProtVars; use DXProtout; use DXProt; -use QXProt; use DXMsg; use DXCron; use DXConnect; @@ -195,22 +194,7 @@ sub new_channel # create the channel - if ($user->wantnp) { - if ($user->passphrase && $main::me->user->passphrase) { - $dxchan = QXProt->new($call, $conn, $user); - } else { - unless ($user->passphrase) { - Log('DXCommand', "$call using NP but has no passphrase"); - dbg("$call using NP but has no passphrase"); - } - unless ($main::me->user->passphrase) { - Log('DXCommand', "$main::mycall using NP but has no passphrase"); - dbg("$main::mycall using NP but has no passphrase"); - } - already_conn($conn, $call, "Need to exchange passphrases"); - return; - } - } elsif ($user->is_node) { + if ($user->is_node) { $dxchan = DXProt->new($call, $conn, $user); } elsif ($user->is_user) { $dxchan = DXCommandmode->new($call, $conn, $user); @@ -498,10 +482,14 @@ Spot->init(); # initialise the protocol engine dbg("Start Protocol Engines ..."); DXProt->init(); -QXProt->init(); # put in a DXCluster node for us here so we can add users and take them away -$routeroot = Route::Node->new($mycall, $version*100+5300, Route::here($main::me->here)|Route::conf($main::me->conf)); +$routeroot = Route::Node->new($mycall); +$routeroot->version($version*100+5300); +$routeroot->here($main::me->here || 1); +$routeroot->conf($main::me->conf || 0); +$routeroot->add_dxchan($me); +$routeroot->lastseen(time); # make sure that there is a routing OUTPUT node default file #unless (Filter::read_in('route', 'node_default', 0)) { @@ -552,7 +540,6 @@ for (;;) { DXCron::process(); # do cron jobs DXCommandmode::process(); # process ongoing command mode stuff DXProt::process(); # process ongoing ak1a pcxx stuff - QXProt::process(); DXConnect::process(); DXMsg::process(); DXDb::process(); -- 2.34.1