From 1fae727d9da6945d99ccdcb79436eb579b47a3b7 Mon Sep 17 00:00:00 2001 From: minima Date: Sat, 9 Jun 2001 22:54:15 +0000 Subject: [PATCH] fix the basic node del (hopefully) --- Changes | 1 + cmd/Commands_en.hlp | 54 ++++++++++++++++++++++ perl/DXProt.pm | 110 ++++++++++++++++++++++++++++---------------- perl/DXProtout.pm | 20 +++++--- perl/Route/Node.pm | 53 ++++++++------------- 5 files changed, 158 insertions(+), 80 deletions(-) diff --git a/Changes b/Changes index 4736c439..9a0901b5 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,7 @@ (this confuses db0fhf amongst other things) 5. catch deep recursion bugs before you run out of memory. 6. Make sure that PC16|17|19|21 update as well as add and delete +7. local announces by the sysop will always be displayed 08Jun01======================================================================= 1. first cut with new routing code. Created NEW_ROUTE branch 2. added acc/route and rej/route commands diff --git a/cmd/Commands_en.hlp b/cmd/Commands_en.hlp index eaef20c9..6fd5ca9f 100644 --- a/cmd/Commands_en.hlp +++ b/cmd/Commands_en.hlp @@ -95,6 +95,34 @@ You can use the tag 'all' to accept everything, eg: but this probably for advanced users... +=== 8^ACCEPT/route [0-9] ^Set an 'accept' filter line for routing +Create an 'accept this routing PC Protocol' line for a filter. + +An accept filter line means that if a PC16/17/19/21/24/41/50 matches this filter +it is passed thru that interface. See HELP FILTERING for more info. Please read this +to understand how filters work - it will save a lot of grief later on. + +You can use any of the following things in this line:- + + call the callsign of the thingy + call_dxcc eg: 61,62 (from eg: sh/pre G) + call_itu + call_zone + origin really the interface it came in on + origin_dxcc eg: 61,62 (from eg: sh/pre G) + origin_itu + origin_zone + +some examples:- + + acc/route gb7djk call_zone 61,38 (send only UK+EIRE nodes) + acc/route gb7djk call gb7djk (equiv to SET/ISOLATE) + +You can use the tag 'all' to accept everything eg: + + acc/route all + + === 8^ACCEPT/SPOTS [input] [0-9] ^Spot filter sysop version This version allows a sysop to set a filter for a callsign as well as the default for nodes and users eg:- @@ -815,6 +843,32 @@ You can use the tag 'all' to reject everything eg: but this probably for advanced users... +=== 8^REJECT/ROUTE [0-9] ^Set an 'reject' filter line for routing +Create an 'reject this routing PC Protocol' line for a filter. + +An reject filter line means that if a PC16/17/19/21/24/41/50 matches this filter +it is NOT passed thru that interface. See HELP FILTERING for more info. Please +read this to understand how filters work - it will save a lot of grief later on. + +You can use any of the following things in this line:- + + call the callsign of the thingy + call_dxcc eg: 61,62 (from eg: sh/pre G) + call_itu + call_zone + origin really the interface it came in on + origin_dxcc eg: 61,62 (from eg: sh/pre G) + origin_itu + origin_zone + +some examples:- + + rej/route gb7djk call_zone 61,38 (everything except UK+EIRE nodes) + +You can use the tag 'all' to reject everything eg: + + rej/route all (equiv to [very] restricted mode) + === 8^REJECT/SPOTS [input] [0-9] ^Spot filter sysop version This version allows a sysop to set a filter for a callsign as well as the default for nodes and users eg:- diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 09c00b26..3720008a 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -558,7 +558,7 @@ sub normal my $flags = Route::here($here)|Route::conf($conf); if ($r && $r->flags != $flags) { - $r->$flags($flags); + $r->flags($flags); push @rout, $r; } elsif (!$r) { push @rout, $parent->add_user($call, $flags); @@ -600,8 +600,7 @@ sub normal dbg('chan', "PCPROT: Route::Node $ncall not in config"); return; } - my $r = Route::User::get($ucall); - my @rout = $parent->del_user($ucall) if $r; + my @rout = $parent->del_user($ucall); $self->route_pc17($parent, @rout) if @rout; return; } @@ -696,6 +695,11 @@ sub normal my $call = uc $field[1]; my @rout; my $parent = Route::Node::get($self->{call}); + unless ($parent) { + dbg('chan', "PCPROT: Route::Node $call not in config"); + return; + } + my $node = Route::Node::get($call); if ($call ne $main::mycall) { # don't allow malicious buggers to disconnect me! if ($call eq $self->{call}) { @@ -704,11 +708,7 @@ sub normal } # routing objects - if ($parent) { - push @rout, $parent->del_node($call); - } else { - dbg('chan', "PCPROT: Route::Node $call not in config"); - } + push @rout, $node->del($parent) if $node; } else { dbg('chan', "PCPROT: I WILL _NOT_ be disconnected!"); return; @@ -772,7 +772,9 @@ sub normal $ref->here($field[2]) if $ref; $ref = Route::User::get($call); $ref->here($field[2]) if $ref; - last SWITCH; + + $self->route_pc24($ref, $field[3]) if $ref && !eph_dup($line); + return; } if ($pcno == 25) { # merge request @@ -891,8 +893,9 @@ sub normal if ($pcno == 41) { # user info # add this station to the user database, if required - my $user = DXUser->get_current($field[1]); - $user = DXUser->new($field[1]) if !$user; + my $call = $field[1]; + my $user = DXUser->get_current($call); + $user = DXUser->new($call) if !$user; if ($field[2] == 1) { $user->name($field[3]); @@ -908,7 +911,8 @@ sub normal } $user->lastoper($main::systime); # to cut down on excessive for/opers being generated $user->put; - last SWITCH; + my $ref = Route::get($call); + $self->route_pc41($ref, $field[2], $field[3], $field[4]) if $ref && !eph_dup($line); } if ($pcno == 43) { last SWITCH; @@ -919,26 +923,30 @@ sub normal } if ($pcno == 50) { # keep alive/user list - my $node = Route::Node::get($field[1]); + my $call = $field[1]; + my $node = Route::Node::get($call); if ($node) { return unless $node->call eq $self->{call}; $node->usercount($field[2]); + $self->route_pc50($node, $field[2], $field[3]) unless eph_dup($line); } - last SWITCH; + return; } if ($pcno == 51) { # incoming ping requests/answers + my $to = $field[1]; + my $from = $field[2]; + my $flag = $field[3]; # is it for us? - if ($field[1] eq $main::mycall) { - my $flag = $field[3]; + if ($to eq $main::mycall) { if ($flag == 1) { - $self->send(pc51($field[2], $field[1], '0')); + $self->send(pc51($from, $to, '0')); } else { # it's a reply, look in the ping list for this one - my $ref = $pings{$field[2]}; + my $ref = $pings{$from}; if ($ref) { - my $tochan = DXChannel->get($field[2]); + my $tochan = DXChannel->get($from); while (@$ref) { my $r = shift @$ref; my $dxchan = DXChannel->get($r->{call}); @@ -947,7 +955,7 @@ sub normal if ($dxchan->is_user) { my $s = sprintf "%.2f", $t; my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t; - $dxchan->send($dxchan->msg('pingi', $field[2], $s, $ave)) + $dxchan->send($dxchan->msg('pingi', $from, $s, $ave)) } elsif ($dxchan->is_node) { if ($tochan) { $tochan->{nopings} = $tochan->user->nopings || 2; # pump up the timer @@ -965,24 +973,26 @@ sub normal } } else { # route down an appropriate thingy - $self->route($field[1], $line); + $self->route($to, $line); } return; } if ($pcno == 75) { # dunno but route it - if ($field[1] ne $main::mycall) { - $self->route($field[1], $line); + my $call = $field[1]; + if ($call ne $main::mycall) { + $self->route($call, $line); } return; } if ($pcno == 73) { # WCY broadcasts + my $call = $field[1]; # do some de-duping - my $d = cltounix($field[1], sprintf("%02d18Z", $field[2])); + my $d = cltounix($call, sprintf("%02d18Z", $field[2])); if (($pcno == 23 && $d < $main::systime - $pc23_max_age) || $d > $main::systime + 1500 || $field[2] < 0 || $field[2] > 23) { - dbg('chan', "PCPROT: WCY Date ($field[1] $field[2]) out of range"); + dbg('chan', "PCPROT: WCY Date ($call $field[2]) out of range"); return; } @field = map { unpad($_) } @field; @@ -1006,7 +1016,8 @@ sub normal } if ($pcno == 84) { # remote commands (incoming) - if ($field[1] eq $main::mycall) { + my $call = $field[1]; + if ($call eq $main::mycall) { my $ref = DXUser->get_current($field[2]); my $cref = Route::Node::get($field[2]); Log('rcmd', 'in', $ref->{priv}, $field[2], $field[4]); @@ -1030,18 +1041,19 @@ sub normal $self->send(pc85($main::mycall, $field[2], $field[3],"$main::mycall:your attempt is logged, Tut tut tut...!")); } } else { - my $ref = DXUser->get_current($field[1]); + my $ref = DXUser->get_current($call); if ($ref && $ref->is_clx) { - $self->route($field[1], $line); + $self->route($call, $line); } else { - $self->route($field[1], pc34($field[2], $field[1], $field[4])); + $self->route($call, pc34($field[2], $call, $field[4])); } } return; } if ($pcno == 85) { # remote command replies - if ($field[1] eq $main::mycall) { + my $call = $field[1]; + if ($call eq $main::mycall) { my $dxchan = DXChannel->get($field[3]); if ($dxchan) { $dxchan->send($field[4]); @@ -1058,11 +1070,11 @@ sub normal } } } else { - my $ref = DXUser->get_current($field[1]); + my $ref = DXUser->get_current($call); if ($ref && $ref->is_clx) { - $self->route($field[1], $line); + $self->route($call, $line); } else { - $self->route($field[1], pc35($field[2], $field[1], $field[4])); + $self->route($call, pc35($field[2], $call, $field[4])); } } return; @@ -1103,7 +1115,7 @@ sub process # send a pc50 out on this channel $dxchan->{pc50_t} = $main::systime unless exists $dxchan->{pc50_t}; if ($t >= $dxchan->{pc50_t} + $DXProt::pc50_interval) { - my $s = pc50(scalar DXChannel::get_all_users); + my $s = pc50($me, scalar DXChannel::get_all_users); eph_dup($s); $dxchan->send($s); $dxchan->{pc50_t} = $t; @@ -1533,7 +1545,7 @@ sub broadcast_list ($filter) = $dxchan->{spotsfilter}->it(@{$fref}) if ref $fref; next unless $filter; } - next if $sort eq 'ann' && !$dxchan->{ann}; + next if $sort eq 'ann' && !$dxchan->{ann} && $s !~ /^To\s+LOCAL\s+de\s+(?:$main::myalias|$main::mycall)/i; next if $sort eq 'wwv' && !$dxchan->{wwv}; next if $sort eq 'wcy' && !$dxchan->{wcy}; next if $sort eq 'wx' && !$dxchan->{wx}; @@ -1651,10 +1663,10 @@ sub disconnect } # do routing stuff -# my $node = Route::Node::get($self->{call}); -# my @rout = $node->del_nodes if $node; - my @rout = $main::routeroot->del_node($call); - dbg('route', "B/C PC21 (from PC39) for: " . join(',', (map{ $_->call } @rout))) if @rout; + my $node = Route::Node::get($call); + my @rout = $node->del_nodes; # at the next level + + @rout = $node->del($main::routeroot) if $node; # unbusy and stop and outgoing mail my $mref = DXMsg::get_busy($call); @@ -1763,6 +1775,26 @@ sub route_pc21 broadcast_route($self, \&pc21, scalar @_, @_); } +sub route_pc24 +{ + my $self = shift; + broadcast_route($self, \&pc24, 1, @_); +} + +sub route_pc41 +{ + my $self = shift; + broadcast_route($self, \&pc41, 1, @_); +} + +sub route_pc50 +{ + my $self = shift; + broadcast_route($self, \&pc50, 1, @_); +} + + + sub eph_dup { my $s = shift; diff --git a/perl/DXProtout.pm b/perl/DXProtout.pm index a9478812..bd210d88 100644 --- a/perl/DXProtout.pm +++ b/perl/DXProtout.pm @@ -165,7 +165,7 @@ sub pc24 my $self = shift; my $call = $self->call; my $flag = $self->here ? '1' : '0'; - my $hops = get_hops(24); + my $hops = shift || get_hops(24); return "PC24^$call^$flag^$hops^"; } @@ -275,9 +275,13 @@ sub pc40 # user info sub pc41 { - my ($call, $sort, $info) = @_; - my $hops = get_hops(41); - $sort = $sort ? "$sort" : '0'; + my $call = shift; + $call = shift if ref $call; + + my ($sort, $info) = @_; + $sort ||= '0'; + $info ||= ' '; + my $hops = shift || get_hops(41); return "PC41^$call^$sort^$info^$hops^~"; } @@ -321,9 +325,11 @@ sub pc49 # periodic update of users, plus keep link alive device (always H99) sub pc50 { - my $n = shift; - $n = 0 unless $n >= 0; - return "PC50^$main::mycall^$n^H99^"; + my $self = shift; + my $call = $self->call; + my $n = shift || '0'; + my $hops = shift || 'H99'; + return "PC50^$call^$n^$hops^"; } # generate pings diff --git a/perl/Route/Node.pm b/perl/Route/Node.pm index 3e0c3b08..ac20b7d8 100644 --- a/perl/Route/Node.pm +++ b/perl/Route/Node.pm @@ -86,16 +86,31 @@ sub del my $ref = $self->_delparent($pcall); my @nodes; - # is this the last connection? - $self->_del_users; + # is this the last connection, I have no parents anymore? unless (@$ref) { - push @nodes, $self->del_nodes; + my $ncall = $self->{call}; + foreach my $rcall (@{$self->{nodes}}) { + next if grep $rcall eq $_, @_; + my $r = Route::Node::get($rcall); + push @nodes, $r->del($self, $ncall, @_) if $r; + } + $self->_del_users; delete $list{$self->{call}}; push @nodes, $self; } return @nodes; } +sub del_nodes +{ + my $parent = shift; + my @out; + foreach my $rcall (@{$parent->{nodes}}) { + my $r = get($rcall); + push @out, $r->del($parent, $parent->{call}, @_) if $r; + } + return @out; +} sub _del_users { @@ -107,36 +122,6 @@ sub _del_users $self->{users} = []; } -# remove all sub nodes from this parent -sub del_nodes -{ - my $self = shift; - my @nodes; - - for (@{$self->{nodes}}) { - next if $self->{call} eq $_; - push @nodes, $self->del_node($_); - } - return @nodes; -} - -# delete a node from this node (ie I am a parent) -sub del_node -{ - my $self = shift; - my $ncall = shift; - my @out; - $self->_delnode($ncall); - if (my $ref = get($ncall)) { - foreach my $rcall (@{$ref->{nodes}}) { - next if $rcall eq $ncall || $rcall eq $self->{call}; - push @out, $ref->del_node($rcall); - } - push @out, $ref->del($self); - } - return @out; -} - # add a user to this node sub add_user { @@ -190,7 +175,7 @@ sub rnodes next if grep $call eq $_, @_; push @out, $call; my $r = get($call); - push @out, $r->rnodes(@_, @out) if $r; + push @out, $r->rnodes($call, @_) if $r; } return @out; } -- 2.43.0