ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/doc/technical/ts3.txt
Revision: 10153
Committed: Sat Jul 2 16:50:08 2022 UTC (4 years ago) by michael
Content type: text/plain
File size: 15638 byte(s)
Log Message:
- Remove svn $Id$ from documents in doc/

File Contents

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

Properties

Name Value
svn:eol-style native
svn:keywords Id