41b34d6f2eacc03ca4a5d5b9f85c980b7bc62c64
[spider.git] / perl / QXProt.pm
1 #
2 # This module impliments the new protocal mode for a dx cluster
3 #
4 # Copyright (c) 2001 Dirk Koopman G1TLH
5 #
6 # $Id$
7
8
9 package QXProt;
10
11 @ISA = qw(DXChannel DXProt);
12
13 use DXUtil;
14 use DXChannel;
15 use DXUser;
16 use DXM;
17 use DXLog;
18 use Spot;
19 use DXDebug;
20 use Filter;
21 use DXDb;
22 use AnnTalk;
23 use Geomag;
24 use WCY;
25 use Time::HiRes qw(gettimeofday tv_interval);
26 use BadWords;
27 use DXHash;
28 use Route;
29 use Route::Node;
30 use Script;
31 use DXProt;
32 use Verify;
33
34 use strict;
35
36 use vars qw($VERSION $BRANCH);
37 $VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
38 $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/  || (0,0));
39 $main::build += $VERSION;
40 $main::branch += $BRANCH;
41
42 sub init
43 {
44         my $user = DXUser->get($main::mycall);
45         $DXProt::myprot_version += $main::version*100;
46         $main::me = QXProt->new($main::mycall, 0, $user); 
47         $main::me->{here} = 1;
48         $main::me->{state} = "indifferent";
49         $main::me->{sort} = 'S';    # S for spider
50         $main::me->{priv} = 9;
51         $main::me->{metric} = 0;
52         $main::me->{pingave} = 0;
53         $main::me->{registered} = 1;
54         $main::me->{version} = $main::version;
55         $main::me->{build} = $main::build;
56                 
57 #       $Route::Node::me->adddxchan($main::me);
58 }
59
60 sub start
61 {
62         my $self = shift;
63         $self->SUPER::start(@_);
64 }
65
66 sub sendinit
67 {
68         my $self = shift;
69         
70         $self->send($self->genI);
71 }
72
73 sub normal
74 {
75         if ($_[1] =~ /^PC\d\d\^/) {
76                 DXProt::normal(@_);
77                 return;
78         }
79         my ($sort, $tonode, $fromnode, $msgid, $incs);
80         return unless ($sort, $tonode, $fromnode, $msgid, $incs) = $_[1] =~ /^QX([A-Z])\^(\*|[-A-Z0-9]+)\^([-A-Z0-9]+)\^([0-9A-F]{1,4})\^.*\^([0-9A-F]{2})$/;
81
82         $msgid = hex $msgid;
83         my $noderef = Route::Node::get($fromnode);
84         $noderef = Route::Node::new($fromnode) unless $noderef;
85
86         my $il = length $incs; 
87         my $cs = sprintf("%02X", unpack("%32C*", substr($_[1], 0, length($_[1]) - ($il+1))) & 255);
88         if ($incs ne $cs) {
89                 dbg("QXPROT: Checksum fail in: $incs ne calc: $cs" ) if isdbg('chanerr');
90                 return;
91         }
92
93         return unless $noderef->newid($msgid);
94
95         $_[0]->handle($sort, $tonode, $fromnode, $msgid, $_[1]);
96         return;
97 }
98
99 sub handle
100 {
101         no strict 'subs';
102         my $self = shift;
103         my $sort = shift;
104         my $sub = "handle$sort";
105         $self->$sub(@_) if $self->can($sub);
106         return;
107 }
108
109 sub gen
110 {
111         no strict 'subs';
112         my $self = shift;
113         my $sort = shift;
114         my $sub = "gen$sort";
115         $self->$sub(@_) if $self->can($sub);
116         return;
117 }
118
119 my $last_node_update = 0;
120 my $node_update_interval = 60*15;
121
122 sub process
123 {
124         if ($main::systime >= $last_node_update+$node_update_interval) {
125 #               sendallnodes();
126 #               sendallusers();
127                 $last_node_update = $main::systime;
128         }
129 }
130
131 sub disconnect
132 {
133         my $self = shift;
134         $self->DXProt::disconnect(@_);
135 }
136
137 my $msgid = 1;
138
139 sub frame
140 {
141         my $sort = shift;
142         my $to = shift || "*";
143         my $ht;
144         
145         $ht = sprintf "%X", $msgid;
146         my $line = join '^', "QX$sort", $to, $main::mycall, $ht, @_;
147         my $cs = sprintf "%02X", unpack("%32C*", $line) & 255;
148         $msgid = 1 if ++$msgid > 0xffff;
149         return "$line^$cs";
150 }
151
152 sub send_frame
153 {
154         my $self = shift;
155         my $origin = shift || $main::me;
156         for (@_) {
157                 $self->send(frame('X', undef, $origin == $main::me || $origin->is_user ? '' : $origin->call, $_));
158         }
159 }
160
161 sub handleI
162 {
163         my $self = shift;
164         
165         my @f = split /\^/, $_[3];
166         if ($self->user->passphrase && $f[7] && $f[8]) {
167                 my $inv = Verify->new($f[7]);
168                 unless ($inv->verify($f[8], $main::me->user->passphrase, $main::mycall, $self->call)) {
169                         $self->sendnow('D','Sorry...');
170                         $self->disconnect;
171                 }
172                 $self->{verified} = 1;
173         } else {
174                 $self->{verified} = 0;
175         }
176         if ($self->{outbound}) {
177                 $self->send($self->genI);
178         } 
179         if ($self->{sort} ne 'S' && $f[4] eq 'DXSpider') {
180                 $self->{user}->{sort} = $self->{sort} = 'S';
181                 $self->{user}->{priv} = $self->{priv} = 1 unless $self->{priv};
182         }
183         $self->{version} = $f[5];
184         $self->{build} = $f[6];
185         $self->state('init1');
186         $self->{lastping} = 0;
187 }
188
189 sub genI
190 {
191         my $self = shift;
192         my @out = ('I', $self->call, "DXSpider", ($main::version + 53) * 100, $main::build);
193         if (my $pass = $self->user->passphrase) {
194                 my $inp = Verify->new;
195                 push @out, $inp->challenge, $inp->response($pass, $self->call, $main::mycall);
196         }
197         return frame(@out);
198 }
199
200 sub handleR
201 {
202
203 }
204
205 sub genR
206 {
207
208 }
209
210 sub handleP
211 {
212
213 }
214
215 sub genP
216 {
217
218 }
219
220 sub handleX
221 {
222         my $self = shift;
223         my ($sort, $to, $from, $msgid, $origin, $line) = split /\^/, $_[3], 6;
224
225         my ($pcno) = $line =~ /^PC(\d\d)/;
226         if ($pcno) {
227                 $line =~ s/^[\x\x]$//;
228                 DXProt::normal($self, $line);
229         }
230 }
231
232
233 1;