X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProtHandle.pm;h=add5c521df7a541895a66010c1aa1cb7746df3e3;hb=b7cacf8c291739ffb8630c4d2a275cb9c9074e45;hp=26781885eb318f38292b2a9d1858c6549614ddc1;hpb=db0959118b4c5045e842cf07c399e2924bd6ca10;p=spider.git diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index 26781885..add5c521 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -37,6 +37,9 @@ use RouteDB; use strict; +use vars qw($VERSION $BRANCH); +($VERSION, $BRANCH) = dxver(q$Revision$); + use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restime $eph_pc34_restime $last_hour $last10 %eph %pings %rcmds $ann_to_talk $pingint $obscount %pc19list $chatdupeage $chatimportfn @@ -410,6 +413,7 @@ sub handle_16 dbg("PCPROT: don't send users to $self->{call}") if isdbg('chanerr'); return; } + # is it me? if ($ncall eq $main::mycall) { dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr'); @@ -425,11 +429,6 @@ sub handle_16 return; } - unless ($h) { - dbg("PCPROT: non-local PC16, ignored") if isdbg('chanerr'); - return; - } - my $parent = Route::Node::get($ncall); if ($parent) { @@ -441,6 +440,15 @@ sub handle_16 # input filter if required return unless $self->in_filter_route($parent); + } else { + $parent = Route::Node->new($ncall); + } + + unless ($h) { + if ($parent->via_pc92) { + dbg("PCPROT: non-local node controlled by PC92, ignored") if isdbg('chanerr'); + return; + } } my $i; @@ -471,9 +479,10 @@ sub handle_16 $r->flags($flags); $au = $r; } - push @rout, $r if $au; + push @rout, $r if $h && $au; } else { - push @rout, $parent->add_user($call, $flags); + my @ans = $parent->add_user($call, $flags); + push @rout, @ans if $h && @ans; } # send info to all logged in thingies @@ -490,8 +499,8 @@ sub handle_16 $user->put; } if (@rout) { - $self->route_pc16($origin, $line, $parent, @rout); - $self->route_pc92a($main::mycall, undef, $parent, @rout); + $self->route_pc16($origin, $line, $parent, @rout) if @rout; +# $self->route_pc92a($main::mycall, undef, $parent, @rout) if $h && $self->{state} eq 'normal'; } } @@ -513,6 +522,7 @@ sub handle_17 dbg("PCPROT: don't send users to $self->{call}") if isdbg('chanerr'); return; } + if ($ncall eq $main::mycall) { dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr'); return; @@ -540,6 +550,19 @@ sub handle_17 return; } + $dxchan = DXChannel::get($ncall); + unless ($dxchan) { + if ($parent->via_pc92) { + dbg("PCPROT: non-local node controlled by PC92, ignored") if isdbg('chanerr'); + return; + } + } + + if (DXChannel::get($ucall)) { + dbg("PCPROT: trying do disconnect local user, ignored") if isdbg('chanerr'); + return; + } + # input filter if required and then remove user if present if ($parent) { # return unless $self->in_filter_route($parent); @@ -559,7 +582,7 @@ sub handle_17 $uref = Route->new($ucall) unless $uref; # throw away $self->route_pc17($origin, $line, $parent, $uref); - $self->route_pc92d($main::mycall, undef, $parent, $uref); +# $self->route_pc92d($main::mycall, undef, $parent, $uref) if $dxchan; } # link request @@ -583,7 +606,8 @@ sub handle_18 $self->sort('S'); } $self->{handle_xml}++ if DXXml::available() && $_[1] =~ /\bxml\b/; - $self->{do_pc92}++ if $_[1] =~ /\bpc92\b/; + my ($pc9x) = $_[1] =~ /\bpc9\[(\d+)\]\b/; + $self->{do_pc92}++ if (defined $pc9x && $pc9x =~ /2/) || $_[1] =~ /\bpc92\b/; } else { $self->version(50.0); $self->version($_[2] / 100) if $_[2] && $_[2] =~ /^\d+$/; @@ -627,7 +651,7 @@ sub handle_19 my $newline = "PC19^"; # new routing list - my @rout; + my (@rout, @pc92out); # first get the INTERFACE node my $parent = Route::Node::get($self->{call}); @@ -637,6 +661,8 @@ sub handle_19 return; } + my $h; + # parse the PC19 # # We are making a major change from now on. We are only going to accept @@ -646,7 +672,8 @@ sub handle_19 # The justification for this is that most of it is wrong or out of date # anyway. # - # From now on we are only going to believe PC92 data. + # From now on we are only going to believe PC92 data and locally connected + # non-pc92 nodes. # for ($i = 1; $i < $#_-1; $i += 4) { my $here = $_[$i]; @@ -665,10 +692,15 @@ sub handle_19 next if $call eq $main::mycall; # check that this PC19 isn't trying to alter the wrong dxchan + $h = 0; my $dxchan = DXChannel::get($call); - if ($dxchan && $dxchan != $self) { - dbg("PCPROT: PC19 from $self->{call} trying to alter wrong locally connected $call, ignored!") if isdbg('chanerr'); - next; + if ($dxchan) { + if ($dxchan == $self) { + $h = 1; + } else { + dbg("PCPROT: PC19 from $self->{call} trying to alter wrong locally connected $call, ignored!") if isdbg('chanerr'); + next; + } } my $user = check_add_node($call); @@ -680,9 +712,11 @@ sub handle_19 RouteDB::update($call, $self->{call}, $dxchan ? 1 : undef); - unless ($dxchan) { - dbg("PCPROT: PC19 not directly connected, ignored") if isdbg('chanerr'); - next; + unless ($h) { + if ($parent->via_pc92) { + dbg("PCPROT: non-local node controlled by PC92, ignored") if isdbg('chanerr'); + next; + } } my $r = Route::Node::get($call); @@ -711,6 +745,7 @@ sub handle_19 my $ar = $parent->add($call, $ver, $flags); $user->wantroutepc19(1) unless defined $user->wantroutepc19; push @rout, $ar if $ar; + push @pc92out, $r if $h; } else { next; } @@ -731,10 +766,26 @@ sub handle_19 if (@rout) { $self->route_pc21($self->{call}, $line, @rout); $self->route_pc19($self->{call}, $line, @rout); - $self->route_pc92a($main::mycall, $line, $main::routeroot, @rout); + } + if (@pc92out) { + $self->route_pc92a($main::mycall, $line, $main::routeroot, @pc92out) if $self->{state} eq 'normal'; } } +sub send_delayed_pc92 +{ + my $self = shift; + + # send out delayed PC92 config for this node if it is external + unless ($self->{do_pc92}) { + my $node = Route::Node::get($self->{call}); + if ($node) { + my @rout = map {my $r = Route::User::get($_); $r ? ($r) : ()} $node->users; + $self->route_pc92c($main::mycall, undef, $node, @rout); + } + } +} + # send local configuration sub handle_20 { @@ -746,6 +797,7 @@ sub handle_20 $self->send(pc22()); $self->state('normal'); $self->{lastping} = 0; + $self->send_delayed_pc92; } # delete a cluster from the list @@ -783,6 +835,11 @@ sub handle_21 my $node = Route::Node::get($call); if ($node) { + if ($node->via_pc92) { + dbg("PCPROT: controlled by PC92, ignored") if isdbg('chanerr'); + return; + } + my $dxchan = DXChannel::get($call); if ($dxchan && $dxchan != $self) { dbg("PCPROT: PC21 from $self->{call} trying to alter locally connected $call, ignored!") if isdbg('chanerr'); @@ -803,7 +860,7 @@ sub handle_21 if (@rout) { $self->route_pc21($origin, $line, @rout); - $self->route_pc92d($main::mycall, $line, $main::routeroot, @rout); +# $self->route_pc92d($main::mycall, $line, $main::routeroot, @rout); } } @@ -816,6 +873,8 @@ sub handle_22 my $origin = shift; $self->state('normal'); $self->{lastping} = 0; + + $self->send_delayed_pc92 } # WWV info @@ -1264,7 +1323,7 @@ sub _decode_pc92_call my $icall = shift; my @part = split /:/, $icall; my ($flag, $call) = unpack "A A*", $part[0]; - return () unless $flag && $flag ge '0' && $flag le '7'; + return () unless defined $flag && $flag ge '0' && $flag le '7'; return () unless $call && is_callsign($call); my $is_node = $flag & 4; my $is_extnode = $flag & 2; @@ -1339,10 +1398,10 @@ sub gen_pc9x_t if (!$_last_time || $_last_time != $main::systime) { $_last_time = $main::systime; $_last_occurs = 0; - return $_last_time; + return $_last_time - $main::systime_daystart; } else { $_last_occurs++; - return sprintf "$_last_time.%02d", $_last_occurs; + return sprintf "%d.%02d", $_last_time - $main::systime_daystart, $_last_occurs; } } @@ -1352,11 +1411,11 @@ sub check_pc9x_t my $t = shift; my $pc = shift; my $create = shift; - + my $parent = ref $call ? $call : Route::Node::get($call); if ($parent) { my $lastid = $parent->lastid->{$pc} || 0; - if ($lastid >= $t) { + if ($lastid + $main::systime_daystart >= $t + $main::systime_daystart) { dbg("PCPROT: dup / old id on $call <= $lastid, ignored") if isdbg('chanerr'); return; } @@ -1364,7 +1423,7 @@ sub check_pc9x_t $parent = Route::Node->new($call); } $parent->lastid->{$pc} = $t; - + return $parent; } @@ -1393,10 +1452,12 @@ sub handle_92 return; } - my $parent = check_pc9x_t($pcall, $t, 92, 1); + my $parent = check_pc9x_t($pcall, $t, 92, 1) || return; $parent->lastid->{92} = $t; $parent->do_pc92(1); + $parent->via_pc92(1); + $parent->reset_obs; if (@ent) { @@ -1404,6 +1465,10 @@ sub handle_92 # and update any information that needs to be done. my ($call, $is_node, $is_extnode, $here, $version, $build) = _decode_pc92_call($ent[0]); if ($call && $is_node) { + if ($call eq $main::mycall) { + dbg("PCPROT: looped back on node entry, ignored") if isdbg('chanerr'); + return; + } if ($is_extnode) { # reparent to external node (note that we must have received a 'C' or 'A' record # from the true parent node for this external before we get one for the this node @@ -1420,6 +1485,8 @@ 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->via_pc92(1); + $parent->reset_obs; shift @ent; } @@ -1469,12 +1536,10 @@ sub handle_92 $self->route_pc21($pcall, undef, $r) if $r->isa('Route::Node'); $self->route_pc17($pcall, undef, $parent, $r) if $r->isa('Route::User'); } - foreach my $r (@radd) { - next unless $r; - - $self->route_pc19($pcall, undef, $r) if $r->isa('Route::Node'); - $self->route_pc16($pcall, undef, $parent, $r) if $r->isa('Route::User'); - } + my @pc19 = grep { $_ && $_->isa('Route::Node') } @radd; + my @pc16 = grep { $_ && $_->isa('Route::User') } @radd; + $self->route_pc19($pcall, undef, @pc19) if @pc19; + $self->route_pc16($pcall, undef, $parent, @pc16) if @pc16; } # if get here then rebroadcast the thing with its Hop count decremented (if