X-Git-Url: http://dxcluster.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProt.pm;h=48410eb2ffb50082c87320193086e67b9237dea6;hb=9bc8098facc58d802923bdc0adf9b6cad1b0a800;hp=0d222859178ef07e06bed935b40cd9fc0d83741b;hpb=a162f8f36fe83f8e45b284a5aa5e71022dcd8be2;p=spider.git diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 0d222859..48410eb2 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -33,6 +33,9 @@ use DXHash; use Route; use Route::Node; use Script; +use Investigate; +use RouteDB; + use strict; @@ -44,7 +47,8 @@ $main::branch += $BRANCH; 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 + $pingint $obscount %pc19list $chatdupeage $chatimportfn + $investigation_int $pc19_version %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck $allowzero $decode_dk0wcy $send_opernam @checklist); @@ -71,6 +75,9 @@ $eph_pc34_restime = 30; $pingint = 5*60; $obscount = 2; $chatdupeage = 20 * 60 * 60; +$chatimportfn = "$main::root/chat_import"; +$investigation_int = 12*60*60; # time between checks to see if we can see this node +$pc19_version = 5466; # the visible version no for outgoing PC19s generated from pc59 @checklist = ( @@ -411,6 +418,10 @@ sub handle_10 } } + # remember a route to this node and also the node on which this user is + RouteDB::update($_[6], $self->{call}); +# RouteDB::update($to, $_[6]); + # it is here and logged on $dxchan = DXChannel->get($main::myalias) if $to eq $main::mycall; $dxchan = DXChannel->get($to) unless $dxchan; @@ -431,6 +442,8 @@ sub handle_10 return; } + # can we see an interface to send it down? + # not visible here, send a message of condolence $vref = undef; $ref = Route::get($from); @@ -503,7 +516,10 @@ sub handle_11 } } - + # remember a route +# RouteDB::update($_[7], $self->{call}); +# RouteDB::update($_[6], $_[7]); + my @spot = Spot::prepare($_[1], $_[2], $d, $_[5], $_[6], $_[7]); # global spot filtering on INPUT if ($self->{inspotsfilter}) { @@ -629,12 +645,17 @@ sub handle_12 return; } + my $dxchan; if ((($dxchan = DXChannel->get($_[2])) && $dxchan->is_user) || $_[4] =~ /^[\#\w.]+$/){ $self->send_chat($line, @_[1..6]); } elsif ($_[2] eq '*' || $_[2] eq $main::mycall) { + # remember a route +# RouteDB::update($_[5], $self->{call}); +# RouteDB::update($_[1], $_[5]); + # ignore something that looks like a chat line coming in with sysop # flag - this is a kludge... if ($_[3] =~ /^\#\d+ / && $_[4] eq '*') { @@ -671,17 +692,12 @@ sub handle_16 my $line = shift; my $origin = shift; - if (eph_dup($line)) { - dbg("PCPROT: dup PC16 detected") if isdbg('chanerr'); - return; - } - # general checks my $dxchan; my $ncall = $_[1]; my $newline = "PC16^"; - # do I want users from this channel? + # dos I want users from this channel? unless ($self->user->wantpc16) { dbg("PCPROT: don't send users to $self->{call}") if isdbg('chanerr'); return; @@ -691,6 +707,24 @@ sub handle_16 dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr'); return; } + + RouteDB::update($ncall, $self->{call}); + + # do we believe this call? + unless ($ncall eq $self->{call} || $self->is_believed($ncall)) { + if (my $ivp = Investigate::get($ncall, $self->{call})) { + $ivp->store_pcxx($pcno,$line,$origin,@_); + } else { + dbg("PCPROT: We don't believe $ncall on $self->{call}") if isdbg('chanerr'); + } + return; + } + + if (eph_dup($line)) { + dbg("PCPROT: dup PC16 detected") if isdbg('chanerr'); + return; + } + my $parent = Route::Node::get($ncall); # if there is a parent, proceed, otherwise if there is a latent PC19 in the PC19list, @@ -830,6 +864,18 @@ sub handle_17 return; } + RouteDB::delete($ncall, $self->{call}); + + # do we believe this call? + unless ($ncall eq $self->{call} || $self->is_believed($ncall)) { + if (my $ivp = Investigate::get($ncall, $self->{call})) { + $ivp->store_pcxx($pcno,$line,$origin,@_); + } else { + dbg("PCPROT: We don't believe $ncall on $self->{call}") if isdbg('chanerr'); + } + return; + } + my $uref = Route::User::get($ucall); unless ($uref) { dbg("PCPROT: Route::User $ucall not in config") if isdbg('chanerr'); @@ -907,11 +953,6 @@ sub handle_19 my $i; my $newline = "PC19^"; - if (eph_dup($line)) { - dbg("PCPROT: dup PC19 detected") if isdbg('chanerr'); - return; - } - # new routing list my @rout; @@ -931,13 +972,13 @@ sub handle_19 my $user = DXUser->get_current($origin); if (!$user) { $user = DXUser->new($origin); - $user->sort('S'); $user->priv(1); # I have relented and defaulted nodes $user->lockout(1); $user->homenode($origin); $user->node($origin); $user->wantroutepc19(1); } + $user->sort('A') unless $user->is_node; $user->put; } $parent = $op; @@ -970,12 +1011,35 @@ sub handle_19 my $user = DXUser->get_current($call); if (!$user) { $user = DXUser->new($call); - $user->sort('A'); $user->priv(1); # I have relented and defaulted nodes $user->lockout(1); $user->homenode($call); $user->node($call); } + $user->sort('A') unless $user->is_node; + + RouteDB::update($call, $self->{call}); + + # do we believe this call? + my $genline = "PC19^$here^$call^$conf^$ver^$_[-1]^"; + unless ($call eq $self->{call} || $self->is_believed($call)) { + my $pt = $user->lastping($self->{call}) || 0; + if ($pt+$investigation_int < $main::systime && !Investigate::get($call, $self->{call})) { + my $ivp = Investigate->new($call, $self->{call}); + $ivp->version($ver); + $ivp->here($here); + $ivp->store_pcxx($pcno,$genline,$origin,'PC19',$here,$call,$conf,$ver,$_[-1]); + } else { + dbg("PCPROT: We don't believe $call on $self->{call}") if isdbg('chanerr'); + } + $user->put; + next; + } + + if (eph_dup($genline)) { + dbg("PCPROT: dup PC19 for $call detected") if isdbg('chanerr'); + next; + } my $r = Route::Node::get($call); my $flags = Route::here($here)|Route::conf($conf); @@ -1058,6 +1122,18 @@ sub handle_21 return; } + RouteDB::delete($call, $self->{call}); + + # check if we believe this + unless ($call eq $self->{call} || $self->is_believed($call)) { + if (my $ivp = Investigate::get($call, $self->{call})) { + $ivp->store_pcxx($pcno,$line,$origin,@_); + } else { + dbg("PCPROT: We don't believe $call on $self->{call}") if isdbg('chanerr'); + } + return; + } + # check to see if we are in the pc19list, if we are then don't bother with any of # this routing table manipulation, just remove it from the list and dump it my @rout; @@ -1423,6 +1499,9 @@ sub handle_50 my $origin = shift; my $call = $_[1]; + + RouteDB::update($call, $self->{call}); + my $node = Route::Node::get($call); if ($node) { return unless $node->call eq $self->{call}; @@ -1470,25 +1549,35 @@ sub handle_51 my $nopings = $tochan->user->nopings || $obscount; push @{$tochan->{pingtime}}, $t; shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6; - - # cope with a missed ping, this means you must set the pingint large enough + + # cope with a missed ping, this means you must set the pingint large enough if ($t > $tochan->{pingint} && $t < 2 * $tochan->{pingint} ) { $t -= $tochan->{pingint}; } - - # calc smoothed RTT a la TCP + + # calc smoothed RTT a la TCP if (@{$tochan->{pingtime}} == 1) { $tochan->{pingave} = $t; } else { $tochan->{pingave} = $tochan->{pingave} + (($t - $tochan->{pingave}) / 6); } $tochan->{nopings} = $nopings; # pump up the timer + if (my $ivp = Investigate::get($from, $self->{call})) { + $ivp->handle_ping; + } + } elsif (my $rref = Route::Node::get($r->{call})) { + if (my $ivp = Investigate::get($from, $self->{call})) { + $ivp->handle_ping; + } } - } + } } } } } else { + + RouteDB::update($from, $self->{call}); + if (eph_dup($line)) { dbg("PCPROT: dup PC51 detected") if isdbg('chanerr'); return; @@ -1626,11 +1715,15 @@ sub process } } + Investigate::process(); + # every ten seconds if ($t - $last10 >= 10) { # clean out ephemera eph_clean(); + import_chat(); + $last10 = $t; } @@ -1966,6 +2059,7 @@ sub send_local_config # # is called route(to, pcline); # + sub route { my ($self, $call, $line) = @_; @@ -1977,7 +2071,9 @@ sub route # always send it down the local interface if available my $dxchan = DXChannel->get($call); - unless ($dxchan) { + if ($dxchan) { + dbg("route: $call -> $dxchan->{call} direct" ) if isdbg('route'); + } else { my $cl = Route::get($call); $dxchan = $cl->dxchan if $cl; if (ref $dxchan) { @@ -1985,8 +2081,23 @@ sub route dbg("PCPROT: Trying to route back to source, dropped") if isdbg('chanerr'); return; } + dbg("route: $call -> $dxchan->{call} using normal route" ) if isdbg('route'); + } + } + + # try the backstop method + unless ($dxchan) { + my $rcall = RouteDB::get($call); + if ($rcall) { + if ($self && $rcall eq $self->{call}) { + dbg("PCPROT: Trying to route back to source, dropped") if isdbg('chanerr'); + return; + } + $dxchan = DXChannel->get($rcall); + dbg("route: $call -> $rcall using RouteDB" ) if isdbg('route') && $dxchan; } } + if ($dxchan) { my $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name if ($routeit) { @@ -2058,14 +2169,23 @@ sub load_hops # add a ping request to the ping queues sub addping { - my ($from, $to) = @_; + my ($from, $to, $via) = @_; my $ref = $pings{$to} || []; my $r = {}; $r->{call} = $from; $r->{t} = [ gettimeofday ]; - route(undef, $to, pc51($to, $main::mycall, 1)); + if ($via && (my $dxchan = DXChannel->get($via))) { + $dxchan->send(pc51($to, $main::mycall, 1)); + } else { + route(undef, $to, pc51($to, $main::mycall, 1)); + } push @$ref, $r; $pings{$to} = $ref; + my $u = DXUser->get_current($to); + if ($u) { + $u->lastping(($via || $from), $main::systime); + $u->put; + } } sub process_rcmd @@ -2190,6 +2310,8 @@ sub disconnect eph_del_regex("^PC1[679].*$c"); } } + + RouteDB::delete_interface($call); # remove them from the pc19list as well while (my ($k,$v) = each %pc19list) { @@ -2389,6 +2511,7 @@ sub eph_dup $s =~ s/\^H\d\d?\^?\~?$//; $r = 1 if exists $eph{$s}; # pump up the dup if it keeps circulating $eph{$s} = $main::systime + $t; + dbg("PCPROT: emphemeral duplicate") if $r && isdbg('chanerr'); return $r; } @@ -2429,5 +2552,69 @@ sub run_cmd { goto &DXCommandmode::run_cmd; } + + +# import any msgs in the chat directory +# the messages are sent to the chat group which forms the +# the first part of the name (eg: solar.1243.txt would be +# sent to chat group SOLAR) +# +# Each message found is sent: one non-blank line to one chat +# message. So 4 lines = 4 chat messages. +# +# The special name LOCAL is for local users ANN +# The special name ALL is for ANN/FULL +# The special name SYSOP is for ANN/SYSOP +# +sub import_chat +{ + # are there any to do in this directory? + return unless -d $chatimportfn; + unless (opendir(DIR, $chatimportfn)) { + dbg("can\'t open $chatimportfn $!") if isdbg('msg'); + Log('msg', "can\'t open $chatimportfn $!"); + return; + } + + my @names = readdir(DIR); + closedir(DIR); + my $name; + foreach $name (@names) { + next if $name =~ /^\./; + my $splitit = $name =~ /^split/; + my $fn = "$chatimportfn/$name"; + next unless -f $fn; + unless (open(MSG, $fn)) { + dbg("can\'t open import file $fn $!") if isdbg('msg'); + Log('msg', "can\'t open import file $fn $!"); + unlink($fn); + next; + } + my @msg = map { s/\r?\n$//; $_ } ; + close(MSG); + unlink($fn); + + my @cat = split /\./, $name; + my $target = uc $cat[0]; + + foreach my $text (@msg) { + next unless $text && $text !~ /^\s*#/; + if ($target eq 'ALL' || $target eq 'LOCAL' || $target eq 'SYSOP') { + my $sysopflag = $target eq 'SYSOP' ? '*' : ' '; + if ($target ne 'LOCAL') { + send_announce($main::me, pc12($main::mycall, $text, '*', $sysopflag), $main::mycall, '*', $text, $sysopflag, $main::mycall, '0'); + } else { + Log('ann', 'LOCAL', $main::mycall, $text); + DXChannel::broadcast_list("To LOCAL de ${main::mycall}: $text\a", 'ann', undef, DXCommandmode->get_all()); + } + } else { + my $msgid = nextchatmsgid(); + $text = "#$msgid $text"; + send_chat($main::me, pc12($main::mycall, $text, '*', $target), $main::mycall, '*', $text, $target, $main::mycall, '0'); + } + } + } +} + 1; __END__