Protocol changes for +TSora


Note:
The protocols described here implement TimeStamps on IRC channels and nicks. The idea of IRC TimeStamps was started on Undernet, and first implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here are not exactly the same as the ones used on Undernet; the nick-kill handling is very similar and must be credited to Run, while the "TimeStamped channel description" protocol is quite different.

Note:
This document has been adapted to TS3.

TSora servers keep track of which version of the TS protocol (if any) their neighboring servers are using, and take it into account when sending messages to them. This allows for seamless integration of TS servers into a non-TS net, and for upgrades of the protocol.

Each server knows which is the lowest and the highest version of the TS protocol it can interact with; currently both of these are set to 3:

#define TS_CURRENT 3		/* the highest TS ver we can do */
#define TS_MIN 3		/* the lowest TS ver we can do  */


Timings and TS versions:

Explanations:

Servers will always know which of their directly-linked servers can do TS, and will use the TS protocol only with servers that do understand it. This makes it possible to switch to full TS in just one code-replacement step, without incompatibilities.

As long as not all servers are TS-aware, the net will be divided into "zones" of linked TS-aware servers. Channel modes will be kept synchronized at least within the zone in which the channel was created, and nick collisions between servers in the same zone will result in only one client being killed.

Time synchronization ensures that servers have the same idea of the current time, and achieves this purpose as long as TS servers are introduced one by one within the same 'zone'. The merging of two zones cannot synchronize them completely, but it is to be expected that within each zone the effective time will be very close to the real time.

By sending TSINFO after SERVER rather than before, we avoid the extra lag created by the identd check on the server. To be able to send immediately a connect burst of either type (TS or not), we need to know before that if the server does TS or not, so we send that information with PASS as an extra argument. And to avoid being incompatible with 2.9 servers, which check that this second argument begins with "2.9", we check that it *ends* with "TS".

The current time is only used when setting a TS on a new channel or nick, and once such a TS is set, it is never modified because of synchronization, as it is much more important that the TS for a channel or nick stays the same across all servers than that it is accurate to the second.

Note that Undernet's 2.8.x servers have no time synchronization at all, and have had no problems because of it - all of this is more to catch the occasional server with a way-off clock than anything.


NICK handling patches (anti nick-collide + shorter connect burst):

Explanations:

The modified nick-introduction syntax allows for a slightly shorter connect-burst, and most importantly lets the server compare user@host's when determining which nick to kill: if the user@host is the same, then the older nick must be killed rather than the newer.

When talking to a non-TS server, we need to behave exactly like one because it expects us to. When talkign to a TS server, we don't kill the nicks it's introducing, as we know it'll be smart enough to do it itself when seeing our own introduced nick.

When we see a nick arriving from a non-TS server, it won't have a TS, but it's safe enough to give it the current time rather than keeping it 0; such TS's won't be the same all across the network (as long as there is more than one TS zone), and when there's a collision, the TS used will be the one in the zone the collision occurs in.

Also, it is important to note that by the time a server sees (and chooses to ignore) a nick introduction, the introducing server has also had the time to put umode changes for that nick on its queue, so we must ignore them too... so we need to ignore fake-prefix lines rather than sending kills for them. This is safe enough, as the rest of the protocol ensures that they'll get killed anyway (and the Undernet does it too, so it's been more than enough tested). Just for an extra bit of compatibility, we still kill fake prefixes coming from non-TS servers.

This part of the TS protocol is almost exactly the same as the Undernet's .anc (anti-nick-collide) patches, except that Undernet servers don't add usermodes to the NICK line.


TimeStamped channel descriptions (avoiding hacked ops and desynchs):

Explanations:

This part of the protocol is the one that is most different (and incompatible) with the Undernet's: we never timestamp MODE changes, but instead we introduce the concept of time-stamped channel descriptions. This way each server can determine, based on its state and the received description, what the correct modes for a channel are, and deop its own users if necessary. With this protocol, there is *never* the need to reverse and bounce back a mode change. This is both faster and more bandwith-effective.

The end goal is to have a protocol will eventually protect channels against hacked ops, while minimizing the impact on a mixed-server net. In order to do this, whenever there is a conflict between a TS server and a non-TS one, the non-TS one's idea of the whole situation prevails. This means that channels will only have a TS when they have been created on a TS-aware server, and will lose it whenever a server op comes from a non-TS server. Also, at most one 'zone' will have a TS for any given channel at any given time, ensuring that there won't be any deops when zones are merged. However, when TS zones are merged, if the side that has a TS also has ops, then the TS is kept across the whole new zone.

Effective protection will only be ensured once all servers run TS patches and channels have been re-created, as there is no way servers can assign a TS to a channel they are not creating (like they do with nicks) without having unwanted deops later.

The visible effects of this are that when a split rejoins, and one side has hacked ops, the other side doesn't see any server mode changes (just like with Undernet), but the side that has hacked ops sees:

The less obvious part of this protocol is its behavior in the case that the younger side of a rejoin has servers that are lagged with each other. In such a situation, a SJOIN that clears all modes and sets the legitimate ones is being propagated from one server, and lagged illegitimate mode changes and kicks are being propagated in the opposite direction. In this case, a kick done by someone who is being deopped by the SJOIN must be taken into account to keep the name list in sync (and since it can only be kicking someone who also was on the younger side), while a deop does not matter (and will be ignored by the first server on the other side), and an opping *needs* to be discareded to avoid hacked ops.

The main property of timestamped channel descriptions that makes them a very stable protocol even with lag and splits, is that they leave a server in the same final state, independently of the order in which channel descriptions coming from different servers are received. Even when SJOINs and MODEs for the same channel are being propagated in different direction because of several splits rejoining, the final state will be the same, independently of the exact order in which each server received the SJOINs, and will be the same across all the servers in the same zone.


Maintained by: Roger Espel Llima (aka orabidoo)
<espel@iagora.net>