- 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, $_[2], $_[3], $_[4]);
-}
-
-sub handle_42 {goto &handle_28}
-
-
-# database
-sub handle_44 {goto &handle_37}
-sub handle_45 {goto &handle_37}
-sub handle_46 {goto &handle_37}
-sub handle_47 {goto &handle_37}
-sub handle_48 {goto &handle_37}
-
-# message and database
-sub handle_49
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
-
- if (eph_dup($line)) {
- dbg("PCPROT: Dup PC49 ignored\n") if isdbg('chanerr');
- return;
- }
-
- if ($_[1] eq $main::mycall) {
- DXMsg::handle_49($self, @_);
- } else {
- $self->route($_[1], $line) unless $self->is_clx;
- }
-}
-
-# keep alive/user list
-sub handle_50
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
-
- my $call = $_[1];
- my $node = Route::Node::get($call);
- if ($node) {
- return unless $node->call eq $self->{call};
- $node->usercount($_[2]);
-
- # input filter if required
- return unless $self->in_filter_route($node);
-
- $self->route_pc50($node, $_[2], $_[3]) unless eph_dup($line);
- }
-}
-
-# incoming ping requests/answers
-sub handle_51
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
- my $to = $_[1];
- my $from = $_[2];
- my $flag = $_[3];
-
-
- # is it for us?
- if ($to eq $main::mycall) {
- if ($flag == 1) {
- $self->send(pc51($from, $to, '0'));
- } else {
- # it's a reply, look in the ping list for this one
- my $ref = $pings{$from};
- if ($ref) {
- my $tochan = DXChannel->get($from);
- while (@$ref) {
- my $r = shift @$ref;
- my $dxchan = DXChannel->get($r->{call});
- next unless $dxchan;
- my $t = tv_interval($r->{t}, [ gettimeofday ]);
- if ($dxchan->is_user) {
- my $s = sprintf "%.2f", $t;
- my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t;
- $dxchan->send($dxchan->msg('pingi', $from, $s, $ave))
- } elsif ($dxchan->is_node) {
- if ($tochan) {
- my $nopings = $tochan->user->nopings || 2;
- 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
- if ($t > $tochan->{pingint} && $t < 2 * $tochan->{pingint} ) {
- $t -= $tochan->{pingint};
- }
-
- # 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
- }
- }
- }
- }
- }
- } else {
- if (eph_dup($line)) {
- dbg("PCPROT: dup PC51 detected") if isdbg('chanerr');
- return;
- }
- # route down an appropriate thingy
- $self->route($to, $line);
- }
-}
-
-# dunno but route it
-sub handle_75
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
- my $call = $_[1];
- if ($call ne $main::mycall) {
- $self->route($call, $line);
- }
-}
-
-# WCY broadcasts
-sub handle_73
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
- my $call = $_[1];
-
- # do some de-duping
- my $d = cltounix($call, sprintf("%02d18Z", $_[2]));
- if (($pcno == 23 && $d < $main::systime - $pc23_max_age) || $d > $main::systime + 1500 || $_[2] < 0 || $_[2] > 23) {
- dbg("PCPROT: WCY Date ($call $_[2]) out of range") if isdbg('chanerr');
- return;
- }
- @_ = map { unpad($_) } @_;
- if (WCY::dup($d)) {
- dbg("PCPROT: Dup WCY Spot ignored\n") if isdbg('chanerr');
- return;
- }
-
- my $wcy = WCY::update($d, @_[2..12]);
-
- my $rep;
- eval {
- $rep = Local::wcy($self, @_[1..12]);
- };
- # dbg("Local::wcy error $@") if isdbg('local') if $@;
- return if $rep;
-
- # broadcast to the eager world
- send_wcy_spot($self, $line, $d, @_[2..12]);
-}
-
-# remote commands (incoming)
-sub handle_84
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
- $self->process_rcmd($_[1], $_[2], $_[3], $_[4]);
-}
-
-# remote command replies
-sub handle_85
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
- $self->process_rcmd_reply($_[1], $_[2], $_[3], $_[4]);
-}
-
-# if get here then rebroadcast the thing with its Hop count decremented (if
-# there is one). If it has a hop count and it decrements to zero then don't
-# rebroadcast it.
-#
-# NOTE - don't arrive here UNLESS YOU WANT this lump of protocol to be
-# REBROADCAST!!!!
-#
-
-sub handle_default
-{
- my $self = shift;
- my $pcno = shift;
- my $line = shift;
-
- if (eph_dup($line)) {
- dbg("PCPROT: Ephemeral dup, dropped") if isdbg('chanerr');
- } else {
- unless ($self->{isolate}) {
- DXChannel::broadcast_nodes($line, $self); # send it to everyone but me
- }
- }
-}
-
-#
-# This is called from inside the main cluster processing loop and is used
-# for despatching commands that are doing some long processing job
-#
-sub process
-{
- my $t = time;
- my @dxchan = DXChannel->get_all();
- my $dxchan;
- my $pc50s;
-
- # send out a pc50 on EVERY channel all at once
- if ($t >= $last_pc50 + $DXProt::pc50_interval) {
- $pc50s = pc50($main::me, scalar DXChannel::get_all_users);
- eph_dup($pc50s);
- $last_pc50 = $t;
- }
-
- foreach $dxchan (@dxchan) {
- next unless $dxchan->is_node();
- next if $dxchan == $main::me;
-
- # send the pc50 or PC90
- $dxchan->send($pc50s) if $pc50s;
-
- # send a ping out on this channel
- if ($dxchan->{pingint} && $t >= $dxchan->{pingint} + $dxchan->{lastping}) {
- if ($dxchan->{nopings} <= 0) {
- $dxchan->disconnect;
- } else {
- addping($main::mycall, $dxchan->call);
- $dxchan->{nopings} -= 1;
- $dxchan->{lastping} = $t;
- }
- }
- }
-
- # every ten seconds
- if ($t - $last10 >= 10) {
- # clean out ephemera
-
- eph_clean();
-
- $last10 = $t;
- }
-