6a56b6389d1e5d680f10c5008a3a2be1ea8a5acf
[spider.git] / techdoc / protocol.pod
1 =head1 NAME
2
3 DXSpiderWeb Orthogonal Communications Protocol 
4
5 $Revision$
6
7 =head1 SYNOPSIS
8
9  <Origin>,<TimeSeq>,<Hop>,<FrmUser>,<To>,<ToUser>|<Tag>,<Data>...
10
11 =head1 ABSTRACT
12
13 For many years DX Clusters have used a protocol which was designed 
14 for a non-looped tree of nodes. This environment has probably never, reliably, 
15 been achieved in practice; certainly not recently.
16
17 There have always been loops, sometimes bringing the network to its 
18 knees. In modern usage, both in order to get some resilience and also
19 to expedite information flow, we use internet based, deliberately
20 looped networks with filtering. Whilst this works, after a fashion, there 
21 are all sorts of problems that the current PC protocol can never
22 address.
23
24 This document 
25 describes a complete replacement for the PC protocol. It allows a
26 fully looped network, is inherently extensible and should be simple
27 to implement (especially in perl).
28
29 All implementations of this protocol shall B<only> use this protocol
30 for inter-node communications. 
31
32 =head1 DESCRIPTION
33
34 This protocol is
35 designed to be an extensible basis for any type of one to many
36 "instant" line-based communications tasks.
37
38 This protocol is designed to be flood routed in a meshed network in
39 as efficient a manner as possible. The reason we have chosen this
40 mechanism is that most L</Messages> need to be broadcast to all nodes.
41
42 Experience has shown that nodes will appear and (more infrequently) 
43 disappear without much (or any) notice. 
44 Therefore, the constantly changing and uncoordinated
45 nature of the network doesn't lend itself to fixed routing policies.
46
47 Having said that: directed routing is available where routes have
48 been learned through past traffic.
49 Those L</Messages> that could be routed (mainly single line one to 
50 one "talk" L</Messages>) 
51 happen sufficiently infrequently that, should they need to be flood routed
52 (because no route has been learned yet) it is a small cost overall.
53
54 =head1 Messages
55
56 A message is a single line of UTF8 encoded and HTTP escaped text 
57 terminated in the standard internet manner with a <CR><LF>. 
58
59 Each message consists of a L</Routing Section> and a L</Command Section>. 
60 The two sections are separated with the '|' character. 
61 It follows that these
62 characters (as well as non-printable characters, <CR>, <LF> and
63 a small number of other reserved characters)
64 can only be sent escaped. This is described further in the 
65 L</Command Section> and L</Fields>.
66
67 Most of this document is concerned with the L</Routing Section>, however
68 some L</Standard Commands> which all implementation should issue and
69 must accept are described.
70
71 =head1 Routing Section
72
73 The application that implements this protocol is essentially a line
74 oriented message router. One line equals one message. Each line is
75 effectively a datagram. 
76
77 It is assumed that nodes are connected to
78 each other using a "reliable" streaming protocol such as TCP/IP or
79 AX25. Having said that: in context, L</Messages> in this protocol could be 
80 multi/broadcast, either "as is" or wrapped in some other framing
81 protocol. 
82
83 Because this is an unreliable, best effort, "please route my packets
84 through your node" protocol, there is no guarantee that a message
85 will get to the other side of a mesh of nodes. There may be a
86 discontinuity either caused by outage or deliberate filtering. 
87
88 However, as it is envisaged that most L</Messages> will be flood routed or,
89 in the case of directed L</Messages> (those that have L</To> and/or
90 L</ToUser> fields) down some/most/all interfaces showing a route for that
91 direction, it is unlikely that L</Messages> will be lost in practice.
92
93 =head2 Field Description
94
95 Only the first three fields in the L</Routing Section> are compulsory
96 and indicate that this is a broadcast to be sent to all nodes coming
97 from the L</Origin>. If the message needs to be identified as coming
98 from a user on a node, then the L</FrmUser> field is added.
99
100 Adding a L</To> and/or L</ToUser> field will restrict the destinations
101 or recipients that receive this message. 
102
103 The L</Hop> field is incremented on receipt of a message on a node.
104
105 Fields are separated by the comma ',' character with the last field 
106 required followed by the vertical bar '|' character.
107
108 If trailing fields are missed out then superfluous commas can also
109 be left out. If intervening fields are missing then no space needs
110 to be left for the separating comma.  
111
112 The characters allowed in the routing section are restricted. Any 
113 invalid characters in any field will cause the whole message to be
114 silently dropped.
115
116 More detailed descriptions of the fields follow:
117
118 =over
119
120 =item B<Origin>
121
122 This is a compulsory field. It is the name of the originating node.
123 The field can contain up to 12 characters in the set [-A-Z0-9_] in
124 any order. Higher layers may restrict this further.
125
126 The field must not be changed by any other node.
127
128 =item B<TimeSeq>
129
130 This is a compulsory field. It is a 10 hexadecimal digit string which
131 consists of a day no (1-31), 
132 a flag to indicate NTP syncronisation in use,
133 seconds within that day (0-86399) [total of 6 hex digits] 
134 that are concatenated with a sequence number (0-65535)
135 [4 hex digits] making the total of 10 hexadecimal digits.
136
137 The date portion is constructed as:
138
139   my $date = ((((gmtime)[3] < 1) | $ntpflag) < 18) |  (time % 86400);
140
141 The sequence number is simply an unsigned short (or 16 bit) number
142 starting at 0. 
143
144 Each message originated at this node will increment the sequence
145 number.
146
147 =item B<Hop>
148
149 This is a compulsory field. It is the number of hops from the 
150 originating node. It is incremented immediately on receipt and
151 before determining its value. 
152
153 So the originating node sends a message with a L</Hop> of 0, the
154 neighbouring nodes must increment this field before passing
155 it on to higher layers for onward processing.
156
157 Implementations may have an upper limit to this field and may
158 silently drop incoming L</Messages> with a L</Hop> count greater than the
159 limit.
160
161 =item B<FrmUser>
162
163 This field is optional. It is the identifier of the originating
164 user.  If it is missing then the message is 
165 assumed to come from the originating node itself. 
166
167 It can consist of up to 12 characters in the set [-A-Z0-9_] 
168 in any order. Higher layers may restrict this further.
169
170 =item B<To>
171
172 This field is optional. It is a string of up to 12 characters 
173 in the set [-A-Z0-9_] in any order. 
174
175 This field is used either to indicate particular node destination
176 or to differentiate this broadcast in some way by making this
177 message as a member of a L</Channel>. Any message can be sent
178 down any L</Channel>. The names of L</Channel>s and their usage
179 is entirely up to the implementor.  
180
181 It is assumed that node names can be differentiated from user
182 names and L</Channel> names.
183
184 If the field is set to a particular node destination, it will
185 be routed (rather than broadcast) to that node. However, any
186 intervening nodes are free to duplicate the message and send
187 it down more than one, likely looking, interface - depending on any
188 network policies that may pertain. 
189
190 =item B<ToUser>
191
192 This field is optional. It is a string of up to 12 characters
193 in the set [-A-Z0-9_] in any order. Higher layers may restrict 
194 this further.
195
196 Conventionally this field is used to indicate the user to whom
197 this message is directed. In an ideal world the L</To> field
198 will be set, by the originating node, to the identifier of the node
199 on which this user resides. 
200
201 If the L</To> field is not set then this message will be 
202 broadcast. However, should a node become apparent (on route)
203 then nodes are free to fill in the L</To> field and proceed
204 with a more directed approach. 
205
206 If it becomes apparent (on route) that there may be more than
207 one possible L</To> destination for a L</ToUser> then a node
208 may duplicate the message (keeping the same L</TimeSeq>) and
209 route it onwards. Because of the L</DeDuplication> inherent in 
210 the system, it is indeterminate as to which destination will
211 receive the message. It is possible for all or just some 
212 destinations to receive the message. The tuple (L</Origin>,
213 L</TimeSeq>) will determine uniqueness. 
214
215 This field can, in the case where L</To>
216 is set to the name of a node, be set to a L</Channel>. If this
217 is the case then this will cause this message to be sent to
218 a L</Channel> on the L</To> node only.
219
220 =back 
221
222 =head2 Channel
223
224 Channels are a concept very similar to that on IRC. It is a 
225 way of segregating data flows in a network. In principle, subject
226 to local policy or application requirements, any data (or
227 L</Command Section>) can be sent down any channel.
228
229 It is up to the implementation whether to use this feature or not.  
230
231 =head2 Routing
232
233 It is assumed that nodes will be connected in a looped network with
234 more than one route available (in many cases) to another node.
235
236 In anycase, most traffic is not directed, but broadcast to all users
237 on all nodes.
238
239 Each message is uniquely identified by the (L</Origin>,L</TimeSeq>) 
240 tuple. The basic system will learn which interfaces can see what nodes
241 by looking at the tuple and merging that with the L</Hop> count. 
242 Each interface remembers the latest L</TimeSeq> with the lowest L</Hop>
243 for each L</Origin> that arrives on that interface. It also remembers
244 the number of L</Messages> for that L</Origin> that has been received on
245 that interface.
246
247 Any message for onward broadcast is duplicated and sent out on all
248 interfaces that it did not come in on. 
249
250 Any message that is directed to a particular node will be sent out on
251 the "best" interface based on routing information gathered so far. If there
252 is more than one possible route then, depending on network or local
253 policy, the message may be duplicated and sent on other interfaces
254 as well.
255
256 =head2 DeDuplication
257
258 On receipt of a message, its unique tuple (L</Origin>,L</TimeSeq>) is
259 checked against a hash table. If it exists: the message is silently
260 dropped. If it does not exist in the hash table then the tuple is
261 added.
262
263 The hash table is periodically cleaned, removing tuples that 
264 have expired. The length of time a tuple remains in the hash table
265 is implementation dependant but could easily be several days, if
266 required.
267
268 This mechanism only ensures that a message broadcast around the network
269 travels the least distance and through the fewest nodes possible. It
270 is up to higher layers to make sure that data carried is not, itself,
271 duplicated!
272
273 =head2 Examples
274
275  # on link startup from GB7BAA (both sides hello)
276  GB7TLH,3D02350001,0,GB7BAA|HELLO,Aranea,1.2,24.123
277  GB7BAA,3D02355421,1,GB7TLH|HELLO,Aranea,1.1,23.245
278
279  # on user startup to GB7TLH
280  GB7TLH,3D042506F2,0,G1TLH|HELLO,PClient,1.3
281
282  # on user disconnection
283  GB7TLH,3D9534F32D,0,G1TLH|BYE
284
285  # a talk (actually 'text') message to a user (some distance away
286  # from the origin node)
287  GB7TLH,3D03450019,3,G1TLH,GB7BAA,G8TIC|T,Hiya Mike what's happening?
288
289  # a talk/chat/text message to a channel or group
290  GB7TLH,0413525F23,2,G1TLH,VHF|T,2m is opening on MS
291
292  # a ping to find the whereabouts and distance of a user from a node
293  # the hex number on the end is the ping ID
294  GB7TLH,1512346543,0,,,G7BRN|PING,9F4D 
295
296  # the same from a user on GB7TLH
297  GB7TLH,1512346543,0,G1TLH,,G7BRN|PING,23
298
299  # this effectively asks whether the user is on-line on a particular node
300  GB7TLH,1512346543,0,G1TLH,GB7DJK,G7BRN|PING,35DE
301
302  # A possible reply, same ID as ping followed by the no of hops on the 
303  # ping that was received
304  GB7DJK,1512450534,3,G7BRN,GB7TLH,G1TLH|PONG,35DE,3 
305
306
307 =head1 Command Section
308
309 The L</Command Section> of the message contains the actual data being
310 passed. It is called the Command Section because all commands
311 are identified with a L</Tag> each of which is implemented by 
312 the software using this protocol. Each </Tag> (usually) is followed by one
313 or more L</Fields>. 
314
315 =head2 Tag
316
317 The L</Tag> consists of string of uppercase letters and digits, starting
318 with a leading, uppercase, letter. Tags should be as short as is meaningful.
319
320 Valid tags would be:
321
322  DX
323  PC23
324  ANN
325
326 Invalid tags include:
327
328  1AAA
329  dx
330  Ann
331
332 The L</Tag> is separated from its data L</Fields> by a comma ','. 
333
334 =head2 Fields
335
336 All fields
337 in any subsequent data shall be separated by a comma ','.
338 All fields shall
339 be HTTP encoded such that reserved characters (comma ',', 
340 vertical bar '|',
341 percent '%', 
342 equals '=' 
343 and non printable characters less than 127 (or %7F in hex)
344 [including newline and carraige return] are tranlated to
345 their two hex digit equivalent preceeded by the percent '%' character.
346
347 For example:
348
349  "%0D%0A" is "<carriage return><linefeed>".
350  "hello%2C there" is "hello, there"
351
352 This is not standard CSV, fields are not quoted (delimited with either
353 ' or ").
354
355 All national characters above 127 are UTF8 encoded in the
356 standard perl 5.8.x way. It follows that all (perl) programs that
357 are written according to this specification must say:
358
359  use UTF8;
360
361 A message (or line) is terminated with <carriage return><linefeed>
362 0x0d 0x0a. Incoming L</Messages> must be accepted even when terminated
363 with just <linefeed>.
364
365 Care must be taken to make sure that fields have any reserved characters
366 encoded. In particular: it is perfectly permissible to have <linefeed>
367 characters in a field - so long as they are escaped.
368
369 Fields come in two styles: either simple fields (just containing
370 data) or B<key>=B<value> pairs. Each pair must be separated from
371 the next by a comma ','. The B<key> must consist of the set of
372 characters [a-z0-9_] (ie lowercase letters, digits and underscore),
373 with a leading letter. The B<value> must be HTTP encoded as
374 specified above and can otherwise contain any character.
375
376 There is no maximum size specified for a message. It is up to each
377 implimentation to enforce one (if only for their own protection).
378
379 =head2 Standard Commands
380
381 There are a number of L</Standard Commands> which must be accepted by 
382 all implementations.
383
384 =over
385
386 =item B<HELLO>
387
388  HELLO,<software name>,<version>,<build>,<comments>
389
390 Command sent on connection to another node. Both sides send their information
391 to the other. All the possible arguments are optional, although some of the
392 arguments should be sent in order to help diagnose problems. This command is
393 broadcast.
394
395 =item B<BYE> 
396
397  BYE,<comments>
398
399 Command sent to all connections when the software is shutting down. This is sent
400 by the node just before shutdown occurs. This is really only used to help the
401 network prune its routing tables. It isn't a requirement. The <comment> field
402 is optional. 
403
404 =item B<DISC>
405
406  DISC,<node name>,<comments>
407
408 Command sent when a node has disconnected from this node. This message is sent when
409 an interface shuts down. It need not be sent if a L<BYE> from an interface for
410 that node has just been received. This command should be broadcast.
411
412 The <node name> is mandatory and is the name of the interface that has just 
413 disconnected.
414
415 =item B<PING>
416
417  PING,<ping id>
418
419 Command to send a ping to a node or user. This command is used both by the software
420 and users to determine a) whether a node or user exists and b) how good the path is
421 between them. 
422
423 The <ping id> is a unique string which is usually the hexadecimal equivalent of an 
424 integer that is incremented every time it is used. But it can be anything that
425 will identify this ping using the tuple (L<Origin>,<ping id>) as unique.
426
427 =item B<PONG>
428
429  PONG,<ping id>,<no of hops on ping>
430
431 Command to reply to a ping. This is sent as a reply to an incoming ping command.
432 The <ping id> is the one supplied and the <no of hops on ping> is the number of
433 hops it took for the ping to arrive.
434
435 =item B<T>
436
437  T,<text>
438
439 All implementations must be able to send "text" (encoded as specified in 
440 L</Fields>). There would be little point in doing all this otherwise!
441
442 =back
443
444 =head1 AUTHOR
445
446 Dirk Koopman, G1TLH, E<lt>djk@tobit.co.ukE<gt>
447
448 =head1 COPYRIGHT AND LICENSE
449
450 Copyright 2004 by Dirk Koopman, G1TLH
451
452 This library is free software; you can redistribute it and/or modify
453 it under the same terms as Perl itself.
454
455 $Revision$
456
457 =cut
458
459