X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProtHandle.pm;h=e7160d7cb7148b0e59e5a809cd63258163f0e7b4;hb=ab811a0c902225075a9bd69749f65594079433a9;hp=eea43772deb4f06eb0826c779abbf98959257259;hpb=be8bb8ddece08d2893896418423a95548cbf316f;p=spider.git diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index eea43772..e7160d7c 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -2,7 +2,7 @@ # # This module impliments the handlers for the protocal mode for a dx cluster # -# Copyright (c) 1998-2006 Dirk Koopman G1TLH +# Copyright (c) 1998-2007 Dirk Koopman G1TLH # # # @@ -43,16 +43,20 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim $investigation_int $pc19_version $myprot_version %nodehops $baddx $badspotter $badnode $censorpc $allowzero $decode_dk0wcy $send_opernam @checklist - $eph_pc15_restime $pc9x_past_age $pc9x_future_age + $eph_pc15_restime $pc9x_past_age $pc9x_dupe_age $pc10_dupe_age $pc92_slug_changes $last_pc92_slug + $pc92Ain $pc92Cin $pc92Din $pc92Kin $pc9x_time_tolerance ); -$pc9x_past_age = 62*60; # maximum age in the past of a px9x (a config record might be the only - # thing a node might send - once an hour) -$pc9x_future_age = 2*3600; # maximum age in the future ditto +$pc9x_dupe_age = 60; # catch loops of circular (usually) D records $pc10_dupe_age = 45; # just something to catch duplicate PC10->PC93 conversions $pc92_slug_changes = 60; # slug any changes going outward for this long $last_pc92_slug = 0; # the last time we sent out any delayed add or del PC92s +$pc9x_time_tolerance = 15*60; # the time on a pc9x is allowed to be out by this amount +$pc9x_past_age = (122*60)+ # maximum age in the past of a px9x (a config record might be the only + $pc9x_time_tolerance; # thing a node might send - once an hour and we allow an extra hour for luck) + # this is actually the partition between "yesterday" and "today" but old. + # incoming talk commands sub handle_10 @@ -222,7 +226,7 @@ sub handle_11 # # fix up qra locators of known users - my $user = DXUser->get_current($spot[4]); + my $user = DXUser::get_current($spot[4]); if ($user) { my $qra = $user->qra; unless ($qra && is_qra($qra)) { @@ -269,12 +273,13 @@ sub handle_11 } # local processing - my $r; - eval { - $r = Local::spot($self, @spot); - }; - # dbg("Local::spot1 error $@") if isdbg('local') if $@; - return if $r; + if (defined &Local::spot) { + my $r; + eval { + $r = Local::spot($self, @spot); + }; + return if $r; + } # DON'T be silly and send on PC26s! return if $pcno == 26; @@ -353,6 +358,15 @@ sub handle_12 } else { $self->route($_[2], $line); } + + # local processing + if (defined &Local::ann) { + my $r; + eval { + $r = Local::ann($self, $line, @_[1..6]); + }; + return if $r; + } } sub handle_15 @@ -449,7 +463,7 @@ sub handle_16 # reject this if we think it is a node already my $r = Route::Node::get($call); - my $u = DXUser->get_current($call) unless $r; + my $u = DXUser::get_current($call) unless $r; if ($r || ($u && $u->is_node)) { dbg("PCPROT: $call is a node") if isdbg('chanerr'); next; @@ -471,7 +485,7 @@ sub handle_16 } # add this station to the user database, if required - my $user = DXUser->get_current($ncall); + my $user = DXUser::get_current($ncall); $user = DXUser->new($call) unless $user; $user->homenode($parent->call) if !$user->homenode; $user->node($parent->call); @@ -554,7 +568,7 @@ sub handle_17 $parent->del_user($uref); # send info to all logged in thingies - my $user = DXUser->get_current($ncall); + my $user = DXUser::get_current($ncall); $self->tell_login('logoutu', "$ncall: $ucall") if $user && $user->is_local_node; $self->tell_buddies('logoutb', $ucall, $ncall); @@ -624,7 +638,7 @@ sub check_add_node my $call = shift; # add this station to the user database, if required (don't remove SSID from nodes) - my $user = DXUser->get_current($call); + my $user = DXUser::get_current($call); if (!$user) { $user = DXUser->new($call); $user->priv(1); # I have relented and defaulted nodes @@ -933,12 +947,13 @@ sub handle_23 # note this only takes the first one it gets Geomag::update($d, $_[2], $sfi, $k, $i, @_[6..8], $r); - my $rep; - eval { - $rep = Local::wwv($self, $_[1], $_[2], $sfi, $k, $i, @_[6..8], $r); - }; - # dbg("Local::wwv2 error $@") if isdbg('local') if $@; - return if $rep; + if (defined &Local::wwv) { + my $rep; + eval { + $rep = Local::wwv($self, $_[1], $_[2], $sfi, $k, $i, @_[6..8], $r); + }; + return if $rep; + } # DON'T be silly and send on PC27s! return if $pcno == 27; @@ -1127,7 +1142,7 @@ sub handle_41 } # add this station to the user database, if required - my $user = DXUser->get_current($call); + my $user = DXUser::get_current($call); $user = DXUser->new($call) unless $user; if ($sort == 1) { @@ -1303,12 +1318,13 @@ sub handle_73 my $wcy = WCY::update($d, @_[2..12]); - my $rep; - eval { - $rep = Local::wcy($self, @_[1..12]); - }; - # dbg("Local::wcy error $@") if isdbg('local') if $@; - return if $rep; + if (defined &Local::wcy) { + my $rep; + eval { + $rep = Local::wcy($self, @_[1..12]); + }; + return if $rep; + } # broadcast to the eager world send_wcy_spot($self, $line, $d, @_[2..12]); @@ -1477,6 +1493,21 @@ sub check_pc9x_t my $pc = shift; my $create = shift; + # check that the time is between 0 >= $t < 86400 + unless ($t >= 0 && $t < 86400) { + dbg("PCPROT: time invalid t: $t, ignored") if isdbg('chanerr'); + return undef; + } + + # check that the time of this pc9x is within tolerance (default 15 mins either way) + my $now = $main::systime - $main::systime_daystart ; + my $diff = abs($now - $t); + unless ($diff < $pc9x_time_tolerance || 86400 - $diff < $pc9x_time_tolerance) { + my $c = ref $call ? $call->call : $call; + dbg("PC9XERR: $c time out of range t: $t now: $now diff: $diff > $pc9x_time_tolerance, ignored") if isdbg('chan'); + return undef; + } + my $parent = ref $call ? $call : Route::Node::get($call); if ($parent) { # we only do this for external calls whose routing table @@ -1488,26 +1519,46 @@ sub check_pc9x_t my $lastid = $parent->lastid; if (defined $lastid) { if ($t < $lastid) { + # note that this is where we determine whether this pc9x has come in yesterday + # but is still greater (modulo 86400) than the lastid or is simply an old + # duplicate sentence. To determine this we need to do some module 86400 + # arithmetic. High numbers mean that this is an old duplicate sentence, + # low numbers that it is a new sentence. + # + # Typically you will see yesterday being taken on $t = 84, $lastid = 86235 + # and old dupes with $t = 234, $lastid = 256 (which give answers 249 and + # 86378 respectively in the calculation below). + # if ($t+86400-$lastid > $pc9x_past_age) { - dbg("PCPROT: dup id on $t <= lastid $lastid, ignored") if isdbg('chanerr'); - return; + dbg("PCPROT: dup id on $t <= lastid $lastid, ignored") if isdbg('chanerr') || isdbg('pc92dedupe'); + return undef; } } elsif ($t == $lastid) { - dbg("PCPROT: dup id on $t == lastid $lastid, ignored") if isdbg('chanerr'); - return; + dbg("PCPROT: dup id on $t == lastid $lastid, ignored") if isdbg('chanerr') || isdbg('pc92dedupe'); + return undef; } else { - # $t > $lastid, check that the timestamp offered isn't too far away from 'now' - if ($t-$lastid > $pc9x_future_age ) { - dbg("PCPROT: id $t too far in the future of lastid $lastid, ignored") if isdbg('chanerr'); - return; + # check that if we have a low number in lastid that yesterday's numbers + # (likely in the 85000+ area) don't override them, thus causing flip flopping + if ($lastid+86400-$t < $pc9x_past_age) { + dbg("PCPROT: dup id on $t in yesterday, lastid $lastid, ignored") if isdbg('chanerr') || isdbg('pc92dedupe'); + return undef; } } } } } elsif ($create) { $parent = Route::Node->new($call); + } else { + dbg("PCPROT: $call does not exist, ignored") if isdbg('pc92dedupe'); + return undef; + } + if (isdbg('pc92dedupe')) { + my $exists = exists $parent->{lastid}; # naughty, naughty :-) + my $val = $parent->{lastid}; + my $s = $exists ? (defined $val ? $val : 'exists/undef') : 'undef'; + dbg("PCPROT: $call pc92 id lastid $s -> $t"); } - $parent->lastid($t) if $parent; + $parent->lastid($t); return $parent; } @@ -1578,6 +1629,11 @@ sub handle_92 my $t = $_[2]; my $sort = $_[3]; + # this catches loops of A/Ds +# if (eph_dup($line, $pc9x_dupe_age)) { +# return; +# } + if ($pcall eq $main::mycall) { dbg("PCPROT: looped back, ignored") if isdbg('chanerr'); return; @@ -1601,7 +1657,9 @@ sub handle_92 return; } - my $parent = check_pc9x_t($pcall, $t, 92, 1) || return; + # don't create routing entries for D records that don't already exist + # this is what causes all those PC92 loops! + my $parent = check_pc9x_t($pcall, $t, 92, $sort ne 'D') || return; my $oparent = $parent; $parent->do_pc9x(1); @@ -1651,6 +1709,8 @@ sub handle_92 } } elsif ($sort eq 'K') { + $pc92Kin += length $line if $sort eq 'K'; + # remember the last channel we arrived on $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call; @@ -1664,10 +1724,17 @@ sub handle_92 push @radd, $add if $add; $parent->reset_obs; + $parent->version($ent[4]) if $ent[4]; + $parent->build($ent[5]) if $ent[5]; + dbg("ROUTE: reset obscount on $parent->{call} now " . $parent->obscount) if isdbg('obscount'); } } elsif ($sort eq 'A' || $sort eq 'D' || $sort eq 'C') { + $pc92Ain += length $line if $sort eq 'A'; + $pc92Cin += length $line if $sort eq 'C'; + $pc92Din += length $line if $sort eq 'D'; + # remember the last channel we arrived on $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call; @@ -1827,6 +1894,12 @@ sub handle_93 return; } + # ignore PC93 coming in from outside this node with a target of local + if ($to eq 'LOCAL' && $self != $main::me) { + dbg("PCPROT: incoming LOCAL chat not from local node, ignored") if isdbg('chanerr'); + return; + } + # if it is routeable then then treat it like a talk my $ref = Route::get($to); if ($ref) { @@ -1874,7 +1947,9 @@ sub handle_93 # chat messages to non-pc9x nodes $self->send_chat(1, pc12($from, $text, undef, $to, undef, $pcall), $from, '*', $text, $to, $pcall, '0'); } - $self->broadcast_route_pc9x($pcall, undef, $line, 0); + + # broadcast this chat sentence everywhere unless it is targetted to 'LOCAL' + $self->broadcast_route_pc9x($pcall, undef, $line, 0) unless $to eq 'LOCAL' || $via eq 'LOCAL'; } # if get here then rebroadcast the thing with its Hop count decremented (if