X-Git-Url: http://www.dxcluster.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProtHandle.pm;h=43e5670cf4d511311658ecf6cd9e6875bf17d8b0;hb=cd5b993f99b52d3c3c51779e9ea1fa150232225e;hp=166d56439f12c925cb50f7ffb92032fd460c39fb;hpb=2255cfd184e50c01e1b655961a59ae050147aa79;p=spider.git diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index 166d5643..43e5670c 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -171,13 +171,13 @@ sub handle_11 # convert the date to a unix date my $d = cltounix($_[3], $_[4]); # bang out (and don't pass on) if date is invalid or the spot is too old (or too young) - if (!$d || ($pcno == 11 && ($d < $main::systime - $pc11_max_age || $d > $main::systime + 900))) { + if (!$d || (($pcno == 11 || $pcno == 61) && ($d < $main::systime - $pc11_max_age || $d > $main::systime + 900))) { dbg("PCPROT: Spot ignored, invalid date or out of range ($_[3] $_[4])\n") if isdbg('chanerr'); return; } # is it 'baddx' - if ($baddx->in($_[2]) || BadWords::check($_[2]) || $_[2] =~ /COCK/) { + if ($baddx->in($_[2]) || BadWords::check($_[2])) { dbg("PCPROT: Bad DX spot, ignored") if isdbg('chanerr'); return; } @@ -197,7 +197,7 @@ sub handle_11 } } - my @spot = Spot::prepare($_[1], $_[2], $d, $_[5], $nossid, $_[7]); + my @spot = Spot::prepare($_[1], $_[2], $d, $_[5], $nossid, $_[7], $_[8]); # global spot filtering on INPUT if ($self->{inspotsfilter}) { my ($filter, $hops) = $self->{inspotsfilter}->it(@spot); @@ -1353,7 +1353,10 @@ sub _decode_pc92_call my $is_node = $flag & 4; my $is_extnode = $flag & 2; my $here = $flag & 1; - return ($call, $is_node, $is_extnode, $here, $part[1], $part[2]); + my $ip = $part[3]; + $ip ||= $part[1] if $part[1] && ($part[1] =~ /^(?:\d+\.)+/ || $part[1] =~ /^(?:(?:[abcdef\d]+)?,)+/); + $ip =~ s/,/:/g if $ip; + return ($call, $is_node, $is_extnode, $here, $part[1], $part[2], $ip); } # decode a pc92 call: flag call : version : build @@ -1364,7 +1367,7 @@ sub _encode_pc92_call # plain call or value return $ref unless ref $ref; - my $ext = shift; + my $ext = shift || 0; my $flag = 0; my $call = $ref->call; my $extra = ''; @@ -1373,14 +1376,17 @@ sub _encode_pc92_call $flag |= 4; my $dxchan = DXChannel::get($call); $flag |= 2 if $call ne $main::mycall && $dxchan && !$dxchan->{do_pc9x}; - if ($ext) { - if ($ref->version) { - my $version = $ref->version || 1.0; - $version = $version * 100 + 5300 if $version < 50; - $extra .= ":" . $version; - } + if (($ext & 1) && $ref->version) { + my $version = $ref->version || 1.0; + $version = $version * 100 + 5300 if $version < 50; + $extra .= ":" . $version; } } + if (($ext & 2) && $ref->ip) { + my $ip = $ref->ip; + $ip =~ s/:/,/g; + $extra .= ':' . $ip; + } return "$flag$call$extra"; } @@ -1394,18 +1400,29 @@ sub _add_thingy my $dxchan = shift; my $hops = shift; - my ($call, $is_node, $is_extnode, $here, $version, $build) = @$s; + my ($call, $is_node, $is_extnode, $here, $version, $build, $ip) = @$s; my @rout; if ($call) { + my $ncall = $parent->call; if ($is_node) { - dbg("ROUTE: added node $call to " . $parent->call) if isdbg('routelow'); - @rout = $parent->add($call, $version, Route::here($here)); + dbg("ROUTE: added node $call to $ncall") if isdbg('routelow'); + @rout = $parent->add($call, $version, Route::here($here), $ip); my $r = Route::Node::get($call); $r->PC92C_dxchan($dxchan->call, $hops) if $r; + if ($ip) { + $r->ip($ip); + Log('DXProt', "PC92A $call -> $ip on $ncall"); + } } else { - dbg("ROUTE: added user $call to " . $parent->call) if isdbg('routelow'); - @rout = $parent->add_user($call, Route::here($here)); + dbg("ROUTE: added user $call to $ncall") if isdbg('routelow'); + @rout = $parent->add_user($call, Route::here($here), $ip); + $dxchan->tell_buddies('loginb', $call, $ncall) if $dxchan; + my $r = Route::User::get($call); + if ($ip) { + $r->ip($ip); + Log('DXProt', "PC92A $call -> $ip on $ncall"); + } } if ($pc92_slug_changes && $parent == $main::routeroot) { $things_add{$call} = Route::get($call); @@ -1419,6 +1436,7 @@ sub _del_thingy { my $parent = shift; my $s = shift; + my $dxchan = shift; my ($call, $is_node, $is_extnode, $here, $version, $build) = @$s; my @rout; if ($call) { @@ -1428,9 +1446,12 @@ sub _del_thingy dbg("ROUTE: deleting node $call from " . $parent->call) if isdbg('routelow'); @rout = $ref->del($parent) if $ref; } else { - $ref = Route::User::get($call); dbg("ROUTE: deleting user $call from " . $parent->call) if isdbg('routelow'); - @rout = $parent->del_user($ref) if $ref; + $ref = Route::User::get($call); + if ($ref) { + $dxchan->tell_buddies('logoutb', $call, $parent->call) if $dxchan; + @rout = $parent->del_user($ref); + } } if ($pc92_slug_changes && $parent == $main::routeroot) { $things_del{$call} = $ref unless exists $things_add{$call}; @@ -1755,12 +1776,13 @@ sub handle_92 push @radd, $add if $add; } - # do a pass through removing any references to either locally connected nodes or mycall + # do a pass through removing any references to either mycall my @nent; for (@ent) { + my $dxc; next unless $_ && @$_; - if ($_->[0] eq $main::mycall || DXChannel::get($_->[0])) { - dbg("PCPROT: $_->[0] refers to locally connected node, ignored") if isdbg('chanerr'); + if ($_->[0] eq $main::mycall) { + dbg("PCPROT: $_->[0] refers to me, ignored") if isdbg('chanerr'); next; } push @nent, $_; @@ -1772,7 +1794,7 @@ sub handle_92 } } elsif ($sort eq 'D') { for (@nent) { - push @rdel, _del_thingy($parent, $_); + push @rdel, _del_thingy($parent, $_, $self); } } elsif ($sort eq 'C') { my (@nodes, @users); @@ -1806,10 +1828,10 @@ sub handle_92 } # del users here foreach my $r (@$dnodes) { - push @rdel,_del_thingy($parent, [$r, 1]); + push @rdel,_del_thingy($parent, [$r, 1], $self); } foreach my $r (@$dusers) { - push @rdel,_del_thingy($parent, [$r, 0]); + push @rdel,_del_thingy($parent, [$r, 0], $self); } # remember this last PC92C for rebroadcast on demand @@ -1836,6 +1858,42 @@ sub handle_92 $self->broadcast_route_pc9x($pcall, undef, $line, 0); } +# get all the routes for a thing, bearing in mind that the thing (e.g. a user) +# might be on two or more nodes at the same time or that there may be more than +# one equal distance neighbour to a node. +# +# What this means that if sh/route g1tlh shows that he is on (say) two nodes, then +# a Route::findroutes is done on each of those two nodes, the best route(s) taken from +# each and then combined to give a set of dxchans to send the PC9x record down +# +sub find_pc9x_routes +{ + my $to = shift; + my $ref = Route::get($to); + my @parent; + my %cand; + + if ($ref->isa('Route::User')) { + my $dxchan = DXChannel::get($to); + push @parent, $to if $dxchan; + push @parent, $ref->parents; + } else { + @parent = $to; + } + foreach my $p (@parent) { + my $lasthops; + my @routes = Route::findroutes($p); + foreach my $r (@routes) { + $lasthops = $r->[0] unless defined $lasthops; + if ($r->[0] == $lasthops) { + $cand{$r->[1]->call} = $r->[1]; + } else { + last; + } + } + } + return values %cand; +} sub handle_93 { @@ -1896,45 +1954,26 @@ sub handle_93 # if it is routeable then then treat it like a talk my $ref = Route::get($to); if ($ref) { - # local talks my $dxchan; - $dxchan = DXChannel::get($main::myalias) if $to eq $main::mycall; - $dxchan = DXChannel::get($to) unless $dxchan; - # 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 + # convert to PC10 or local talks where appropriate # PC93 capable nodes of the same hop count all get a copy # if there is a PC10 node then it will get a copy and that # will be it. Hopefully such a node will not figure highly # in the route list, unless it is local, 'cos it don't issue PC92s! - my @routes = Route::findroutes($to); + # note that both local and PC93s at the same time are possible if the + # user on more than one node. + my @routes = find_pc9x_routes($to); my $lasthops; - foreach my $r (@routes) { - $lasthops = $r->[0] unless defined $lasthops; - if ($r->[0] == $lasthops) { - $dxchan = $r->[1]; - if (ref $dxchan && $dxchan->isa('DXChannel')) { - if ($dxchan->{do_pc9x}) { - $dxchan->send($line); - } else { - $dxchan->talk($from, $to, $via, $text, $onode); - last; - } + foreach $dxchan (@routes) { + if (ref $dxchan && $dxchan->isa('DXChannel')) { + if ($dxchan->{do_pc9x}) { + $dxchan->send($line); } else { - dbg("ERROR: $to -> $dxchan is not a DXChannel! (convert to pc10)"); + $dxchan->talk($from, $to, $via, $text, $onode); } } else { - last; + dbg("ERROR: $to -> $dxchan is not a DXChannel! (convert to pc10)"); } } return;