X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProt.pm;h=d9e59c4937bc9211cc8425a804760879dfba6aa6;hb=84e68f5fca6f33df5e2c7c801038043d339aaac2;hp=ce9b13a4b077c61cd0c8568784f768061f992081;hpb=fade7a04893b2451b0dce2f51bffcd8b7f669a85;p=spider.git diff --git a/perl/DXProt.pm b/perl/DXProt.pm index ce9b13a4..d9e59c49 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -178,6 +178,14 @@ sub normal } if ($pcno == 11 || $pcno == 26) { # dx spot + + # route 'foreign' pc26s + if ($pcno == 26) { + if ($field[7] ne $main::mycall) { + route($field[7], $line); + return; + } + } # if this is a 'nodx' node then ignore it last SWITCH if grep $field[7] =~ /^$_/, @DXProt::nodx_node; @@ -305,8 +313,17 @@ sub normal if ($pcno == 16) { # add a user my $node = DXCluster->get_exact($field[1]); - last SWITCH if !$node; # ignore if havn't seen a PC19 for this one yet - last SWITCH unless $node->isa('DXNode'); + return unless $node; # ignore if havn't seen a PC19 for this one yet + return unless $node->isa('DXNode'); + if ($node->dxchan != $self) { + dbg('chan', "LOOP: $field[1] came in on wrong channel"); + return; + } + my $dxchan; + if (($dxchan = DXChannel->get($field[1])) && $dxchan != $self) { + dbg('chan', "LOOP: $field[1] connected locally"); + return; + } my $i; @@ -336,7 +353,18 @@ sub normal } if ($pcno == 17) { # remove a user - + my $node = DXCluster->get_exact($field[2]); + return unless $node; + return unless $node->isa('DXNode'); + if ($node->dxchan != $self) { + dbg('chan', "LOOP: $field[2] came in on wrong channel"); + return; + } + my $dxchan; + if (($dxchan = DXChannel->get($field[2])) && $dxchan != $self) { + dbg('chan', "LOOP: $field[2] connected locally"); + return; + } my $ref = DXCluster->get_exact($field[1]); $ref->del() if $ref; last SWITCH; @@ -351,18 +379,34 @@ sub normal if ($pcno == 19) { # incoming cluster list my $i; + my $newline = "PC19^"; for ($i = 1; $i < $#field-1; $i += 4) { my $here = $field[$i]; my $call = uc $field[$i+1]; - my $confmode = $field[$i+2] eq '*'; + my $confmode = $field[$i+2]; my $ver = $field[$i+3]; # now check the call over - next if DXCluster->get_exact($call); # we already have this + my $node = DXCluster->get_exact($call); + if ($node) { + my $dxchan; + if (($dxchan = DXChannel->get($call)) && $dxchan != $self) { + dbg('chan', "LOOP: $call connected locally"); + } + if ($node->dxchan != $self) { + dbg('chan', "LOOP: $call come in on wrong channel"); + next; + } + dbg('chan', "already have $call"); + next; + } # check for sane parameters next if $ver < 5000; # only works with version 5 software next if length $call < 3; # min 3 letter callsigns + + # add it to the nodes table and outgoing line + $newline .= "$here^$call^$confmode^$ver^"; DXNode->new($self, $call, $confmode, $here, $ver); # unbusy and stop and outgoing mail (ie if somehow we receive another PC19 without a disconnect) @@ -385,6 +429,11 @@ sub normal # queue up any messages DXMsg::queue_msg(0) if $self->state eq 'normal'; + return if $newline eq "PC19^"; + + # add hop count + $newline .= get_hops(19) . "^"; + $line = $newline; last SWITCH; } @@ -402,8 +451,22 @@ sub normal if ($pcno == 21) { # delete a cluster from the list my $call = uc $field[1]; if ($call ne $main::mycall) { # don't allow malicious buggers to disconnect me! - my $ref = DXCluster->get_exact($call); - $ref->del() if $ref; + my $node = DXCluster->get_exact($call); + if ($node) { + if ($node->dxchan != $self) { + dbg('chan', "LOOP: $call come in on wrong channel"); + return; + } + my $dxchan; + if (($dxchan = DXChannel->get($call)) && $dxchan != $self) { + dbg('chan', "LOOP: $call connected locally"); + return; + } + $node->del(); + } else { + dbg('chan', "$call not in table, dropped"); + return; + } } last SWITCH; } @@ -417,6 +480,15 @@ sub normal } if ($pcno == 23 || $pcno == 27) { # WWV info + + # route 'foreign' pc27s + if ($pcno == 27) { + if ($field[8] ne $main::mycall) { + route($field[8], $line); + return; + } + } + # do some de-duping my $d = cltounix($field[1], sprintf("%02d18Z", $field[2])); my $sfi = unpad($field[3]); @@ -459,8 +531,8 @@ sub normal } if ($pcno == 25) { # merge request - unless ($field[1] eq $main::mycall) { - dbg('chan', "merge request to $field[1] from $field[2] ignored"); + if ($field[1] ne $main::mycall) { + route($field[1], $line); return; } @@ -471,7 +543,7 @@ sub normal my @in = reverse Spot::search(1, undef, undef, 0, $field[3]-1); my $in; foreach $in (@in) { - $self->send(pc26(@{$in}[0..4], $in->[7])); + $self->send(pc26(@{$in}[0..4], $field[2])); } } @@ -480,14 +552,18 @@ sub normal my @in = reverse Geomag::search(0, $field[4], time, 1); my $in; foreach $in (@in) { - $self->send(pc27(@{$in})); + $self->send(pc27(@{$in}[0..5], $field[2])); } } return; } - + if (($pcno >= 28 && $pcno <= 33) || $pcno == 40 || $pcno == 42 || $pcno == 49) { # mail/file handling - DXMsg::process($self, $line); + if ($field[1] eq $main::mycall) { + DXMsg::process($self, $line); + } else { + route($field[1], $line); + } return; } @@ -499,7 +575,10 @@ sub normal unless ($field[3] =~ /rcmd/i || !$cref || !$ref || $cref->mynode->call ne $ref->homenode) { # not allowed to relay RCMDS! if ($ref->{priv}) { # you have to have SOME privilege, the commands have further filtering $self->{remotecmd} = 1; # for the benefit of any command that needs to know + my $oldpriv = $self->{priv}; + $self->{priv} = $ref->{priv}; # assume the user's privilege level my @in = (DXCommandmode::run_cmd($self, $field[3])); + $self->{priv} = $oldpriv; for (@in) { s/\s*$//og; $self->send(pc35($main::mycall, $field[2], "$main::mycall:$_")); @@ -532,10 +611,8 @@ sub normal return; } - if ($pcno == 37) { - last SWITCH; - } - + # for pc 37 see 44 onwards + if ($pcno == 38) { # node connected list from neighbour return; } @@ -572,25 +649,21 @@ sub normal if ($pcno == 43) { last SWITCH; } - if ($pcno == 44) { - last SWITCH; - } - if ($pcno == 45) { - last SWITCH; - } - if ($pcno == 46) { - last SWITCH; - } - if ($pcno == 47) { - last SWITCH; - } - if ($pcno == 48) { - last SWITCH; + if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47 || $pcno == 49) { + if ($field[1] eq $main::mycall) { + ; + } else { + route($field[1], $line); + } + return; } if ($pcno == 50) { # keep alive/user list - my $ref = DXCluster->get_exact($field[1]); - $ref->update_users($field[2]) if $ref; + my $node = DXCluster->get_exact($field[1]); + if ($node) { + return unless $node->dxchan == $self; + $node->update_users($field[2]); + } last SWITCH; } @@ -700,7 +773,7 @@ sub finish delete $pings{$call}; # now broadcast to all other ak1a nodes that I have gone - broadcast_ak1a(pc21($call, 'Gone.'), $self); + broadcast_ak1a(pc21($call, 'Gone.'), $self) unless $self->{isolate}; Log('DXProt', $call . " Disconnected"); $ref->del() if $ref; @@ -937,7 +1010,7 @@ sub get_all_user_calls sub get_hops { - my ($pcno) = @_; + my $pcno = shift; my $hops = $DXProt::hopcount{$pcno}; $hops = $DXProt::def_hopcount if !$hops; return "H$hops";