]> jfr.im git - irc/freenode/ircd-seven.git/commitdiff
Add ufnc.txt
authorEd Kellett <redacted>
Sun, 7 Apr 2019 22:56:26 +0000 (23:56 +0100)
committerEd Kellett <redacted>
Tue, 9 Apr 2019 12:21:23 +0000 (13:21 +0100)
doc/technical/ufnc.txt [new file with mode: 0644]

diff --git a/doc/technical/ufnc.txt b/doc/technical/ufnc.txt
new file mode 100644 (file)
index 0000000..49d84d4
--- /dev/null
@@ -0,0 +1,81 @@
+UFNC: FNC as a real nick change
+===============================
+
+Motivation
+----------
+
+seven, like charybdis, uses the RSFNC mechanism to enable services to change
+user nicknames. RSFNC looks like this:
+
+    ENCAP victims-server RSFNC victim-uid newnick oldTS newTS
+
+and doesn't do anything by itself: it just asks victim's server to perform the
+equivalent of a /nick.
+
+This causes a race condition when RSFNCs depend on each other. Starting with
+001TARGET on the nick 'foobar', consider a typical services REGAIN:
+
+    ENCAP serv1 RSFNC 001TARGET Guest12345 1000 1234
+    ENCAP serv2 RSFNC 002TARGET foobar 1001 1234
+
+serv1 will receive the first RSFNC, changing 001TARGET's nick to Guest12345.
+However, if it doesn't manage to do that and send a NICK to serv2 before serv2
+receives the second RSFNC, serv2 will change 002TARGET's nick to foobar while
+still seeing 001TARGET's nick as foobar. The RSFNC spec requires that in this
+case 001TARGET is killed.
+
+The kill could be avoided by issuing a SAVE, or by saving the first target
+in the first place instead of RSFNC-ing them. There is another solution,
+however: instead of _requesting_ a nick change, have services unilaterally
+_propagate_ a nick change. As commands from any given server cannot be
+reordered, the race condition is avoided.
+
+
+UFNC
+------
+
+Our addition is as follows:
+
+    UFNC targetUID newnick nickTS
+
+UFNC should only be issued by a services server. However, if attempts to enforce
+this are implemented, they must account for the fact that the nick change has
+already propagated; SAVE, SQUIT or KILL would be okay, while just ignoring the
+UFNC would not.
+
+UFNC must be silently ignored if nickTS does not match the target's TS.
+Otherwise, a server receiving a UFNC changes the target's nick to newnick,
+leaving its TS unchanged. It is propagated as a UFNC to servers that support it,
+or as a NICK to servers that do not.
+
+If newnick already exists, its existing owner is killed, regardless of their TS,
+as with RSFNC.
+
+We introduce a new server capability, also named UFNC, representing the ability
+of a server to process and propagate UFNC commands. Servers issuing UFNC must
+ensure their entire path to the vicitm's server has UFNC support. Servers
+receiving a UFNC message may enforce this.
+
+
+Desync resistance
+-----------------
+
+UFNC is not designed to handle the case where two different U-lined servers send
+conflicting UFNC messages.
+
+In other cases, we believe UFNC cannot lead to nick desyncs:
+
+ - Normal nick changes, including those generated by RSFNC, are either case
+   changes or are guaranteed to change the nickTS, no matter how fast they
+   are sent.
+
+   For regular nick changes which change the TS, a NICK racing with a UFNC will
+   override the UFNC it arrives second, and invalidate the UFNC if it
+   arrives first.
+
+   A case change NICK racing with a UFNC will be ignored if it arrives second
+   (requiring a small modification to the NICK logic), and overridden if it
+   arrives first.
+
+ - SAVEs always change the TS, so a SAVE racing with a UFNC will win everywhere
+   by the same logic as for regular NICK.