X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProt.pm;h=966f0eefb0d88f4a5f4d7d8a105329542deef3df;hb=3e075e9d00d74fd477c44db2b29eb3eac9d6d88a;hp=5407bb1bd24f96d60affc55ff8975a8b39753cdc;hpb=0063cd3ba6d514ae92a6aaf22472e509eabf7e43;p=spider.git diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 5407bb1b..966f0eef 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -275,10 +275,8 @@ sub normal # print join(',', @field), "\n"; - # ignore any lines that don't start with PC - return if !$field[0] =~ /^PC/; - # process PC frames + # process PC frames, this will fail unless the frame starts PCnn my ($pcno) = $field[0] =~ /^PC(\d\d)/; # just get the number return unless $pcno; return if $pcno < 10 || $pcno > 99; @@ -286,7 +284,7 @@ sub normal # check for and dump bad protocol messages my $n = check($pcno, @field); if ($n) { - dbg('chan', "PCPROT: bad field $n, dumped (" . parray($checklist[$pcno-10]) . ")"); + dbg("PCPROT: bad field $n, dumped (" . parray($checklist[$pcno-10]) . ")") if isdbg('chanerr'); return; } @@ -295,7 +293,7 @@ sub normal eval { $pcr = Local::pcprot($self, $pcno, @field); }; -# dbg('local', "Local::pcprot error $@") if $@; +# dbg("Local::pcprot error $@") if isdbg('local') if $@; return if $pcr; SWITCH: { @@ -305,7 +303,7 @@ sub normal if ($censorpc) { my @bad; if (@bad = BadWords::check($field[3])) { - dbg('chan', "PCPROT: Bad words: @bad, dropped" ); + dbg("PCPROT: Bad words: @bad, dropped") if isdbg('chanerr'); return; } } @@ -318,7 +316,8 @@ sub normal } else { $call = $to = $field[2]; } - $dxchan = DXChannel->get($call); + $dxchan = DXChannel->get($main::myalias) if $call eq $main::mycall; + $dxchan = DXChannel->get($call) unless $dxchan; if ($dxchan && $dxchan->is_user) { $field[3] =~ s/\%5E/^/g; $dxchan->talk($field[1], $to, $via, $field[3]); @@ -340,13 +339,13 @@ sub normal # if this is a 'nodx' node then ignore it if ($badnode->in($field[7])) { - dbg('chan', "PCPROT: Bad Node, dropped"); + dbg("PCPROT: Bad Node, dropped") if isdbg('chanerr'); return; } # if this is a 'bad spotter' user then ignore it if ($badspotter->in($field[6])) { - dbg('chan', "PCPROT: Bad Spotter, dropped"); + dbg("PCPROT: Bad Spotter, dropped") if isdbg('chanerr'); return; } @@ -354,13 +353,13 @@ sub normal my $d = cltounix($field[3], $field[4]); # bang out (and don't pass on) if date is invalid or the spot is too old (or too young) if (!$d || ($pcno == 11 && ($d < $main::systime - $pc11_max_age || $d > $main::systime + 900))) { - dbg('chan', "PCPROT: Spot ignored, invalid date or out of range ($field[3] $field[4])\n"); + dbg("PCPROT: Spot ignored, invalid date or out of range ($field[3] $field[4])\n") if isdbg('chanerr'); return; } # is it 'baddx' if ($baddx->in($field[2])) { - dbg('chan', "PCPROT: Bad DX spot, ignored"); + dbg("PCPROT: Bad DX spot, ignored") if isdbg('chanerr'); return; } @@ -368,17 +367,17 @@ sub normal $field[5] =~ s/^\s+//; # take any leading blanks off $field[2] = unpad($field[2]); # take off leading and trailing blanks from spotted callsign if ($field[2] =~ /BUST\w*$/) { - dbg('chan', "PCPROT: useless 'BUSTED' spot"); + dbg("PCPROT: useless 'BUSTED' spot") if isdbg('chanerr'); return; } if (Spot::dup($field[1], $field[2], $d, $field[5])) { - dbg('chan', "PCPROT: Duplicate Spot ignored\n"); + dbg("PCPROT: Duplicate Spot ignored\n") if isdbg('chanerr'); return; } if ($censorpc) { my @bad; if (@bad = BadWords::check($field[5])) { - dbg('chan', "PCPROT: Bad words: @bad, dropped" ); + dbg("PCPROT: Bad words: @bad, dropped") if isdbg('chanerr'); return; } } @@ -388,7 +387,7 @@ sub normal if ($self->{inspotsfilter}) { my ($filter, $hops) = $self->{inspotsfilter}->it(@spot); unless ($filter) { - dbg('chan', "PCPROT: Rejected by filter"); + dbg("PCPROT: Rejected by input spot filter") if isdbg('chanerr'); return; } } @@ -423,7 +422,7 @@ sub normal my $node; my $to = $user->homenode; my $last = $user->lastoper || 0; - if ($send_opernam && $main::systime > $last + $DXUser::lastoperinterval && $to && ($node = Route::Node::get($to)) ) { + if ($to ne $main::mycall && $send_opernam && $main::systime > $last + $DXUser::lastoperinterval && $to && ($node = Route::Node::get($to)) ) { my $cmd = "forward/opernam $spot[4]"; # send the rcmd but we aren't interested in the replies... my $dxchan = $node->dxchan; @@ -455,7 +454,7 @@ sub normal eval { $r = Local::spot($self, @spot); }; -# dbg('local', "Local::spot1 error $@") if $@; +# dbg("Local::spot1 error $@") if isdbg('local') if $@; return if $r; # DON'T be silly and send on PC26s! @@ -470,14 +469,14 @@ sub normal # announce duplicate checking $field[3] =~ s/^\s+//; # remove leading blanks if (AnnTalk::dup($field[1], $field[2], $field[3])) { - dbg('chan', "PCPROT: Duplicate Announce ignored"); + dbg("PCPROT: Duplicate Announce ignored") if isdbg('chanerr'); return; } if ($censorpc) { my @bad; if (@bad = BadWords::check($field[3])) { - dbg('chan', "PCPROT: Bad words: @bad, dropped" ); + dbg("PCPROT: Bad words: @bad, dropped") if isdbg('chanerr'); return; } } @@ -502,7 +501,7 @@ sub normal my ($filter, $hops) = $self->{inannfilter}->it(@field[1..6], $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq); unless ($filter) { - dbg('chan', "PCPROT: Rejected by filter"); + dbg("PCPROT: Rejected by input announce filter") if isdbg('chanerr'); return; } } @@ -534,33 +533,42 @@ sub normal my $newline = "PC16^"; if ($ncall eq $main::mycall) { - dbg('chan', "PCPROT: trying to alter config on this node from outside!"); + dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr'); return; } $dxchan = DXChannel->get($ncall); if ($dxchan && $dxchan ne $self) { - dbg('chan', "PCPROT: PC16 from $self->{call} trying to alter locally connected $ncall, ignored!"); + dbg("PCPROT: PC16 from $self->{call} trying to alter locally connected $ncall, ignored!") if isdbg('chanerr'); return; } my $parent = Route::Node::get($ncall); unless ($parent) { - dbg('chan', "PCPROT: Node $ncall not in config"); + dbg("PCPROT: Node $ncall not in config") if isdbg('chanerr'); return; } + + # input filter if required + return unless $self->in_filter_route($parent); + my $i; my @rout; for ($i = 2; $i < $#field; $i++) { my ($call, $conf, $here) = $field[$i] =~ /^(\S+) (\S) (\d)/o; next unless $call && $conf && defined $here && is_callsign($call); + next if $call eq $main::mycall; + $conf = $conf eq '*'; my $r = Route::User::get($call); my $flags = Route::here($here)|Route::conf($conf); - if ($r && $r->flags != $flags) { - $r->flags($flags); - push @rout, $r; - } elsif (!$r) { + if ($r) { + if ($r->flags != $flags) { + $r->flags($flags); + push @rout, $r; + } + $r->addparent($ncall); + } else { push @rout, $parent->add_user($call, $flags); } @@ -587,19 +595,23 @@ sub normal my $ncall = $field[2]; my $ucall = $field[1]; if ($ncall eq $main::mycall) { - dbg('chan', "PCPROT: trying to alter config on this node from outside!"); + dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr'); return; } $dxchan = DXChannel->get($ncall); if ($dxchan && $dxchan ne $self) { - dbg('chan', "PCPROT: PC17 from $self->{call} trying to alter locally connected $ncall, ignored!"); + dbg("PCPROT: PC17 from $self->{call} trying to alter locally connected $ncall, ignored!") if isdbg('chanerr'); return; } my $parent = Route::Node::get($ncall); unless ($parent) { - dbg('chan', "PCPROT: Route::Node $ncall not in config"); + dbg("PCPROT: Route::Node $ncall not in config") if isdbg('chanerr'); return; } + + # input filter if required + return unless $self->in_filter_route($parent); + my @rout = $parent->del_user($ucall); $self->route_pc17($parent, @rout) if @rout; return; @@ -610,11 +622,7 @@ sub normal # first clear out any nodes on this dxchannel my $parent = Route::Node::get($self->{call}); - my @rout; - for ($parent->nodes) { - my $r = Route::Node::get($_); - push @rout, $r->del_node if $r; - } + my @rout = $parent->del_nodes; $self->route_pc21(@rout, $parent); $self->send_local_config(); $self->send(pc20()); @@ -628,6 +636,11 @@ sub normal # new routing list my @rout; my $parent = Route::Node::get($self->{call}); + unless ($parent) { + dbg("DXPROT: my parent $self->{call} has disappeared"); + $self->disconnect; + return; + } # parse the PC19 for ($i = 1; $i < $#field-1; $i += 4) { @@ -640,25 +653,38 @@ sub normal $ver = 5000 if $ver eq '0000'; next if $ver < 5000; # only works with version 5 software next if length $call < 3; # min 3 letter callsigns + next if $call eq $main::mycall; # update it if required - my $r; + my $r = Route::Node::get($call); my $flags = Route::here($here)|Route::conf($conf); - if ($parent->call eq $call && ($parent->version ne $ver || $parent->flags != $flags)) { - $parent->version($ver); - $parent->flags($flags); - push @rout, $parent; - } elsif ($parent->call ne $call) { - next if $call eq $main::mycall || $call eq $self->{call}; - - my $r = $parent->add($call, $ver, Route::here($here)|Route::conf($conf)); - push @rout, $r if $r; - } else { - $r = Route::Node::get($call); - if ($r && ($r->version ne $ver || $r->flags != $flags)) { + if ($r) { + my $ar; + if ($call ne $parent->call) { + if ($self->in_filter_route($r)) { + $ar = $parent->add($call, $ver, $flags); + push @rout, $ar if $ar; + } else { + next; + } + } + if ($r->version ne $ver || $r->flags != $flags) { $r->version($ver); - $r->flags(Route::here($here)|Route::conf($conf)); + $r->flags($flags); + push @rout, $r unless $ar; + } + } else { + if ($call eq $self->{call}) { + dbg("DXPROT: my channel route for $call has disappeared"); + next; + }; + + my $new = Route->new($call); # throw away + if ($self->in_filter_route($new)) { + my $r = $parent->add($call, $ver, $flags); push @rout, $r; + } else { + next; } } @@ -696,21 +722,26 @@ sub normal my @rout; my $parent = Route::Node::get($self->{call}); unless ($parent) { - dbg('chan', "PCPROT: Route::Node $call not in config"); + dbg("DXPROT: my parent $self->{call} has disappeared"); + $self->disconnect; 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}) { - dbg('chan', "PCPROT: Trying to disconnect myself with PC21"); + dbg("PCPROT: Trying to disconnect myself with PC21") if isdbg('chanerr'); return; } - # routing objects - push @rout, $node->del($parent) if $node; + if ($node) { + # input filter it + return unless $self->in_filter_route($node); + + # routing objects + push @rout, $node->del($parent); + } } else { - dbg('chan', "PCPROT: I WILL _NOT_ be disconnected!"); + dbg("PCPROT: I WILL _NOT_ be disconnected!") if isdbg('chanerr'); return; } $self->route_pc21(@rout) if @rout; @@ -740,11 +771,11 @@ sub normal my ($r) = $field[6] =~ /R=(\d+)/; $r = 0 unless $r; if (($pcno == 23 && $d < $main::systime - $pc23_max_age) || $d > $main::systime + 1500 || $field[2] < 0 || $field[2] > 23) { - dbg('chan', "PCPROT: WWV Date ($field[1] $field[2]) out of range"); + dbg("PCPROT: WWV Date ($field[1] $field[2]) out of range") if isdbg('chanerr'); return; } if (Geomag::dup($d,$sfi,$k,$i,$field[6])) { - dbg('chan', "PCPROT: Dup WWV Spot ignored\n"); + dbg("PCPROT: Dup WWV Spot ignored\n") if isdbg('chanerr'); return; } $field[7] =~ s/-\d+$//o; # remove spotter's ssid @@ -755,7 +786,7 @@ sub normal eval { $rep = Local::wwv($self, $field[1], $field[2], $sfi, $k, $i, @field[6..8], $r); }; -# dbg('local', "Local::wwv2 error $@") if $@; +# dbg("Local::wwv2 error $@") if isdbg('local') if $@; return if $rep; # DON'T be silly and send on PC27s! @@ -768,12 +799,18 @@ sub normal if ($pcno == 24) { # set here status my $call = uc $field[1]; - my $ref = Route::Node::get($call); - $ref->here($field[2]) if $ref; - $ref = Route::User::get($call); - $ref->here($field[2]) if $ref; + my ($nref, $uref); + $nref = Route::Node::get($call); + $uref = Route::User::get($call); + return unless $nref || $uref; # if we don't know where they are, it's pointless sending it on - $self->route_pc24($ref, $field[3]) if $ref && !eph_dup($line); + unless (eph_dup($line)) { + $nref->here($field[2]) if $nref; + $uref->here($field[2]) if $uref; + my $ref = $nref || $uref; + return unless $self->in_filter_route($ref); + $self->route_pc24($ref, $field[3]); + } return; } @@ -783,7 +820,7 @@ sub normal return; } if ($field[2] eq $main::mycall) { - dbg('chan', "PCPROT: Trying to merge to myself, ignored"); + dbg("PCPROT: Trying to merge to myself, ignored") if isdbg('chanerr'); return; } @@ -886,7 +923,7 @@ sub normal if ($field[1] eq $self->{call}) { $self->disconnect(1); } else { - dbg('chan', "PCPROT: came in on wrong channel"); + dbg("PCPROT: came in on wrong channel") if isdbg('chanerr'); } return; } @@ -911,12 +948,19 @@ sub normal } $user->lastoper($main::systime); # to cut down on excessive for/opers being generated $user->put; - my $ref = Route::get($call); - $self->route_pc41($ref, $field[2], $field[3], $field[4]) if $ref && !eph_dup($line); + my $ref = Route::get($call) || Route->new($call); + + # input filter if required + return unless $self->in_filter_route($ref); + + $self->route_pc41($ref, $call, $field[2], $field[3], $field[4]) if $ref && !eph_dup($line); + return; } + if ($pcno == 43) { last SWITCH; } + if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47 || $pcno == 48) { DXDb::process($self, $line); return; @@ -928,6 +972,10 @@ sub normal if ($node) { return unless $node->call eq $self->{call}; $node->usercount($field[2]); + + # input filter if required + return unless $self->in_filter_route($node); + $self->route_pc50($node, $field[2], $field[3]) unless eph_dup($line); } return; @@ -992,12 +1040,12 @@ sub normal # do some de-duping 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 ($call $field[2]) out of range"); + dbg("PCPROT: WCY Date ($call $field[2]) out of range") if isdbg('chanerr'); return; } @field = map { unpad($_) } @field; if (WCY::dup($d,@field[3..7])) { - dbg('chan', "PCPROT: Dup WCY Spot ignored\n"); + dbg("PCPROT: Dup WCY Spot ignored\n") if isdbg('chanerr'); return; } @@ -1007,7 +1055,7 @@ sub normal eval { $rep = Local::wwv($self, @field[1..12]); }; - # dbg('local', "Local::wcy error $@") if $@; + # dbg("Local::wcy error $@") if isdbg('local') if $@; return if $rep; # broadcast to the eager world @@ -1090,7 +1138,7 @@ sub normal # if (eph_dup($line)) { - dbg('chan', "PCPROT: Ephemeral dup, dropped"); + dbg("PCPROT: Ephemeral dup, dropped") if isdbg('chanerr'); } else { unless ($self->{isolate}) { broadcast_ak1a($line, $self); # send it to everyone but me @@ -1166,41 +1214,45 @@ sub send_dx_spot # taking into account filtering and so on foreach $dxchan (@dxchan) { next if $dxchan == $me; - my $routeit; - my ($filter, $hops); + next if $dxchan == $self; + $dxchan->dx_spot($line, $self->{isolate}, @_, $self->{call}); + } +} - if ($dxchan->{spotsfilter}) { - ($filter, $hops) = $dxchan->{spotsfilter}->it(@_, $self->{call} ); - next unless $filter; - } - - if ($dxchan->is_node) { - next if $dxchan == $self; - if ($hops) { - $routeit = $line; - $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; - } else { - $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name - next unless $routeit; - } - if ($filter) { - $dxchan->send($routeit) if $routeit; - } else { - $dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate}; - } - } elsif ($dxchan->is_user && $dxchan->{dx}) { - my $buf = Spot::formatb($dxchan->{user}->wantgrid, $_[0], $_[1], $_[2], $_[3], $_[4]); - $buf .= "\a\a" if $dxchan->{beep}; - $buf =~ s/\%5E/^/g; - if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') { - $dxchan->send($buf); - } else { - $dxchan->delay($buf); - } - } +sub dx_spot +{ + my $self = shift; + my $line = shift; + my $isolate = shift; + my ($filter, $hops); + + if ($self->{spotsfilter}) { + ($filter, $hops) = $self->{spotsfilter}->it(@_); + return unless $filter; + } + send_prot_line($self, $filter, $hops, $isolate, $line) +} + +sub send_prot_line +{ + my ($self, $filter, $hops, $isolate, $line) = @_; + my $routeit; + + if ($hops) { + $routeit = $line; + $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; + } else { + $routeit = adjust_hops($self, $line); # adjust its hop count by node name + next unless $routeit; + } + if ($filter) { + $self->send($routeit) if $routeit; + } else { + $self->send($routeit) unless $self->{isolate} || $isolate; } } + sub send_wwv_spot { my $self = shift; @@ -1229,34 +1281,23 @@ sub send_wwv_spot my $routeit; my ($filter, $hops); - if ($dxchan->{wwvfilter}) { - ($filter, $hops) = $dxchan->{wwvfilter}->it(@_, $self->{call}, $wwv_dxcc, $wwv_itu, $wwv_cq, $org_dxcc, $org_itu, $org_cq); - next unless $filter; - } - if ($dxchan->is_node) { - if ($hops) { - $routeit = $line; - $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; - } else { - $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name - next unless $routeit; - } - if ($filter) { - $dxchan->send($routeit) if $routeit; - } else { - $dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate}; - - } - } elsif ($dxchan->is_user && $dxchan->{wwv}) { - my $buf = "WWV de $_[6] <$_[1]>: SFI=$_[2], A=$_[3], K=$_[4], $_[5]"; - $buf .= "\a\a" if $dxchan->{beep}; - if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') { - $dxchan->send($buf); - } else { - $dxchan->delay($buf); - } - } + $dxchan->wwv($line, $self->{isolate}, @_, $self->{call}, $wwv_dxcc, $wwv_itu, $wwv_cq, $org_dxcc, $org_itu, $org_cq); } + +} + +sub wwv +{ + my $self = shift; + my $line = shift; + my $isolate = shift; + my ($filter, $hops); + + if ($self->{wwvfilter}) { + ($filter, $hops) = $self->{wwvfilter}->it(@_); + return unless $filter; + } + send_prot_line($self, $filter, $hops, $isolate, $line) } sub send_wcy_spot @@ -1283,36 +1324,24 @@ sub send_wcy_spot # taking into account filtering and so on foreach $dxchan (@dxchan) { next if $dxchan == $me; - my $routeit; - my ($filter, $hops); + next if $dxchan == $self; - if ($dxchan->{wcyfilter}) { - ($filter, $hops) = $dxchan->{wcyfilter}->it(@_, $self->{call}, $wcy_dxcc, $wcy_itu, $wcy_cq, $org_dxcc, $org_itu, $org_cq); - next unless $filter; - } - if ($dxchan->is_clx || $dxchan->is_spider || $dxchan->is_dxnet) { - if ($hops) { - $routeit = $line; - $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; - } else { - $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name - next unless $routeit; - } - if ($filter) { - $dxchan->send($routeit) if $routeit; - } else { - $dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate}; - } - } elsif ($dxchan->is_user && $dxchan->{wcy}) { - my $buf = "WCY de $_[10] <$_[1]> : K=$_[4] expK=$_[5] A=$_[3] R=$_[6] SFI=$_[2] SA=$_[7] GMF=$_[8] Au=$_[9]"; - $buf .= "\a\a" if $dxchan->{beep}; - if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') { - $dxchan->send($buf); - } else { - $dxchan->delay($buf); - } - } + $dxchan->wcy($line, $self->{isolate}, @_, $self->{call}, $wcy_dxcc, $wcy_itu, $wcy_cq, $org_dxcc, $org_itu, $org_cq); + } +} + +sub wcy +{ + my $self = shift; + my $line = shift; + my $isolate = shift; + my ($filter, $hops); + + if ($self->{wcyfilter}) { + ($filter, $hops) = $self->{wcyfilter}->it(@_); + return unless $filter; } + send_prot_line($self, $filter, $hops, $isolate, $line) if $self->is_clx || $self->is_spider || $self->is_dxnet; } # send an announce @@ -1322,9 +1351,9 @@ sub send_announce my $line = shift; my @dxchan = DXChannel->get_all(); my $dxchan; - my $text = unpad($_[2]); my $target; my $to = 'To '; + my $text = unpad($_[2]); if ($_[3] eq '*') { # sysops $target = "SYSOP"; @@ -1364,41 +1393,27 @@ sub send_announce my $routeit; my ($filter, $hops); - if ($dxchan->{annfilter}) { - ($filter, $hops) = $dxchan->{annfilter}->it(@_, $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq); - next unless $filter; - } - if ($dxchan->is_node && $_[1] ne $main::mycall) { # i.e not specifically routed to me - if ($hops) { - $routeit = $line; - $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; - } else { - $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name - next unless $routeit; - } - if ($filter) { - $dxchan->send($routeit) if $routeit; - } else { - $dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate}; - - } - } elsif ($dxchan->is_user) { - unless ($dxchan->{ann}) { - next if $_[0] ne $main::myalias && $_[0] ne $main::mycall; - } - next if $target eq 'SYSOP' && $dxchan->{priv} < 5; - my $buf = "$to$target de $_[0]: $text"; - $buf =~ s/\%5E/^/g; - $buf .= "\a\a" if $dxchan->{beep}; - if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') { - $dxchan->send($buf); - } else { - $dxchan->delay($buf); - } - } + $dxchan->announce($line, $self->{isolate}, $to, $target, $text, @_, $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq) + } +} + +sub announce +{ + my $self = shift; + my $line = shift; + my $isolate = shift; + my $to = shift; + my $target = shift; + my ($filter, $hops); + + if ($self->{annfilter}) { + ($filter, $hops) = $self->{annfilter}->it(@_); + return unless $filter; } + send_prot_line($self, $filter, $hops, $isolate, $line) unless $_[1] eq $main::mycall; } + sub send_local_config { my $self = shift; @@ -1407,7 +1422,7 @@ sub send_local_config my @localnodes; my @remotenodes; - dbg('trace', 'DXProt::send_local_config'); + dbg('DXProt::send_local_config') if isdbg('trace'); # send our nodes if ($self->{isolate}) { @@ -1417,7 +1432,7 @@ sub send_local_config # and are not themselves isolated, this to make sure that isolated nodes # don't appear outside of this node my @dxchan = grep { $_->call ne $main::mycall && $_->call ne $self->{call} } DXChannel::get_all_nodes(); - @localnodes = map { Route::Node::get($_->{call}) or die "connot find node $_->{call}" } @dxchan if @dxchan; + @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan if @dxchan; my @intcalls = map { $_->nodes } @localnodes if @localnodes; my $ref = Route::Node::get($self->{call}); my @rnodes = $ref->nodes; @@ -1434,7 +1449,7 @@ sub send_local_config if ($n) { send_route($self, \&pc16, 1, $n, map {my $r = Route::User::get($_); $r ? ($r) : ()} $n->users); } else { - dbg('chan', "sent a null value"); + dbg("sent a null value") if isdbg('chanerr'); } } } @@ -1449,18 +1464,18 @@ sub route my ($self, $call, $line) = @_; if (ref $self && $call eq $self->{call}) { - dbg('chan', "PCPROT: Trying to route back to source, dropped"); + dbg("PCPROT: Trying to route back to source, dropped") if isdbg('chanerr'); return; } # always send it down the local interface if available my $dxchan = DXChannel->get($call); unless ($dxchan) { - my $cl = Route::Node::get($call); + my $cl = Route::get($call); $dxchan = $cl->dxchan if $cl; if (ref $dxchan) { if (ref $self && $dxchan eq $self) { - dbg('chan', "PCPROT: Trying to route back to source, dropped"); + dbg("PCPROT: Trying to route back to source, dropped") if isdbg('chanerr'); return; } } @@ -1468,10 +1483,10 @@ sub route if ($dxchan) { my $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name if ($routeit) { - $dxchan->send($routeit); + $dxchan->send($routeit) unless $dxchan == $me; } } else { - dbg('chan', "PCPROT: No route available, dropped"); + dbg("PCPROT: No route available, dropped") if isdbg('chanerr'); } } @@ -1646,10 +1661,10 @@ sub addrcmd $r->{t} = $main::systime; $r->{cmd} = $cmd; $rcmds{$to} = $r; - + my $ref = Route::Node::get($to); my $dxchan = $ref->dxchan; - if ($dxchan && $dxchan->is_clx) { + if ($dxchan && $dxchan->is_clx) { route(undef, $to, pc84($main::mycall, $to, $self->{call}, $cmd)); } else { route(undef, $to, pc34($main::mycall, $to, $cmd)); @@ -1721,15 +1736,23 @@ sub send_route my ($filter, $hops); my @rin; - if ($self->{routefilter}) { - for (; @_ && $no; $no--) { - my $r = shift; + for (; @_ && $no; $no--) { + my $r = shift; + + if ($self->{routefilter}) { + $filter = undef; if ($r) { ($filter, $hops) = $self->{routefilter}->it($self->{call}, $self->{dxcc}, $self->{itu}, $self->{cq}, $r->call, $r->dxcc, $r->itu, $r->cq); - push @rin, $r if $filter; + if ($filter) { + push @rin, $r; + } else { + dbg("DXPROT: $self->{call}/" . $r->call . " rejected by output filter") if isdbg('chanerr'); + } } else { - dbg('chan', "was sent a null value"); + dbg("was sent a null value") if isdbg('chanerr'); } + } else { + push @rin, $r; } } if (@rin) { @@ -1741,7 +1764,7 @@ sub send_route $routeit = adjust_hops($self, $line); # adjust its hop count by node name next unless $routeit; } - $self->send($routeit); + $self->send($routeit) if $self->{routefilter} || !$self->{isolate}; } } } @@ -1757,7 +1780,11 @@ sub broadcast_route foreach $dxchan (@dxchan) { next if $dxchan == $self; next if $dxchan == $me; - $dxchan->send_route($generate, @_); + if ($dxchan->{routefilter} || !$self->{isolate}) { + $dxchan->send_route($generate, @_) + } else { + dbg('DXPROT: isolated') if isdbg('chanerr'); + } } } @@ -1803,7 +1830,18 @@ sub route_pc50 broadcast_route($self, \&pc50, 1, @_); } - +sub in_filter_route +{ + my $self = shift; + my $r = shift; + my ($filter, $hops) = (1, 1); + + if ($self->{inroutefilter}) { + ($filter, $hops) = $self->{inroutefilter}->it($self->{call}, $self->{dxcc}, $self->{itu}, $self->{cq}, $r->call, $r->dxcc, $r->itu, $r->cq); + dbg("PCPROT: $self->{call}/" . $r->call . ' rejected by in_filter_route') if !$filter && isdbg('chanerr'); + } + return $filter; +} sub eph_dup {