1. fix set/lockout so that it is possible to lock out all SSIDs except those
authorminima <minima>
Thu, 20 Sep 2001 14:13:11 +0000 (14:13 +0000)
committerminima <minima>
Thu, 20 Sep 2001 14:13:11 +0000 (14:13 +0000)
specifically unlocked and so that you don't need to lock the non-SSID call in
order to lock an SSID call. So set/lock g1tlh will lock out all instances of
g1tlh, g1tlh-1, g1tlh-15 etc except (for instance) unset/lock g1tlh-9.
2. show/lock allows partial callsign matching so sh/lock gb7 will only show
GB7* calls that are locked.
3. Had a grand shift around for the start of NP.

24 files changed:
Changes
cmd/announce.pl
cmd/forward/opername.pl
cmd/kill.pl
cmd/links.pl
cmd/set/here.pl
cmd/set/homenode.pl
cmd/set/location.pl
cmd/set/name.pl
cmd/set/qra.pl
cmd/set/qth.pl
cmd/set/sys_location.pl
cmd/show/lockout.pl
cmd/unset/here.pl
cmd/who.pl
cmd/wx.pl
html/newprot.html
perl/DXChannel.pm
perl/DXCommandmode.pm
perl/DXCron.pm
perl/DXMsg.pm
perl/DXProt.pm
perl/QXProt.pm [new file with mode: 0644]
perl/cluster.pl

diff --git a/Changes b/Changes
index 4ad8dd8aeb15cf3b8e7a5d4712f15685693acdad..8363ca58964814ceb1b33eca6fe150bf736d56e1 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,11 @@
+21Sep01=======================================================================
+1. fix set/lockout so that it is possible to lock out all SSIDs except those
+specifically unlocked and so that you don't need to lock the non-SSID call in
+order to lock an SSID call. So set/lock g1tlh will lock out all instances of
+g1tlh, g1tlh-1, g1tlh-15 etc except (for instance) unset/lock g1tlh-9.
+2. show/lock allows partial callsign matching so sh/lock gb7 will only show
+GB7* calls that are locked.
+3. Had a grand shift around for the start of NP.
 19Sep01=======================================================================
 1. put in some rudimentory rsfp checking for various things
 2. tried to do some fixes on console.pl - YOU WILL REQUIRE Curses 1.06 from
index df7b91d0f54b7913ff423ae64a5981c6e9cf661d..0ea2e12fdf8bbcf8369d75bb59f8be724a91f3e8 100644 (file)
@@ -54,10 +54,10 @@ if (@bad = BadWords::check($line)) {
 
 return (1, $self->msg('dup')) if AnnTalk::dup($from, $toflag, $line);
 Log('ann', $to, $from, $line);
-DXProt::broadcast_list("To $to de $from <$t>: $line", 'ann', undef, @locals);
+DXChannel::broadcast_list("To $to de $from <$t>: $line", 'ann', undef, @locals);
 if ($to ne "LOCAL") {
   my $pc = DXProt::pc12($from, $line, $tonode, $sysopflag, 0);
-  DXProt::broadcast_ak1a($pc);
+  DXChannel::broadcast_nodes($pc);
 }
 
 return (1, ());
index 1daaa1c3291b69cafc2b47cd6f650b787985749e..91acc8b4c9eb173be8a8ecae1fca7897e033682b 100644 (file)
@@ -32,29 +32,29 @@ foreach $call (@f) {
                my $qra = $ref->qra;
                my $latlong = DXBearing::lltos($lat, $long) if $lat && $long;
                if ($name) {
-                       my $l = DXProt::pc41($DXProt::me, $call, 1, $name);
+                       my $l = DXProt::pc41($main::me, $call, 1, $name);
                        DXProt::eph_dup($l);
-                       DXProt::broadcast_all_ak1a($l, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($l, $main::me) ;
                }
                if ($qth) {
                        my $l = DXProt::pc41($call, 2, $qth);
                        DXProt::eph_dup($l);
-                       DXProt::broadcast_all_ak1a($l, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($l, $main::me) ;
                }
                if ($latlong) {
                        my $l = DXProt::pc41($call, 3, $latlong);
                        DXProt::eph_dup($l);
-                       DXProt::broadcast_all_ak1a($l, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($l, $main::me) ;
                }
                if ($node) {
                        my $l = DXProt::pc41($call, 4, $node);
                        DXProt::eph_dup($l);
-                       DXProt::broadcast_all_ak1a($l, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($l, $main::me) ;
                }
                if ($qra) {
                        my $l = DXProt::pc41($call, 5, $qra);
                        DXProt::eph_dup($l);
-                       DXProt::broadcast_all_ak1a($l, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($l, $main::me) ;
                }
        }
 }
index ab7bb511a9082f4902f10a1d0bc90a918504af18..de533bdcabad29f3f276dadf89ced44f21bb5ceb 100644 (file)
@@ -64,7 +64,7 @@ while (@f) {
 foreach $ref ( @refs) {
        Log('msg', "Message $ref->{msgno} from $ref->{from} to $ref->{to} deleted by $call");
        if ($full) {
-               DXProt::broadcast_ak1a(DXProt::pc49($ref->{from}, $ref->{subject}), $DXProt::me);
+               DXChannel::broadcast_nodes(DXProt::pc49($ref->{from}, $ref->{subject}), $main::me);
        }
        my $tonode = $ref->tonode;
        $ref->stop_msg($tonode) if $tonode;
index 648ebba43909eb4348ab4411ede5f5ea1dcada87..463a4e4f91bd58f5126df2f7cc4cca1e1044f10a 100644 (file)
@@ -20,7 +20,7 @@ foreach $dxchan ( sort {$a->call cmp $b->call} DXChannel::get_all_nodes ) {
        my $t = cldatetime($dxchan->startt);
        my $sort;
        my $name = $dxchan->user->name || " ";
-       my $ping = $dxchan->is_node && $dxchan != $DXProt::me ? sprintf("%8.2f",
+       my $ping = $dxchan->is_node && $dxchan != $main::me ? sprintf("%8.2f",
                                                                                                                                        $dxchan->pingave) : "";
        $sort = "DXSP" if $dxchan->is_spider;
        $sort = "CLX " if $dxchan->is_clx;
index 44fc4d4b99ca234a1fb8bb63c6f37b35894e847c..1c4b167cb0bc942837b268bdb6ad4a1563a513f9 100644 (file)
@@ -25,7 +25,7 @@ foreach $call (@args) {
                        $ref->here(1);
                        my $s = DXProt::pc24($ref);
                        DXProt::eph_dup($s);
-                       DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($s, $main::me) ;
                }
        } else {
                push @out, $self->msg('e3', "Set Here", $call);
index cf8d97154d60a0316359452bd061c0b65554380a..b2d7d34280347b4d5b5a8c08c021b642bfe92b1e 100644 (file)
@@ -24,7 +24,7 @@ if ($user) {
        $user->put();
        my $s = DXProt::pc41($call, 4, $line);
        DXProt::eph_dup($s);
-       DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+       DXChannel::broadcast_all_nodes($s, $main::me) ;
        return (1, $self->msg('hnode', $line));
 } else {
        return (1, $self->msg('namee2', $call));
index f4ee0358a496c0654937cc67d5482fb56b841db3..9d31dcf50d723680bbdccfc0823e0d5efddae2c5 100644 (file)
@@ -30,7 +30,7 @@ if ($user) {
                my $l = DXBearing::lltos($lat, $long);
                my $s = DXProt::pc41($call, 3, $l);
                DXProt::eph_dup($s);
-               DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+               DXChannel::broadcast_all_nodes($s, $main::me) ;
        }
        my $qra = DXBearing::lltoqra($lat, $long);
        my $oldqra = $user->qra || "";
@@ -38,7 +38,7 @@ if ($user) {
                $user->qra($qra);
                my $s = DXProt::pc41($call, 5, $qra);
                DXProt::eph_dup($s);
-               DXProt::broadcast_all_ak1a($s, $DXProt::me);
+               DXChannel::broadcast_all_nodes($s, $main::me);
        }
        
        $user->put();
index 3291757455974a77f209057463d7a199b2459a36..4bffef41cabe0de2ee72785bcb77b71df980d9ce 100644 (file)
@@ -23,7 +23,7 @@ if ($user) {
        $user->put();
        my $s = DXProt::pc41($call, 1, $line);
        DXProt::eph_dup($s);
-       DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+       DXChannel::broadcast_all_nodes($s, $main::me) ;
        return (1, $self->msg('name', $line));
 } else {
        return (1, $self->msg('namee2', $call));
index 60c6dc1603fcad5b40463f86e559e6041e844d03..4bae21c3c5f396ba582be37e62a56f6423a68237 100644 (file)
@@ -25,7 +25,7 @@ if ($user) {
                $user->qra($qra);
                my $s = DXProt::pc41($call, 5, $qra);
                DXProt::eph_dup($s);
-               DXProt::broadcast_all_ak1a($s, $DXProt::me);
+               DXChannel::broadcast_all_nodes($s, $main::me);
        }
        my ($lat, $long) = DXBearing::qratoll($qra);
        my $oldlat = $user->lat || 0;
@@ -36,7 +36,7 @@ if ($user) {
                my $l = DXBearing::lltos($lat, $long);
                my $s = DXProt::pc41($call, 3, $l);
                DXProt::eph_dup($s);
-               DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+               DXChannel::broadcast_all_nodes($s, $main::me) ;
        }
        
        $user->put();
index 2b696f94c29d05064ca9f4ce90646bd94a43a405..4a5a881fbbf7aac29797272e208983a72a425b4b 100644 (file)
@@ -23,7 +23,7 @@ if ($user) {
        $user->put();
        my $s = DXProt::pc41($call, 2, $line);
        DXProt::eph_dup($s);
-       DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+       DXChannel::broadcast_all_nodes($s, $main::me) ;
        return (1, $self->msg('qth', $line));
 } else {
        return (1, $self->msg('namee2', $call));
index 903a5796526e7173074aabae7ed31b1495d8889c..aac91823a694117ff464107b070acee534971f1a 100644 (file)
@@ -25,7 +25,7 @@ if ($user) {
        my ($lat, $long) = DXBearing::stoll($line);
        $user->lat($lat);
        $user->long($long);
-       DXProt::broadcast_all_ak1a(DXProt::pc41($call, 3, $line), $DXProt::me);
+       DXChannel::broadcast_all_nodes(DXProt::pc41($call, 3, $line), $main::me);
        if (!$user->qra) {
                my $qra = DXBearing::lltos($lat, $long);
                $user->qra($qra);
index 04d1ef12fca5529f62e447b032e0e2b82d7407cd..f4c87a87c668a767fdb6719e879d643b6fce4201 100644 (file)
@@ -15,13 +15,20 @@ my @out;
 
 use DB_File;
 
+if ($line) {
+       $line =~ s/[^\w-\/]+//g;
+       $line = "^\U\Q$line";
+}
+
 my ($action, $count, $key, $data) = (0,0,0,0);
 for ($action = DXUser::R_FIRST, $count = 0; !$DXUser::dbm->seq($key, $data, $action); $action = DXUser::R_NEXT) {
        if ($data =~ m{lockout =>}) {
-               my $u = DXUser->get_current($key);
-               if ($u && $u->lockout) {
-                       push @out, $key;
-                       ++$count;
+               if ($line && $key =~ /$line/) {
+                       my $u = DXUser->get_current($key);
+                       if ($u && $u->lockout) {
+                               push @out, $key;
+                               ++$count;
+                       }
                }
        }
 } 
index 4da517c111cfe252d9fde761d317cdae619026ee..19db8dbd9ffdb647bf55e85426f981cf25a15dd0 100644 (file)
@@ -25,7 +25,7 @@ foreach $call (@args) {
                        $ref->here(0);
                        my $s = DXProt::pc24($ref);
                        DXProt::eph_dup($s);
-                       DXProt::broadcast_all_ak1a($s, $DXProt::me) ;
+                       DXChannel::broadcast_all_nodes($s, $main::me) ;
                }
        } else {
                push @out, $self->msg('e3', "Unset Here", $call);
index ecb45d70f8eff3167934e57522cd62c078f4b05d..6ec7dba36a9b97a7f2776156f0b0fc30cf3f378d 100644 (file)
@@ -26,7 +26,7 @@ foreach $dxchan ( sort {$a->call cmp $b->call} DXChannel::get_all ) {
                $sort = "AK1A" if $dxchan->is_ak1a;
        }
        my $name = $dxchan->user->name || " ";
-       my $ping = $dxchan->is_node && $dxchan != $DXProt::me ? sprintf("%5.2f", $dxchan->pingave) : "     ";
+       my $ping = $dxchan->is_node && $dxchan != $main::me ? sprintf("%5.2f", $dxchan->pingave) : "     ";
        my $conn = $dxchan->conn;
        my $ip = '';
        $ip = $conn->{peerhost} if $conn && $conn->{peerhost};
index cec70f4e484132fddaddf72a61af9728f099fc94..af7cd0abd785a65ba6f14dc1c4204e981a5500bb 100644 (file)
--- a/cmd/wx.pl
+++ b/cmd/wx.pl
@@ -36,11 +36,11 @@ if ($sort eq "FULL") {
   $to = "LOCAL";
 }
 
-DXProt::broadcast_list("WX de $from <$t>: $line", 'wx', undef, @locals);
+DXChannel::broadcast_list("WX de $from <$t>: $line", 'wx', undef, @locals);
 if ($to ne "LOCAL") {
   $line =~ s/\^//og;    # remove ^ characters!
   my $pc = DXProt::pc12($from, $line, $tonode, $sysopflag, 1);
-  DXProt::broadcast_ak1a($pc, $DXProt::me);
+  DXChannel::broadcast_nodes($pc, $main::me);
 }
 
 return (1, ());
index c34a5354cc1401ce55f711af195182bcf871085c..1bb84fe237ba78ed4528e3097ba45f77ee01bbff 100644 (file)
@@ -32,7 +32,8 @@ become stretched to beyond breaking point. Some attempts have been made to
 extend it, but none have done what is actually required: which is to throw it
 away completely and start from scratch.</p>
 
-<p>This is an attempt at starting again.</p>
+<p>This is an attempt at starting again. In fit of originality I am calling
+it "New Protocol" or "NP" for short</p>
 
 <h3>Design Criteria</h3>
 <ul>
@@ -111,12 +112,12 @@ away completely and start from scratch.</p>
 
 <p></p>
 
-<p>Each protocol line is separate and distinct. This is a "datagram" style
-protocol. Each protocol line is called a "sentence" and begins with the
-string "DX" in upper case, followed by two digits. The sentence is terminated
-by a &lt;cr&gt; or a &lt;lf&gt; character or both. Internally, the
-terminating characters should be discarded completely and the sentence
-processed without.</p>
+<p>Each protocol line is separate and distinct and is called a "sentence".
+This is a "datagram" style protocol. Each protocol line is called a
+"sentence" and begins with the string "QX" in upper case, followed by two
+digits. The sentence is terminated by a &lt;cr&gt; or a &lt;lf&gt; character
+or both. Internally, the terminating characters should be discarded
+completely and the sentence processed without.</p>
 
 <p>The character set used shall be ISO-Latin-1, with only the characters 0x20
 -&gt; 0x7e permitted within a sentence. All other characters shall be "HTML
@@ -140,34 +141,69 @@ digits&gt; of the checksum itself.  The purpose of the checksum is to check
 that no intermediate node has changed the sentence. It is assumed that the
 underlying transport mechanisms will deal with communications errors.</p>
 
-<p>All sentences shall have an &lt;origin&gt;, a &lt;serial&gt; and a
-&lt;destination&gt; number. The &lt;destination&gt; can be empty which implies
-that this sentence is to be broadcast. The &lt;serial&gt; number is a global
-number, which is used for all sentences originating at a node, that is
-incremented modulo 10000, and is used to determine duplicate or out of date
-sentences.</p>
+<p>All sentences shall have an &lt;origin&gt; and a &lt;destination&gt;
+number. The &lt;destination&gt; can be empty which implies that this sentence
+is to be broadcast. </p>
 
 <p>So the generic form of a sentence is:-</p>
 
 <p></p>
 
 <blockquote class="code">
-  DX99|&lt;origin&gt;|&lt;serial&gt;|&lt;destination&gt;|...|&lt;cs&gt;</blockquote>
+  QX99|&lt;destination&gt;|&lt;origin&gt;|...|&lt;cs&gt;</blockquote>
 
 <p></p>
 
 <p>Some examples:-</p>
 
 <blockquote class="code">
-  DX01|GB7TLH|0|GB7DJK|DXSpider 1.48/53.287|DE450A30|F4<br>
-  DX01|GB7DJK|345|GB7TLH|DXSpider 1.49/60.45|4532DA56|A1<br>
-  DX11|GB7TLH|1||G1TLH|FR0G|164563|14001.1|Easy|53<br>
-  DX10|GB7TLH|2||G1TLH|SYSOP|GB7TLH rebooting|4A<br>
-  DX02|GB7TLH|3|GB7MBC|1|98012349|5D<br>
-  DX02|GB7MBC|9356|GB7TLH|0|GB7DJK/0.76,GB7BAA/1.2|AE<br>
+  QX01|GB7TLH|GB7DJK|1|DXSpider:1.48:53.287|90001FFF|5234FE12|DE450A30|F4<br>
+  QX01|GB7DJK|GB7TLH|1|DXSpider:1.49:60.45|90002010|AD412458|4532DA56|A1<br>
+  QX11||GB7TLH|1|G1TLH|FR0G|164563|14001.1|Easy|53<br>
+  QX10||GB7TLH|2|G1TLH|SYSOP|GB7TLH rebooting|4A<br>
 </blockquote>
 
 <p></p>
+
+<p>Some fields are split further into subfields. The separator character
+shall be ' :' .</p>
+
+<p>Some sentences will have serial numbers associated with them which
+functions both as a generation number and as an aid to deduplication. The
+particular usage for each type of sentence is discussed later, but the
+general form will be as a modulo 10000 number (0-9999).</p>
+
+<p></p>
+
+<h1>Initialisation</h1>
+
+<p>When a node wishes to speak NP it shall send a "QX01" initialisation
+sentence to the other node on connection. It does not wait, it connects and
+sends. Both sides of the connection send simultaniously and symetrically. The
+fields currently in this sentence are:-</p>
+
+<p><span class="code">QX01|&lt;destination&gt;|&lt;origin&gt;|&lt;protocol
+version&gt;|&lt;software
+info&gt;|&lt;time&gt;|&lt;random&gt;|&lt;challange&gt;|&lt;cs&gt;</span> </p>
+
+<p>All NP nodes <span style="font-weight: bold">shall<span
+style="font-weight: normal"> use a cryptograph</span></span>ic challenge to
+determine that the node that they are talking to is correct. In this
+protocol, wherever a challenge is mandated, the challenge field will be the
+last field before the checksum and shall include the whole of the sentence
+upto that point as the "salt" to that challenge. </p>
+
+<p>Because we are not yet sufficiently paranoid to include full crytography,
+we will use the standard 32 bit CCITT CRC algorithm on a shared secret
+phrase, each side shall have a different phrase each known to both sides.
+Each connection shall have a different pair of phrases. Each phrase shall be
+at least 40 characters long.</p>
+
+<p>Each sentence that uses a challenge shall include some random element of
+at least 8 characters. The &lt;time&gt; field (if included) is not
+sufficient!</p>
+
+<p>Getting back to the initialisation sentence  </p>
 <hr>
 <span class="copy">Copyright Â© 2001 by Dirk Koopman G1TLH. All Rights
 Reserved</span>
index c4a81c7f509b503a9c3025217f2a3f80b45c5177..01d2135e657e834eac2bf100d5e61f2e443f6036 100644 (file)
@@ -105,6 +105,7 @@ $count = 0;
                  width => '0,Column Width',
                  disconnecting => '9,Disconnecting,yesno',
                  ann_talk => '0,Suppress Talk Anns,yesno',
+                 metric => '1,Route metric',
                 );
 
 use vars qw($VERSION $BRANCH);
@@ -521,6 +522,98 @@ sub rspfcheck
        return 0;
 }
 
+# broadcast a message to all clusters taking into account isolation
+# [except those mentioned after buffer]
+sub broadcast_nodes
+{
+       my $s = shift;                          # the line to be rebroadcast
+       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
+       my @dxchan = DXChannel::get_all_nodes();
+       my $dxchan;
+       
+       # send it if it isn't the except list and isn't isolated and still has a hop count
+       foreach $dxchan (@dxchan) {
+               next if grep $dxchan == $_, @except;
+               next if $dxchan == $main::me;
+               
+               my $routeit = $dxchan->can('adjust_hops') ? $dxchan->adjust_hops($s) : $s;      # adjust its hop count by node name
+
+               $dxchan->send($routeit) unless $dxchan->{isolate} || !$routeit;
+       }
+}
+
+# broadcast a message to all clusters ignoring isolation
+# [except those mentioned after buffer]
+sub broadcast_all_ak1a
+{
+       my $s = shift;                          # the line to be rebroadcast
+       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
+       my @dxchan = DXChannel::get_all_nodes();
+       my $dxchan;
+       
+       # send it if it isn't the except list and isn't isolated and still has a hop count
+       foreach $dxchan (@dxchan) {
+               next if grep $dxchan == $_, @except;
+               next if $dxchan == $main::me;
+
+               my $routeit = $dxchan->can('adjust_hops') ? $dxchan->adjust_hops($s) : $s;      # adjust its hop count by node name
+               $dxchan->send($routeit);
+       }
+}
+
+# broadcast to all users
+# storing the spot or whatever until it is in a state to receive it
+sub broadcast_users
+{
+       my $s = shift;                          # the line to be rebroadcast
+       my $sort = shift;           # the type of transmission
+       my $fref = shift;           # a reference to an object to filter on
+       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
+       my @dxchan = DXChannel::get_all_users();
+       my $dxchan;
+       my @out;
+       
+       foreach $dxchan (@dxchan) {
+               next if grep $dxchan == $_, @except;
+               push @out, $dxchan;
+       }
+       broadcast_list($s, $sort, $fref, @out);
+}
+
+
+# broadcast to a list of users
+sub broadcast_list
+{
+       my $s = shift;
+       my $sort = shift;
+       my $fref = shift;
+       my $dxchan;
+       
+       foreach $dxchan (@_) {
+               my $filter = 1;
+               next if $dxchan == $main::me;
+               
+               if ($sort eq 'dx') {
+                   next unless $dxchan->{dx};
+                       ($filter) = $dxchan->{spotsfilter}->it(@{$fref}) if ref $fref;
+                       next unless $filter;
+               }
+               next if $sort eq 'ann' && !$dxchan->{ann} && $s !~ /^To\s+LOCAL\s+de\s+(?:$main::myalias|$main::mycall)/i;
+               next if $sort eq 'wwv' && !$dxchan->{wwv};
+               next if $sort eq 'wcy' && !$dxchan->{wcy};
+               next if $sort eq 'wx' && !$dxchan->{wx};
+
+               $s =~ s/\a//og unless $dxchan->{beep};
+
+               if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') {
+                       $dxchan->send($s);      
+               } else {
+                       $dxchan->delay($s);
+               }
+       }
+}
+
+
 no strict;
 sub AUTOLOAD
 {
index 9f3c669e26922e39a7118170887048e27ff51f30..a8418bd4daf0af368947b188f8c30a534279f26d 100644 (file)
@@ -61,7 +61,7 @@ sub new
        my $pkg = shift;
        my $call = shift;
        my @rout = $main::routeroot->add_user($call, Route::here(1));
-       DXProt::route_pc16($DXProt::me, $main::routeroot, @rout) if @rout;
+       DXProt::route_pc16($main::me, $main::routeroot, @rout) if @rout;
 
        return $self;
 }
@@ -132,7 +132,7 @@ sub start
        my $lastoper = $user->lastoper || 0;
        my $homenode = $user->homenode || ""; 
        if ($homenode eq $main::mycall && $lastoper + $DXUser::lastoperinterval < $main::systime) {
-               run_cmd($DXProt::me, "forward/opernam $call");
+               run_cmd($main::me, "forward/opernam $call");
                $user->lastoper($main::systime);
        }
 
@@ -451,7 +451,7 @@ sub disconnect
        }
 
        # issue a pc17 to everybody interested
-       DXProt::route_pc17($DXProt::me, $main::routeroot, @rout) if @rout;
+       DXProt::route_pc17($main::me, $main::routeroot, @rout) if @rout;
 
        # I was the last node visited
     $self->user->node($main::mycall);
index 785a1ad93774260a048098ce002d8c687c77219d..74b65996a3e54eb4d0b2cc01ab8488a9504a7ba2 100644 (file)
@@ -286,13 +286,13 @@ sub rcmd
        return  unless $noderef && $noderef->version;
 
        # send it 
-       DXProt::addrcmd($DXProt::me, $call, $line);
+       DXProt::addrcmd($main::me, $call, $line);
 }
 
 sub run_cmd
 {
        my $line = shift;
-       my @in = DXCommandmode::run_cmd($DXProt::me, $line);
+       my @in = DXCommandmode::run_cmd($main::me, $line);
        dbg("cmd run: $line") if isdbg('cron');
        for (@in) {
                s/\s*$//og;
index 8c565797d586490f0384492319aea6b870e30d8e..ec798b54661b4dc3cd23056813db7eb9ad2ccb90 100644 (file)
@@ -389,7 +389,7 @@ sub process
                                if ($_->{from} eq $f[1] && $_->{subject} eq $f[2]) {
                                        $_->del_msg();
                                        Log('msg', "Message $_->{msgno} from $_->{from} ($_->{subject}) fully deleted");
-                                       DXProt::broadcast_ak1a($line, $self);
+                                       DXChannel::broadcast_nodes($line, $self);
                                }
                        }
                }
@@ -1111,7 +1111,7 @@ sub import_msgs
                my @msg = map { chomp; $_ } <MSG>;
                close(MSG);
                unlink($fn);
-               my @out = import_one($DXProt::me, \@msg, $splitit);
+               my @out = import_one($main::me, \@msg, $splitit);
                Log('msg', @out);
        }
 }
index 0c23663c415bf111e30f935f668369304a3e0054..e6380b563e6bc5188a640249c9d7800bc8716d76 100644 (file)
@@ -42,12 +42,11 @@ $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ ) || 0;
 $main::build += $VERSION;
 $main::branch += $BRANCH;
 
-use vars qw($me $pc11_max_age $pc23_max_age $last_pc50
+use vars qw($pc11_max_age $pc23_max_age $last_pc50
                        $last_hour $last10 %eph  %pings %rcmds $ann_to_talk
                        %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck
                        $allowzero $decode_dk0wcy $send_opernam @checklist);
 
-$me = undef;                                   # the channel id for this cluster
 $pc11_max_age = 1*3600;                        # the maximum age for an incoming 'real-time' pc11
 $pc23_max_age = 1*3600;                        # the maximum age for an incoming 'real-time' pc23
 
@@ -185,14 +184,17 @@ sub init
 {
        my $user = DXUser->get($main::mycall);
        $DXProt::myprot_version += $main::version*100;
-       $me = DXProt->new($main::mycall, 0, $user); 
-       $me->{here} = 1;
-       $me->{state} = "indifferent";
+       $main::me = DXProt->new($main::mycall, 0, $user); 
+       $main::me->{here} = 1;
+       $main::me->{state} = "indifferent";
        do "$main::data/hop_table.pl" if -e "$main::data/hop_table.pl";
        confess $@ if $@;
-       $me->{sort} = 'S';    # S for spider
-       $me->{priv} = 9;
-#      $Route::Node::me->adddxchan($me);
+       $main::me->{sort} = 'S';    # S for spider
+       $main::me->{priv} = 9;
+       $main::me->{metric} = 0;
+       $main::me->{pingave} = 0;
+       
+#      $Route::Node::me->adddxchan($main::me);
 }
 
 #
@@ -262,6 +264,7 @@ sub start
        $self->{nopings} = $user->nopings || 2;
        $self->{pingtime} = [ ];
        $self->{pingave} = 999;
+       $self->{metric} ||= 100;
        $self->{lastping} = $main::systime;
 
        # send initialisation string
@@ -1178,7 +1181,7 @@ sub normal
                dbg("PCPROT: Ephemeral dup, dropped") if isdbg('chanerr');
        } else {
                unless ($self->{isolate}) {
-                       broadcast_ak1a($line, $self); # send it to everyone but me
+                       DXChannel::broadcast_nodes($line, $self); # send it to everyone but me
                }
        }
 }
@@ -1196,14 +1199,14 @@ sub process
        
        # send out a pc50 on EVERY channel all at once
        if ($t >= $last_pc50 + $DXProt::pc50_interval) {
-               $pc50s = pc50($me, scalar DXChannel::get_all_users);
+               $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 == $me;
+               next if $dxchan == $main::me;
 
                # send the pc50
                $dxchan->send($pc50s) if $pc50s;
@@ -1252,7 +1255,7 @@ sub send_dx_spot
        # send it if it isn't the except list and isn't isolated and still has a hop count
        # taking into account filtering and so on
        foreach $dxchan (@dxchan) {
-               next if $dxchan == $me;
+               next if $dxchan == $main::me;
                next if $dxchan == $self && $self->is_node;
                $dxchan->dx_spot($line, $self->{isolate}, @_, $self->{call});
        }
@@ -1315,7 +1318,7 @@ sub send_wwv_spot
        # send it if it isn't the except list and isn't isolated and still has a hop count
        # taking into account filtering and so on
        foreach $dxchan (@dxchan) {
-               next if $dxchan == $me;
+               next if $dxchan == $main::me;
                next if $dxchan == $self && $self->is_node;
                my $routeit;
                my ($filter, $hops);
@@ -1362,7 +1365,7 @@ sub send_wcy_spot
        # send it if it isn't the except list and isn't isolated and still has a hop count
        # taking into account filtering and so on
        foreach $dxchan (@dxchan) {
-               next if $dxchan == $me;
+               next if $dxchan == $main::me;
                next if $dxchan == $self;
 
                $dxchan->wcy($line, $self->{isolate}, @_, $self->{call}, $wcy_dxcc, $wcy_itu, $wcy_cq, $org_dxcc, $org_itu, $org_cq);
@@ -1439,7 +1442,7 @@ sub send_announce
        # send it if it isn't the except list and isn't isolated and still has a hop count
        # taking into account filtering and so on
        foreach $dxchan (@dxchan) {
-               next if $dxchan == $me;
+               next if $dxchan == $main::me;
                next if $dxchan == $self && $self->is_node;
                $dxchan->announce($line, $self->{isolate}, $to, $target, $text, @_, $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq);
        }
@@ -1532,103 +1535,13 @@ sub route
        if ($dxchan) {
                my $routeit = adjust_hops($dxchan, $line);   # adjust its hop count by node name
                if ($routeit) {
-                       $dxchan->send($routeit) unless $dxchan == $me;
+                       $dxchan->send($routeit) unless $dxchan == $main::me;
                }
        } else {
                dbg("PCPROT: No route available, dropped") if isdbg('chanerr');
        }
 }
 
-# broadcast a message to all clusters taking into account isolation
-# [except those mentioned after buffer]
-sub broadcast_ak1a
-{
-       my $s = shift;                          # the line to be rebroadcast
-       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
-       my @dxchan = DXChannel::get_all_nodes();
-       my $dxchan;
-       
-       # send it if it isn't the except list and isn't isolated and still has a hop count
-       foreach $dxchan (@dxchan) {
-               next if grep $dxchan == $_, @except;
-               next if $dxchan == $me;
-               
-               my $routeit = adjust_hops($dxchan, $s);      # adjust its hop count by node name
-               $dxchan->send($routeit) unless $dxchan->{isolate} || !$routeit;
-       }
-}
-
-# broadcast a message to all clusters ignoring isolation
-# [except those mentioned after buffer]
-sub broadcast_all_ak1a
-{
-       my $s = shift;                          # the line to be rebroadcast
-       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
-       my @dxchan = DXChannel::get_all_nodes();
-       my $dxchan;
-       
-       # send it if it isn't the except list and isn't isolated and still has a hop count
-       foreach $dxchan (@dxchan) {
-               next if grep $dxchan == $_, @except;
-               next if $dxchan == $me;
-
-               my $routeit = adjust_hops($dxchan, $s);      # adjust its hop count by node name
-               $dxchan->send($routeit);
-       }
-}
-
-# broadcast to all users
-# storing the spot or whatever until it is in a state to receive it
-sub broadcast_users
-{
-       my $s = shift;                          # the line to be rebroadcast
-       my $sort = shift;           # the type of transmission
-       my $fref = shift;           # a reference to an object to filter on
-       my @except = @_;                        # to all channels EXCEPT these (dxchannel refs)
-       my @dxchan = DXChannel::get_all_users();
-       my $dxchan;
-       my @out;
-       
-       foreach $dxchan (@dxchan) {
-               next if grep $dxchan == $_, @except;
-               push @out, $dxchan;
-       }
-       broadcast_list($s, $sort, $fref, @out);
-}
-
-# broadcast to a list of users
-sub broadcast_list
-{
-       my $s = shift;
-       my $sort = shift;
-       my $fref = shift;
-       my $dxchan;
-       
-       foreach $dxchan (@_) {
-               my $filter = 1;
-               next if $dxchan == $me;
-               
-               if ($sort eq 'dx') {
-                   next unless $dxchan->{dx};
-                       ($filter) = $dxchan->{spotsfilter}->it(@{$fref}) if ref $fref;
-                       next unless $filter;
-               }
-               next if $sort eq 'ann' && !$dxchan->{ann} && $s !~ /^To\s+LOCAL\s+de\s+(?:$main::myalias|$main::mycall)/i;
-               next if $sort eq 'wwv' && !$dxchan->{wwv};
-               next if $sort eq 'wcy' && !$dxchan->{wcy};
-               next if $sort eq 'wx' && !$dxchan->{wx};
-
-               $s =~ s/\a//og unless $dxchan->{beep};
-
-               if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'talk') {
-                       $dxchan->send($s);      
-               } else {
-                       $dxchan->delay($s);
-               }
-       }
-}
-
-
 #
 # obtain the hops from the list for this callsign and pc no 
 #
@@ -1905,7 +1818,7 @@ sub broadcast_route
        unless ($self->{isolate}) {
                foreach $dxchan (@dxchan) {
                        next if $dxchan == $self;
-                       next if $dxchan == $me;
+                       next if $dxchan == $main::me;
                        $dxchan->send_route($generate, @_);
                }
        }
diff --git a/perl/QXProt.pm b/perl/QXProt.pm
new file mode 100644 (file)
index 0000000..bce0b56
--- /dev/null
@@ -0,0 +1,116 @@
+#
+# This module impliments the new protocal mode for a dx cluster
+#
+# Copyright (c) 2001 Dirk Koopman G1TLH
+#
+# $Id$
+# 
+
+package QXProt;
+
+@ISA = qw(DXChannel DXProt);
+
+use DXUtil;
+use DXChannel;
+use DXUser;
+use DXM;
+use DXLog;
+use Spot;
+use DXDebug;
+use Filter;
+use DXDb;
+use AnnTalk;
+use Geomag;
+use WCY;
+use Time::HiRes qw(gettimeofday tv_interval);
+use BadWords;
+use DXHash;
+use Route;
+use Route::Node;
+use Script;
+use DXProt;
+
+use strict;
+
+use vars qw($VERSION $BRANCH);
+$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
+$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ ) || 0;
+$main::build += $VERSION;
+$main::branch += $BRANCH;
+
+use vars qw($last_node_update $node_update_interval);
+
+$node_update_interval = 14*60;
+$last_node_update = time;
+
+
+sub start
+{
+       my $self = shift;
+       $self->SUPER::start(@_);
+}
+
+sub normal
+{
+       if ($_[1] =~ /^PC\d\d\^/) {
+               DXProt::normal(@_);
+               return;
+       }
+       my $pcno;
+       return unless ($pcno) = $_[1] =~ /^QX(\d\d)\^/;
+
+       my ($self, $line) = @_;
+       
+       # calc checksum
+       $line =~ s/\^(\d\d)$//;
+       my $incs = hex $1;
+       my $cs = unpack("%32C*", $line) % 255;
+       if ($incs != $cs) {
+               dbg("QXPROT: Checksum fail in: $incs ne calc: $cs" ) if isdbg('qxerr');
+               return;
+       }
+
+       # split the field for further processing
+       my ($id, $tonode, $fromnode, @field) = split /\^/, $line;
+       
+}
+
+sub process
+{
+       if ($main::systime >= $last_node_update+$node_update_interval) {
+#              sendallnodes();
+#              sendallusers();
+               $last_node_update = $main::systime;
+       }
+}
+
+sub sendallnodes
+{
+       my $nodes = join(',', map {sprintf("%s:%d", $_->{call}, int($_->{pingave} * $_->{metric}))} DXChannel::get_all_nodes());
+       my $users = DXChannel::get_all_users();
+       DXChannel::broadcast_nodes(frame(2, undef, undef, hextime(), $users, 'S', $nodes))
+}
+
+sub sendallusers
+{
+
+}
+
+sub hextime
+{
+       my $t = shift || $main::systime;
+       return sprintf "%X", $t; 
+}
+
+sub frame
+{
+       my $pcno = shift;
+       my $to = shift || '';
+       my $from = shift || $main::mycall;
+       
+       my $line = join '^', sprintf("QX%02d", $pcno), $to, $from, @_;
+       my $cs = unpack("%32C*", $line) % 255;
+       return $line . sprintf("^%02X", $cs);
+}
+
+1;
index 3596fa00432169199ff9dbcf55121c79c00d4ea7..1fa2806a72f107cbe2d363a7305b6a495648502d 100755 (executable)
@@ -60,6 +60,7 @@ use DXCommandmode;
 use DXProtVars;
 use DXProtout;
 use DXProt;
+use QXProt;
 use DXMsg;
 use DXCron;
 use DXConnect;
@@ -98,7 +99,7 @@ package main;
 use strict;
 use vars qw(@inqueue $systime $version $starttime $lockfn @outstanding_connects 
                        $zombies $root @listeners $lang $myalias @debug $userfn $clusteraddr 
-                       $clusterport $mycall $decease $is_win $routeroot 
+                       $clusterport $mycall $decease $is_win $routeroot $me
                   );
 
 @inqueue = ();                                 # the main input queue, an array of hashes
@@ -161,8 +162,8 @@ sub new_channel
        my $basecall = $call;
        $basecall =~ s/-\d+$//;
        my $baseuser = DXUser->get($basecall);
-       if ($baseuser && $baseuser->lockout) {
-               my $lock = $user->lockout if $user;
+       my $lock = $user->lockout if $user;
+       if ($baseuser && $baseuser->lockout || $lock) {
                if (!$user || !defined $lock || $lock) {
                        my $host = $conn->{peerhost} || "unknown";
                        Log('DXCommand', "$call on $host is locked out, disconnected");
@@ -179,10 +180,17 @@ sub new_channel
        
 
        # create the channel
-       $dxchan = DXCommandmode->new($call, $conn, $user) if $user->is_user;
-       $dxchan = DXProt->new($call, $conn, $user) if $user->is_node;
-       $dxchan = BBS->new($call, $conn, $user) if $user->is_bbs;
-       die "Invalid sort of user on $call = $sort" if !$dxchan;
+       if ($user->is_spider) {
+               $dxchan = QXProt->new($call, $conn, $user);
+       } elsif ($user->is_node) {
+               $dxchan = DXProt->new($call, $conn, $user);
+       } elsif ($user->is_user) {
+               $dxchan = DXCommandmode->new($call, $conn, $user);
+       } elsif ($user->is_bbs) {
+               $dxchan = BBS->new($call, $conn, $user);
+       } else {
+               die "Invalid sort of user on $call = $sort";
+       }
 
        # check that the conn has a callsign
        $conn->conns($call) if $conn->isa('IntMsg');
@@ -230,7 +238,7 @@ sub cease
 
        # disconnect nodes
        foreach $dxchan (DXChannel->get_all_nodes) {
-           $dxchan->disconnect(2) unless $dxchan == $DXProt::me;
+           $dxchan->disconnect(2) unless $dxchan == $main::me;
        }
        Msg->event_loop(100, 0.01);
 
@@ -429,12 +437,12 @@ dbg("reading in duplicate spot and WWV info ...");
 DXProt->init();
 
 # put in a DXCluster node for us here so we can add users and take them away
-$routeroot = Route::Node->new($mycall, $version*100+5300, Route::here($DXProt::me->here)|Route::conf($DXProt::me->conf));
+$routeroot = Route::Node->new($mycall, $version*100+5300, Route::here($main::me->here)|Route::conf($main::me->conf));
 
 # make sure that there is a routing OUTPUT node default file
 #unless (Filter::read_in('route', 'node_default', 0)) {
-#      my $dxcc = $DXProt::me->dxcc;
-#      $Route::filterdef->cmd($DXProt::me, 'route', 'accept', "node_default call $mycall" );
+#      my $dxcc = $main::me->dxcc;
+#      $Route::filterdef->cmd($main::me, 'route', 'accept', "node_default call $mycall" );
 #}
 
 # read in any existing message headers and clean out old crap
@@ -466,7 +474,7 @@ DXDebug::dbgclean();
 # this, such as it is, is the main loop!
 dbg("orft we jolly well go ...");
 my $script = new Script "startup";
-$script->run($DXProt::me) if $script;
+$script->run($main::me) if $script;
 
 #open(DB::OUT, "|tee /tmp/aa");
 
@@ -485,6 +493,7 @@ for (;;) {
                DXCron::process();      # do cron jobs
                DXCommandmode::process(); # process ongoing command mode stuff
                DXProt::process();              # process ongoing ak1a pcxx stuff
+               QXProt::process();
                DXConnect::process();
                DXMsg::process();
                DXDb::process();