]> Cypherpunks.ru repositories - nncp.git/blob - doc/multicast.texi
fbb31adf94ce0c6444c0d0c85cb06131822a3e17
[nncp.git] / doc / multicast.texi
1 @node Multicast
2 @unnumbered Multicast areas
3
4 NNCP has ability to multicast packets: send single packet to multiple
5 recipients, which also can send it further to others. It can also be
6 called echomail (like in FidoNet networks) or newsgroup (like in Usenet
7 networks).
8
9 @anchor{Area}
10 Each multicast group is identified by so-called @strong{area}. Area
11 consists of private/public Curve25519 keypairs for @ref{Encrypted area,
12 packets encryption}, identity (BLAKE2b-256 hash of the public key) and
13 possible subscribers. Areas are created with @ref{nncp-cfgnew} command.
14
15 You can make either file or exec transmissions to the areas. Those
16 ordinary file/exec packets are double wrapped in:
17
18 @itemize
19 @item encrypted packet, securing the actual packet contents from
20 participants not having area's keypairs (but still being able to relay
21 that encrypted packet to the others)
22 @item area packet, containing area's identity, telling that tossing node
23 can should it to the subscribers further
24 @end itemize
25
26 Area's message identity (@code{MsgHash}) is the hash of the encrypted
27 packet header. Because the area packet, containing the encrypted packet,
28 is relayed as-is without any modifications, that area message's hash
29 will be the same on each node it reaches.
30
31 @ref{nncp-toss, Tosser}'s algorithm of processing the area packet is
32 following:
33
34 @itemize
35 @item check is it known area's identity (@code{AREA}).
36     Fail/skip if it is unknown
37 @item hash encrypted packet's header, getting the @code{MsgHash}
38 @item for each area's subscribers:
39     @itemize
40     @item check if that message was already seen (sent or received from)
41         before by the destination node: check existence of
42         @file{SPOOL/NODE/area/AREA/MsgHash} file. Skip that node if
43         it exists
44     @item if subscriber's node is not the one we received the packet
45         from, then create outgoing encrypted packet to it, with that
46         area packet inside
47     @item create corresponding @file{MsgHash} file
48     @item "rewind" the outer encrypted file to the beginning and repeat
49         the whole cycle again, while all of subscribers will "seen" that
50         area's message.
51
52         Expensive signature verification and shared key computation
53         procedures are skipped in the following cycles -- only symmetric
54         cryptography will be in use, having negligible CPU resource
55         consumption.
56     @end itemize
57 @item check if we have seen that area's message before by looking at
58     @file{SPOOL/SELF/area/AREA/MsgHash}. If so, remove the packet,
59     because it is just a ordinary possible duplicate, finish its processing
60 @item check if we have got corresponding area's private key. If no key
61     exists, then remove the packet, finish its processing -- we just
62     relay it further without being able to read it
63 @item look if area's encrypted packet's sender is known to us. If
64     neither it is known, nor we have @code{allow-unknown} configuration
65     option set for that area, then fail
66 @item otherwise start decryption procedure, possibly ignoring the
67     sender's signature verification if it is unknown
68 @item fed the decrypted contents to the toss-procedure as an ordinary
69     plain packet, receiving files or exec calls
70 @item mark area's message as the seen one, remove the packet, finish
71     processing
72 @end itemize
73
74 Because outgoing packets creation for each subscriber can be time and
75 (disk) resource consuming, we can suddenly fail. It would be bad if we
76 will loose the possibility to retry the multicasting process again. So
77 we have got to save somehow outgoing area's message in permanent
78 storage, while outgoing copies are created. That is why the initial (not
79 relaying) message to the area is sent to the @strong{self} and processed
80 by the @ref{nncp-toss, tosser} to create necessary outgoing message
81 copies. Because message to myself is also encrypted, area's message is
82 encrypted and secured and noone sees plaintext @code{MsgHash}, knowing
83 that you either originated or have that message on the disk.
84
85 For example we have got 4 nodes participating in the single area and
86 let's send file to that area from the @code{nodeA}:
87
88 @example
89 nodeA -> subs: ["nodeB", "nodeD"]
90 nodeB -> subs: ["nodeC", "nodeD", "nodeA"], no keys
91 nodeC -> subs: ["nodeB"]
92 nodeD -> subs: ["nodeA", "nodeB"]
93 @end example
94
95 @example
96 A -- B -- C
97 \   /
98  \ /
99   D
100 @end example
101
102 @example
103 $ nncp-file nodelist-20210704.rec.zst area:nodelist-updates:
104 $ nncp-toss -node self
105 @end example
106
107 @enumerate
108 @item
109 @command{nncp-file} creates an encrypted packet with area packet and
110 encrypted packet inside it, with our own @code{self} node as a recipient
111 (in the @file{SPOOL/SELF/tx} directory). It also creates the
112 @file{SPOOL/SELF/area/AREA/MsgHash} file.
113
114 @item
115 @command{nncp-toss} sees @file{tx/} file and "opens" it, applying the
116 area message tossing procedure as described above. That will create
117 outgoing packets in @file{SPOOL/nodeB/tx} and @file{SPOOL/nodeD/tx}
118 directories with @file{SPOOL/nodeB/area/AREA/MsgHash}
119 @file{SPOOL/nodeD/area/AREA/MsgHash} files. Because we already have
120 @file{SPOOL/SELF/area/AREA/MsgHash}, that packet is removed then.
121
122 @item
123 When @code{nodeB} receives the encrypted packet, it sees the area one
124 inside. It copies/relays it to the @code{nodeC} and @code{nodeD}. It can
125 not read area's message because it lacks the keys.
126
127 @item
128 @code{nodeC} does not relay it to anyone. Just stores
129 @file{nodelist-20210704.rec.zst} in the incoming directory.
130
131 @item
132 @code{nodeD} receives packets from both @code{nodeA} and @code{nodeB}.
133 Only one of them processed, and other is ignored because corresponding
134 @file{MsgHash} file will exist.
135
136 If @code{nodeD} will receive packet from the @code{nodeB} first, it will
137 relay it to the @code{nodeA} also, that will silently remove it when
138 tossing, because it was already seen.
139
140 @item
141 When @code{nodeC} sends message to the area, then @code{nodeA} will
142 receive it twice from @code{nodeB} and @code{nodeD}, ignoring one of
143 them during tossing.
144
145 @end enumerate