]> jfr.im git - irc/rqf/shadowircd.git/blame - doc/technical/README.TSora
Remove additional wrong declaration for rb_kill().
[irc/rqf/shadowircd.git] / doc / technical / README.TSora
CommitLineData
212380e3 1 Protocol changes for +TSora
2 ---------------------------
3
4
5Note:
6
7The protocols described here implement TimeStamps on IRC channels and
8nicks. The idea of IRC TimeStamps was started on Undernet, and first
9implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here
10are not exactly the same as the ones used on Undernet; the nick-kill
11handling is very similar and must be credited to Run, while the
12"TimeStamped channel description" protocol is quite different.
13
14
15
16TSora servers keep track of which version of the TS protocol (if any)
17their neighboring servers are using, and take it into account when
18sending messages to them. This allows for seamless integration of TS
19servers into a non-TS net, and for upgrades of the protocol.
20
21Each server knows which is the lowest and the highest version of the
22TS protocol it can interact with; currently both of these are set to 1:
23
24#define TS_CURRENT 1 /* the highest TS ver we can do */
25#define TS_MIN 1 /* the lowest TS ver we can do */
26
27
28Timings and TS versions:
29========================
30
31. Keep a 'delta' value to be added to the result of all calls to time(),
32 initially 0.
33
34. Send a second argument to the PASS command, ending in the 'TS' string.
35
36. Send a
37
38 SVINFO <TS_CURRENT> <TS_MIN> <STANDALONE> :<UTC-TIME>
39
40 just after "SERVER", where <STANDALONE> is 1 if we're connected to
41 more TSora servers, and 0 if not, and <UTC-TIME> is our idea of the
42 current UTC time, fixed with the delta.
43
44. When we receive a "SVINFO <x> <y> <z> :<t>" line from a connecting
45 server, we ignore it if TS_CURRENT<y or x<TS_MIN, otherwise we
46 set a flag remembering that that server is TS-aware, remember the TS
47 version to use with it (min(TS_CURRENT, x)). Additionally, if this is
48 our first connected TS server, we set our delta to t-<OUR_UTC> if
49 z==0, and to (t-<OUR_UTC>)/2 if z!=0. The SVINFO data is kept around
50 until the server has effectively registered with SERVER, and used
51 *after* sending our own SVINFO to that server.
52
53
54Explanations:
55
56 Servers will always know which of their directly-linked servers can do
57 TS, and will use the TS protocol only with servers that do understand
58 it. This makes it possible to switch to full TS in just one
59 code-replacement step, without incompatibilities.
60
61 As long as not all servers are TS-aware, the net will be divided into
62 "zones" of linked TS-aware servers. Channel modes will be kept
63 synchronized at least within the zone in which the channel was
64 created, and nick collisions between servers in the same zone will
65 result in only one client being killed.
66
67 Time synchronization ensures that servers have the same idea of the
68 current time, and achieves this purpose as long as TS servers are
69 introduced one by one within the same 'zone'. The merging of two zones
70 cannot synchronize them completely, but it is to be expected that
71 within each zone the effective time will be very close to the real
72 time.
73
74 By sending TSINFO after SERVER rather than before, we avoid the extra
75 lag created by the identd check on the server. To be able to send
76 immediately a connect burst of either type (TS or not), we need to
77 know before that if the server does TS or not, so we send that
78 information with PASS as an extra argument. And to avoid being
79 incompatible with 2.9 servers, which check that this second argument
80 begins with "2.9", we check that it *ends* with "TS".
81
82 The current time is only used when setting a TS on a new channel or
83 nick, and once such a TS is set, it is never modified because of
84 synchronization, as it is much more important that the TS for a
85 channel or nick stays the same across all servers than that it is
86 accurate to the second.
87
88 Note that Undernet's 2.8.x servers have no time synchronization at
89 all, and have had no problems because of it - all of this is more to
90 catch the occasional server with a way-off clock than anything.
91
92
93NICK handling patches (anti-nick-collide + shorter connect burst):
94==================================================================
95
96. For each nick, store a TS value = the TS value received if any, or our
97 UTC+delta at the time we first heard of the nick. TS's are propagated
98 to TS-aware servers whenever sending a NICK command.
99
100. Nick changes reset the TS to the current time.
101
102. When sending a connect burst to another TS server, replace the
103 NICK/USER pair with only one NICK command containing the nick, the
104 hopcount, the TS, the umode, and all the USER information.
105
106 The format for a full NICK line is:
107 NICK <nick> <hops> <TS> <umode> <user> <host> <server> :<ircname>
108
109 The umode is a + followed by any applying usermodes.
110
111 The format for a nick-change NICK line is:
112 :<oldnick> NICK <newnick> :<TS>
113
114. When a NICK is received from a TS server, that conflicts with an
115 existing nick:
116 + if the userhosts differ or one is not known:
117 * if the timestamps are equal, kill ours and the old one if it
118 was a nick change
119 * if the incoming timestamp is older than ours, kill ours and
120 propagate the new one
121 * if the incoming timestamp is younger, ignore the line, but kill
122 the old nick if it was a nick change
123 + if the userhosts are the same:
124 * if the timestamps are equal, kill ours and the old one if it
125 was a nick change
126 * if the incoming timestamp is younger, kill ours and propagate
127 the new one
128 * if the incoming timestamp is older, ignore the line but kill
129 the old nick if it was a nick change
130
131. When a NICK is received from a non-TS server that conflicts with
132 an existing nick, kill both.
133
134. Do not send "Fake Prefix" kills in response to lines coming from TS
135 servers; the sanitization works anyway, and this allows the "newer
136 nick overruled" case to work.
137
138Explanations:
139
140 The modified nick-introduction syntax allows for a slightly shorter
141 connect-burst, and most importantly lets the server compare
142 user@host's when determining which nick to kill: if the user@host
143 is the same, then the older nick must be killed rather than the
144 newer.
145
146 When talking to a non-TS server, we need to behave exactly like one
147 because it expects us to. When talkign to a TS server, we don't kill
148 the nicks it's introducing, as we know it'll be smart enough to do it
149 itself when seeing our own introduced nick.
150
151 When we see a nick arriving from a non-TS server, it won't have a TS,
152 but it's safe enough to give it the current time rather than keeping
153 it 0; such TS's won't be the same all across the network (as long as
154 there is more than one TS zone), and when there's a collision, the TS
155 used will be the one in the zone the collision occurs in.
156
157 Also, it is important to note that by the time a server sees (and
158 chooses to ignore) a nick introduction, the introducing server has
159 also had the time to put umode changes for that nick on its queue, so
160 we must ignore them too... so we need to ignore fake-prefix lines
161 rather than sending kills for them. This is safe enough, as the rest
162 of the protocol ensures that they'll get killed anyway (and the
163 Undernet does it too, so it's been more than enough tested). Just for
164 an extra bit of compatibility, we still kill fake prefixes coming from
165 non-TS servers.
166
167 This part of the TS protocol is almost exactly the same as the
168 Undernet's .anc (anti-nick-collide) patches, except that Undernet
169 servers don't add usermodes to the NICK line.
170
171
172TimeStamped channel descriptions (avoiding hacked ops and desynchs):
173====================================================================
174
175. For each channel, keep a timestamp, set to the current time when the
176 channel is created by a client on the local server, or to the received
177 value if the channel has been propagated from a TS server, or to 0
178 otherwise. This value will have the semantics of "the time of creation
179 of the current ops on the channel", and 0 will mean that the channel
180 is in non-TS mode.
181
182 A new server protocol command is introduced, SJOIN, which introduces
183 a full channel description: a timestamp, all the modes (except bans),
184 and the list of channel members with their ops and voices. This
185 command will be used instead of JOIN and of (most) MODEs both in
186 connect bursts and when propagating channel creations among TS
187 servers. SJOIN will never be accepted from or sent to users.
188
189 The syntax for the command is:
190
191 SJOIN <TS> #<channel> <modes> :[@][+]<nick_1> ... [@][+]<nick_n>
192
193 The fields have the following meanings:
194
195 * <TS> is the timestamp for the channel
196
197 * <modes> is the list of global channel modes, starting with a +
198 and a letter for each of the active modes (spmntkil), followed
199 by an argument for +l if there is a limit, and an argument for
200 +k if there's a key (in the same order they were mentioned in
201 the string of letters).
202
203 A channel with no modes will have a "+" in that field.
204
205 A special value of "0" means that the server does not specify the
206 modes, and will be used when more than one SJOIN line is needed
207 to completely describe a channel, or when propagating a SJOIN
208 the modes of which were rejected.
209
210 * Each nick is preceded by a "@" if the user has ops, and a "+" if
211 the user has a voice. For mode +ov, both flags are used.
212
213 SJOINs will be propagated (when appropriate) to neighboring TS
214 servers, and converted to JOINs and MODEs for neighboring non-TS
215 servers.
216
217 To propagate channels for which not all users fit in one
218 SJOIN line, several SJOINs will be sent consecutively, only the first
219 one including actual information in the <mode> field.
220
221 An extra ad-hoc restriction is imposed on SJOIN messages, to simplify
222 processing: if a channel has ops, then the first <nick> of the first
223 SJOIN sent to propagate that channel must be one of the ops.
224
225 Servers will never attempt to reconstruct a SJOIN from JOIN/MODE
226 information being received at the moment from other servers.
227
228. For each user on a channel, keep an extra flag (like ops and voice)
229 that is set when the user has received channel ops from another
230 server (in a SJOIN channel description), which we rejected (ignored).
231 Mode changes (but NOT kicks) coming from a TS server and from someone
232 with this flag set will be ignored. The flag will be reset when the
233 user gets ops from another user or server.
234
235. On deops done by non-local users, coming from TS servers, on channels
236 with a non-zero TS, do not check that the user has ops but check that
237 their 'deopped' flag is not set. For kicks coming from a TS server, do
238 not check either. This will avoid desynchs, and 'bad' modechanges are
239 avoided anyway. Other mode changes will still only be taken into
240 account and propagated when done by users that are seen as having ops.
241
242. When a MODE change that ops someone is received from a server for a
243 channel, that channel's TS is set to 0, and the mode change is
244 propagated.
245
246. When a SJOIN is received for a channel, deal with it in this way:
247 * received-TS = 0:
248 + if we have ops or the SJOIN doesn't op anyone, SJOIN propagated
249 with our own TS.
250 + otherwise, TS set to 0 and SJOIN propagated with 0.
251 * received-TS > 0, own-TS = 0:
252 + if the SJOIN ops someone or we don't have ops, set our TS to the
253 received TS and propagate.
254 + otherwise, propagate with TS = 0.
255 * received-TS = own-TS: propagate.
256 * received-TS < own-TS:
257 + if the SJOIN ops someone, remove *all* modes (except bans) from
258 the channel and propagate these mode changes to all neighboring
259 non-TS servers, and copy the received TS and propagate the SJOIN.
260 + if the SJOIN does not op anyone and we have ops, propagate
261 with our own TS.
262 + otherwise, copy the received TS and propagate the SJOIN.
263 * received-TS > own-TS:
264 + if the SJOIN does not introduce any ops, process and propagate
265 with our own TS.
266 + if we have ops: for each person the mode change would op, set the
267 'deopped' flag; process all the JOINs ignoring the '@' and '+'
268 flags; propagate without the flags and with our TS.
269 + if we don't have ops: set our TS to the received one, propagate
270 with the flags.
271
272
273Explanations:
274
275 This part of the protocol is the one that is most different (and
276 incompatible) with the Undernet's: we never timestamp MODE changes,
277 but instead we introduce the concept of time-stamped channel
278 descriptions. This way each server can determine, based on its state
279 and the received description, what the correct modes for a channel
280 are, and deop its own users if necessary. With this protocol, there is
281 *never* the need to reverse and bounce back a mode change. This is
282 both faster and more bandwith-effective.
283
284 The end goal is to have a protocol will eventually protect channels
285 against hacked ops, while minimizing the impact on a mixed-server net.
286 In order to do this, whenever there is a conflict between a TS server
287 and a non-TS one, the non-TS one's idea of the whole situation
288 prevails. This means that channels will only have a TS when they have
289 been created on a TS-aware server, and will lose it whenever a server
290 op comes from a non-TS server. Also, at most one 'zone' will have a TS
291 for any given channel at any given time, ensuring that there won't be
292 any deops when zones are merged. However, when TS zones are merged, if
293 the side that has a TS also has ops, then the TS is kept across the
294 whole new zone. Effective protection will only be ensured once all
295 servers run TS patches and channels have been re-created, as there is
296 no way servers can assign a TS to a channel they are not creating
297 (like they do with nicks) without having unwanted deops later.
298
299 The visible effects of this timestamped channel-description protocol
300 are that when a split rejoins, and one side has hacked ops, the other
301 side doesn't see any server mode changes (just like with Undernet's
302 TS), but the side that has hacked ops sees:
303
304 * first the first server on the other side deopping and devoicing
305 everyone, and fixing the +spmntkli modes
306 * then other users joining, and getting server ops and voices
307
308 The less obvious part of this protocol is its behavior in the case
309 that the younger side of a rejoin has servers that are lagged with
310 each other. In such a situation, a SJOIN that clears all modes and
311 sets the legitimate ones is being propagated from one server, and
312 lagged illegitimate mode changes and kicks are being propagated in the
313 opposite direction. In this case, a kick done by someone who is being
314 deopped by the SJOIN must be taken into account to keep the name list
315 in sync (and since it can only be kicking someone who also was on the
316 younger side), while a deop does not matter (and will be ignored by
317 the first server on the other side), and an opping *needs* to be
318 discareded to avoid hacked ops.
319
320 The main property of timestamped channel descriptions that makes them
321 a very stable protocol even with lag and splits, is that they leave a
322 server in the same final state, independently of the order in which
323 channel descriptions coming from different servers are received. Even
324 when SJOINs and MODEs for the same channel are being propagated in
325 different direction because of several splits rejoining, the final
326 state will be the same, independently of the exact order in which each
327 server received the SJOINs, and will be the same across all the
328 servers in the same zone.
329
330