Initial import
[ratbox-ambernet.git] / doc / technical / README.TSora
blobc99dc05c13f433685b2e5d5e44a70eb5c22f2f7a
1                        Protocol changes for +TSora
2                        ---------------------------
5 Note: 
7 The protocols described here implement TimeStamps on IRC channels and 
8 nicks. The idea of IRC TimeStamps was started on Undernet, and first 
9 implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here 
10 are not exactly the same as the ones used on Undernet; the nick-kill 
11 handling is very similar and must be credited to Run, while the 
12 "TimeStamped channel description" protocol is quite different.
16 TSora servers keep track of which version of the TS protocol (if any) 
17 their neighboring servers are using, and take it into account when 
18 sending messages to them. This allows for seamless integration of TS 
19 servers into a non-TS net, and for upgrades of the protocol.
21 Each server knows which is the lowest and the highest version of the
22 TS protocol it can interact with; currently both of these are set to 1:
24 #define TS_CURRENT 1            /* the highest TS ver we can do */
25 #define TS_MIN 1                /* the lowest TS ver we can do  */
28 Timings and TS versions:
29 ========================
31 . Keep a 'delta' value to be added to the result of all calls to time(),
32   initially 0.
34 . Send a second argument to the PASS command, ending in the 'TS' string.
36 . Send a
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.
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.
54 Explanations:
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.
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.
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. 
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".
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.
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.
93 NICK handling patches (anti-nick-collide + shorter connect burst):
94 ==================================================================
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.
100 . Nick changes reset the TS to the current time.
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.
106   The format for a full NICK line is:
107   NICK <nick> <hops> <TS> <umode> <user> <host> <server> :<ircname>
109   The umode is a + followed by any applying usermodes.
111   The format for a nick-change NICK line is:
112   :<oldnick> NICK <newnick> :<TS>
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
131 . When a NICK is received from a non-TS server that conflicts with
132   an existing nick, kill both.
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.
138 Explanations:
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.
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.
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.
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.
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.
172 TimeStamped channel descriptions (avoiding hacked ops and desynchs):
173 ====================================================================
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.
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.
189   The syntax for the command is:
191   SJOIN <TS> #<channel> <modes> :[@][+]<nick_1> ...  [@][+]<nick_n>
193   The fields have the following meanings:
195   * <TS> is the timestamp for the channel
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).
203     A channel with no modes will have a "+" in that field.
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.
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.
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.
225   Servers will never attempt to reconstruct a SJOIN from JOIN/MODE 
226   information being received at the moment from other servers.
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.
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.
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. 
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.
273 Explanations:
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.
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.
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:
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
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.
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.