change node disconnection code to improve node clearouts
[spider.git] / perl / DXProtHandle.pm
index 9a4104e5c8ad70d4d4f81bacef83fc4ea3a8e746..eacd9225d7ca197a9c0acf4b3accbd9968574d35 100644 (file)
@@ -41,14 +41,17 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim
                        $last_hour $last10 %eph  %pings %rcmds $ann_to_talk
                        $pingint $obscount %pc19list $chatdupeage $chatimportfn
                        $investigation_int $pc19_version $myprot_version
-                       %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck
+                       %nodehops $baddx $badspotter $badnode $censorpc
                        $allowzero $decode_dk0wcy $send_opernam @checklist
                        $eph_pc15_restime $pc9x_past_age $pc9x_future_age
+                       $pc10_dupe_age
                   );
 
 $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 = 5*60;               # maximum age in the future ditto
+$pc10_dupe_age = 45;                   # just something to catch duplicate PC10->PC93 conversions
+
 
 # incoming talk commands
 sub handle_10
@@ -58,8 +61,10 @@ sub handle_10
        my $line = shift;
        my $origin = shift;
 
-       # rsfp check
-       return if $rspfcheck and !$self->rspfcheck(0, $_[6], $_[1]);
+       # this is to catch loops caused by bad software ...
+       if (eph_dup($line, $pc10_dupe_age)) {
+               return;
+       }
 
        # will we allow it at all?
        if ($censorpc) {
@@ -106,8 +111,8 @@ sub handle_10
        RouteDB::update($_[6], $self->{call});
 #      RouteDB::update($to, $_[6]);
 
-       # convert this to a PC93 and process it as such
-       $self->normal(pc93($to, $from, $via, $_[3], $_[6]));
+       # convert this to a PC93, coming from mycall with origin set and process it as such
+       $main::me->normal(pc93($to, $from, $via, $_[3], $_[6]));
 }
 
 # DX Spot handling
@@ -126,9 +131,6 @@ sub handle_11
                }
        }
 
-       # rsfp check
-       #                       return if $rspfcheck and !$self->rspfcheck(1, $_[7], $_[6]);
-
        # is the spotted callsign blank? This should really be trapped earlier but it
        # could break other protocol sentences. Also check for lower case characters.
        if ($_[2] =~ /^\s*$/) {
@@ -286,8 +288,6 @@ sub handle_12
        my $line = shift;
        my $origin = shift;
 
-       #                       return if $rspfcheck and !$self->rspfcheck(1, $_[5], $_[1]);
-
        # announce duplicate checking
        $_[3] =~ s/^\s+//;                      # remove leading blanks
 
@@ -360,7 +360,7 @@ sub handle_15
        my $origin = shift;
 
        if (eph_dup($line, $eph_pc15_restime)) {
-               dbg("PCPROT: Ephemeral dup, dropped") if isdbg('chanerr');
+               return;
        } else {
                unless ($self->{isolate}) {
                        DXChannel::broadcast_nodes($line, $self) if $line =~ /\^H\d+\^?~?$/; # send it to everyone but me
@@ -402,7 +402,6 @@ sub handle_16
        }
 
        if (eph_dup($line)) {
-               dbg("PCPROT: dup PC16 detected") if isdbg('chanerr');
                return;
        }
 
@@ -545,7 +544,6 @@ sub handle_17
        $self->tell_buddies('logoutb', $ucall, $ncall);
 
        if (eph_dup($line)) {
-               dbg("PCPROT: dup PC17 detected") if isdbg('chanerr');
                return;
        }
 
@@ -833,7 +831,6 @@ sub handle_21
        }
 
        if (eph_dup($line)) {
-               dbg("PCPROT: dup PC21 detected") if isdbg('chanerr');
                return;
        }
 
@@ -878,10 +875,6 @@ sub handle_23
                }
        }
 
-       # only do a rspf check on PC23 (not 27)
-       if ($pcno == 23) {
-               return if $rspfcheck and !$self->rspfcheck(1, $_[8], $_[7])
-       }
 
        # do some de-duping
        my $d = cltounix($_[1], sprintf("%02d18Z", $_[2]));
@@ -941,7 +934,6 @@ sub handle_24
        return unless $nref || $uref; # if we don't know where they are, it's pointless sending it on
 
        if (eph_dup($line)) {
-               dbg("PCPROT: Dup PC24 ignored\n") if isdbg('chanerr');
                return;
        }
 
@@ -1022,7 +1014,7 @@ sub handle_34
        my $line = shift;
        my $origin = shift;
        if (eph_dup($line, $eph_pc34_restime)) {
-               dbg("PCPROT: dupe PC34, ignored") if isdbg('chanerr');
+               return;
        } else {
                $self->process_rcmd($_[1], $_[2], $_[2], $_[3]);
        }
@@ -1095,7 +1087,6 @@ sub handle_41
 
        my $l = "PC41^$call^$sort";
        if (eph_dup($l, $eph_info_restime)) {
-               dbg("PCPROT: dup PC41, ignored") if isdbg('chanerr');
                return;
        }
 
@@ -1176,7 +1167,6 @@ sub handle_49
        my $origin = shift;
 
        if (eph_dup($line)) {
-               dbg("PCPROT: Dup PC49 ignored\n") if isdbg('chanerr');
                return;
        }
 
@@ -1235,7 +1225,6 @@ sub handle_51
                RouteDB::update($from, $self->{call});
 
                if (eph_dup($line)) {
-                       dbg("PCPROT: dup PC51 detected") if isdbg('chanerr');
                        return;
                }
                # route down an appropriate thingy
@@ -1441,7 +1430,7 @@ sub check_pc9x_t
        } elsif ($create) {
                $parent = Route::Node->new($call);
        }
-       $parent->lastid->{$pc} = $t;
+       $parent->lastid->{$pc} = $t if $parent;
 
        return $parent;
 }
@@ -1537,6 +1526,9 @@ sub handle_92
                }
        } elsif ($sort eq 'A' || $sort eq 'D' || $sort eq 'C') {
 
+               # remember the last channel we arrived on
+               $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
+
                # this is the main route section
                # here is where all the routes are created and destroyed
 
@@ -1560,12 +1552,14 @@ sub handle_92
                                                dbg("PCPROT: $call looped back onto $main::mycall, ignored") if isdbg('chanerr');
                                                return;
                                        }
+                                       # this is only accepted from my "self".
+                                       # this also kills configs from PC92 nodes with external PC19 nodes that are also
+                                       # locally connected. Local nodes always take precedence.
+                                       if (DXChannel::get($call) && $call ne $self->{call}) {
+                                               dbg("PCPROT: locally connected node $call from other another node $self->{call}, ignored") if isdbg('chanerr');
+                                               return;
+                                       }
                                        if ($is_extnode) {
-                                               # this is only accepted from my "self"
-                                               if (DXChannel::get($call) && $call ne $self->{call}) {
-                                                       dbg("PCPROT: locally connected node config for $call from other another node $self->{call}, ignored") if isdbg('chanerr');
-                                                       return;
-                                               }
                                                # 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
                                                unless ($parent = Route::Node::get($call)) {
@@ -1579,6 +1573,7 @@ sub handle_92
                                                }
                                                $parent = check_pc9x_t($call, $t, 92) || return;
                                                $parent->via_pc92(1);
+                                               $parent->PC92C_dxchan($self->{call});
                                        }
                                } else {
                                        dbg("PCPROT: must be mycall or external node as first entry, ignored") if isdbg('chanerr');
@@ -1587,6 +1582,7 @@ 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->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
                                shift @ent;
                        }
                }
@@ -1615,11 +1611,9 @@ sub handle_92
 
                        # we only reset obscounts on config records
                        $oparent->reset_obs;
-                       $oparent->PC92C_dxchan($self->{call}) unless $self->{call} eq $oparent->call;
                        dbg("ROUTE: reset obscount on $pcall now " . $oparent->obscount) if isdbg('obscount');
                        if ($oparent != $parent) {
                                $parent->reset_obs;
-                               $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
                                dbg("ROUTE: reset obscount on $parent->{call} now " . $parent->obscount) if isdbg('obscount');
                        }
 
@@ -1694,6 +1688,7 @@ sub handle_93
                return;
        }
 
+       # remember that we are converting PC10->PC93
        unless ($self->{do_pc9x}) {
                dbg("PCPROT: PC9x come in from non-PC9x node, ignored") if isdbg('chanerr');
                return;
@@ -1709,6 +1704,11 @@ sub handle_93
        my $onode = $_[7];
        $onode = $pcall if @_ <= 8;
 
+       # this is catch loops caused by bad software ...
+       if (eph_dup("PC93|$from|$text|$onode", $pc10_dupe_age)) {
+               return;
+       }
+
        # will we allow it at all?
        if ($censorpc) {
                my @bad;
@@ -1718,11 +1718,6 @@ sub handle_93
                }
        }
 
-       # this is catch loops caused by bad software ...
-       if (eph_dup("PC93|$from|$text|$onode")) {
-               return;
-       }
-
        # if this is a 'bad spotter' user then ignore it
        my $nossid = $from;
        $nossid =~ s/-\d+$//;
@@ -1736,9 +1731,16 @@ sub handle_93
                my $dxchan;
                $dxchan = DXChannel::get($main::myalias) if $to eq $main::mycall;
                $dxchan = DXChannel::get($to) unless $dxchan;
-               if ($dxchan && $dxchan->is_user) {
-                       $dxchan->talk($from, $to, $via, $text, $onode);
-                       return;
+               # check it...
+               if ($dxchan) {
+                       if (ref $dxchan && $dxchan->isa('DXChannel')) {
+                               if ($dxchan->is_user) {
+                                       $dxchan->talk($from, $to, $via, $text, $onode);
+                                       return;
+                               }
+                       } else {
+                               dbg("ERROR: $to -> $dxchan is not a DXChannel! (local talk)");
+                       }
                }
 
                # convert to PC10 talks where appropriate
@@ -1746,14 +1748,17 @@ sub handle_93
                if ($ref) {
                        # just go for the "best" one for now (rather than broadcast)
                        $dxchan = $ref->dxchan;
-#                      my @dxchan = $ref->alldxchan;
-#                      for $dxchan (@dxchan) {
+
+                       # check it...
+                       if (ref $dxchan && $dxchan->isa('DXChannel')) {
                                if ($dxchan->{do_pc9x}) {
                                        $dxchan->send($line);
                                } else {
                                        $dxchan->talk($from, $to, $via, $text, $onode);
                                }
-#                      }
+                       } else {
+                               dbg("ERROR: $to -> $dxchan is not a DXChannel! (convert to pc10)");
+                       }
                        return;
                }