freenode / ircd-seven

freenode's IRC server daemon
Other
200 stars 48 forks source link

WIP: UFNC #162

Open edk0 opened 5 years ago

edk0 commented 5 years ago

I'll copy the documentation in the PR below. If this is the first you've heard of this proposal, read that first.

This is a work in progress and should not be merged yet; I'm hoping that you, dear reader, will pick through it and look for cases I haven't covered.

Known issues:


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 may not be issued for a UID (saved) nick.

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: