fix deduping before input filtering
[spider.git] / perl / DXProt.pm
index ec18e19f499f4298921d127909f01ab6644c14fe..6c18a83052329dcddf29c42d149e38fd94d1e898 100644 (file)
@@ -42,7 +42,7 @@ $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ ) || 0;
 $main::build += $VERSION;
 $main::branch += $BRANCH;
 
-use vars qw($pc11_max_age $pc23_max_age $last_pc50
+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
                        %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck
                        $allowzero $decode_dk0wcy $send_opernam @checklist);
@@ -62,6 +62,9 @@ $badnode = new DXHash "badnode";
 $last10 = $last_pc50 = time;
 $ann_to_talk = 1;
 $rspfcheck = 1;
+$eph_restime = 180;
+$eph_info_restime = 60*60;
+$eph_pc34_restime = 30;
 
 @checklist = 
 (
@@ -439,6 +442,7 @@ sub normal
                                }
                        }
 
+
                        my @spot = Spot::prepare($field[1], $field[2], $d, $field[5], $field[6], $field[7]);
                        # global spot filtering on INPUT
                        if ($self->{inspotsfilter}) {
@@ -448,7 +452,10 @@ sub normal
                                        return;
                                }
                        }
-                       
+
+                       # this goes after the input filtering, but before the add
+                       # so that if it is input filtered, it isn't added to the dup
+                       # list. This allows it to come in from a "legitimate" source
                        if (Spot::dup($field[1], $field[2], $d, $field[5])) {
                                dbg("PCPROT: Duplicate Spot ignored\n") if isdbg('chanerr');
                                return;
@@ -693,9 +700,8 @@ sub normal
                        # input filter if required
                        return unless $self->in_filter_route($parent);
                        
-                       my @rout = $parent->del_user($uref);
-
-                       $self->route_pc17($parent, @rout) if @rout;
+                       $parent->del_user($uref);
+                       $self->route_pc17($parent, $uref);
                        return;
                }
                
@@ -824,6 +830,14 @@ sub normal
                                return;
                        }
 
+                       # if I get a PC21 from the same callsign as self then treat it
+                       # as a PC39: I have gone away
+                       if ($call eq $self->call) {
+                               $self->disconnect(1);
+                               eph_del_regex("^PC(?:1[679]|21).*$field[1]");
+                               return;
+                       }
+
                        eph_del_regex("^PC1[79].*$call");
                        
                        my @rout;
@@ -834,11 +848,6 @@ sub normal
                                return;
                        }
                        if ($call ne $main::mycall) { # don't allow malicious buggers to disconnect me!
-                               if ($call eq $self->{call}) {
-                                       dbg("PCPROT: Trying to disconnect myself with PC21") if isdbg('chanerr');
-                                       return;
-                               }
-
                                my $node = Route::Node::get($call);
                                if ($node) {
 
@@ -975,11 +984,16 @@ sub normal
                }
                
                if ($pcno == 34 || $pcno == 36) { # remote commands (incoming)
-                       $self->process_rcmd($field[1], $field[2], $field[2], $field[3]);
+                       if (eph_dup($line, $eph_pc34_restime)) {
+                               dbg("PCPROT: dupe") if isdbg('chanerr');
+                       } else {
+                               $self->process_rcmd($field[1], $field[2], $field[2], $field[3]);
+                       }
                        return;
                }
                
                if ($pcno == 35) {              # remote command replies
+                       eph_del_regex("^PC35\^$field[2]\^$field[1]\^");
                        $self->process_rcmd_reply($field[1], $field[2], $field[1], $field[3]);
                        return;
                }
@@ -1003,6 +1017,11 @@ sub normal
                if ($pcno == 41) {              # user info
                        my $call = $field[1];
 
+                       if (eph_dup($line, $eph_info_restime)) {
+                               dbg("PCPROT: dupe") if isdbg('chanerr');
+                               return;
+                       }
+                       
                        # input filter if required
 #                      my $ref = Route::get($call) || Route->new($call);
 #                      return unless $self->in_filter_route($ref);
@@ -1033,11 +1052,11 @@ sub normal
                        } elsif ($field[2] == 4) {
                                $user->homenode($field[3]);
                        } elsif ($field[2] == 5) {
-                               if (is_qra($field[3])) {
-                                       my ($lat, $long) = DXBearing::qratoll($field[3]);
+                               if (is_qra(uc $field[3])) {
+                                       my ($lat, $long) = DXBearing::qratoll(uc $field[3]);
                                        $user->lat($lat);
                                        $user->long($long);
-                                       $user->qra($field[3]);
+                                       $user->qra(uc $field[3]);
                                } else {
                                        dbg('PCPROT: not a valid QRA locator') if isdbg('chanerr');
                                        return;
@@ -1046,9 +1065,13 @@ sub normal
                        $user->lastoper($main::systime);   # to cut down on excessive for/opers being generated
                        $user->put;
 
+                       unless ($self->{isolate}) {
+                               DXChannel::broadcast_nodes($line, $self); # send it to everyone but me
+                       }
+
 #  perhaps this IS what we want after all
 #                      $self->route_pc41($ref, $call, $field[2], $field[3], $field[4]);
-#                      return;
+                       return;
                }
 
                if ($pcno == 43) {
@@ -1156,7 +1179,7 @@ sub normal
                                return;
                        }
                        @field = map { unpad($_) } @field;
-                       if (WCY::dup($d,@field[3..7])) {
+                       if (WCY::dup($d)) {
                                dbg("PCPROT: Dup WCY Spot ignored\n") if isdbg('chanerr');
                                return;
                        }
@@ -1165,7 +1188,7 @@ sub normal
 
                        my $rep;
                        eval {
-                               $rep = Local::wwv($self, @field[1..12]);
+                               $rep = Local::wcy($self, @field[1..12]);
                        };
                        # dbg("Local::wcy error $@") if isdbg('local') if $@;
                        return if $rep;
@@ -1905,12 +1928,13 @@ sub in_filter_route
 sub eph_dup
 {
        my $s = shift;
+       my $t = shift || $eph_restime;
        my $r;
 
        # chop the end off
        $s =~ s/\^H\d\d?\^?\~?$//;
        $r = 1 if exists $eph{$s};    # pump up the dup if it keeps circulating
-       $eph{$s} = $main::systime;
+       $eph{$s} = $main::systime + $t;
        return $r;
 }
 
@@ -1930,11 +1954,26 @@ sub eph_clean
        my ($key, $val);
        
        while (($key, $val) = each %eph) {
-               if ($main::systime - $val > 180) {
+               if ($main::systime >= $val) {
                        delete $eph{$key};
                }
        }
 }
 
+sub eph_list
+{
+       my ($key, $val);
+       my @out;
+
+       while (($key, $val) = each %eph) {
+               push @out, $key, $val;
+       }
+       return @out;
+}
+
+sub run_cmd
+{
+       goto &DXCommandmode::run_cmd;
+}
 1;
 __END__