Skip to content
This repository has been archived by the owner on Jun 6, 2021. It is now read-only.

WIP: UFNC #162

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

WIP: UFNC #162

wants to merge 6 commits into from

Conversation

edk0
Copy link
Contributor

@edk0 edk0 commented Apr 9, 2019

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:

  • Race with SAVE on an already SAVEd nick can desync
  • Degrading to NICK for servers that lack support is not obviously safe

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:

  • 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.

  • Initial SAVEs change the TS, so a SAVE racing with a UFNC will win everywhere by the same logic as for a regular NICK.

    A second SAVE does not change the TS, so a second SAVE racing with a UFNC could desync; it is therefore prohibited to send a UFNC for a saved nick.

  • When a UFNC is propagated as a NICK, the downgrade to NICK is performed by a server on the path between the UFNC originator and the owner of the nick. Therefore, from the point of view of a server without UFNC support, all nick changes for a given target pass through the downgrading server. If UFNC without downgrade is safe from desyncs, the downgrading server must have a consistent view of the target's nick, and since nick changes for the target can only come from the downgrading server, the non-UFNC server must have the same consistent view.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant