-
Notifications
You must be signed in to change notification settings - Fork 82
Description
A client that chooses to delay processing of a netjoin or netsplit batch until the end of the batch is received may cause state desyncs vs what is on the network. The language for this batch type should say that the clients MUST NOT delay processing of batch lines, but MAY delay displaying the results of the netjoin/netsplit in the UI until the batch has been fully received.
In these examples, assume that Client A has negotiated the batch capability and is delaying processing of batch messages until end of batch is received, while Client B has not negotiated the batch capability (and thus processes every line as it comes in). <-- indicates a message that client receives and --> indicates a message that client sends. Let's also assume the remote server sending the netjoin is slow enough that the local server A and B are connected to can process intervening messages.
| Client A | Client B |
|---|---|
<-- BATCH +foo netjoin local.server remote.server |
|
<-- @batch=foo :C!user@host JOIN #channel |
<-- :C!user@host JOIN #channel |
--> MODE #channel +o C |
|
<-- :B!user@host MODE #channel +o C |
<-- :B!user@host MODE #channel +o C |
<-- BATCH -foo |
End result: Client A processes the fact that B opped C (a nickname it doesn't even know about) before it processes that C joined the channel. It will likely ignore this spurious op, and when it does process that C joined, it will show them in the user list without operator status. However, on the ircd, C is opped, and Client B would show the correct state due to processing everything immediately.
| Client A | Client B |
|---|---|
<-- BATCH +foo netjoin local.server remote.server |
|
<-- @batch=foo :remote.server MODE #channel -o A |
<-- :remote.server MODE #channel -o A |
--> MODE #channel +o A |
|
<-- :B!user@host MODE #channel +o A |
<-- :B!user@host MODE #channel +o A |
<-- @batch=foo :remote.server NOTICE #channel :*** Notice -- TS for #channel changed from 1769042338 to 1769041945 |
<-- :remote.server NOTICE #channel :*** Notice -- TS for #channel changed from 1769042338 to 1769041945 |
<-- @batch=foo :C!user@host JOIN #channel |
<-- :C!user@host JOIN #channel |
<-- BATCH -foo |
In this example, the channel on the joining server has a lower TS, which causes it to deop A for splitriding. Because A is delaying processing of netjoin messages, they first see B opping them (which is allowed but does nothing as they are already opped). Then they process the netjoin and see the deop. The end result is that A believes they are not opped when server-side they are.
The only sensible way of solving this issue is for clients to not delay processing of netjoin messages. They can delay their display to the user, but not their processing.
netsplits have a similar issue if a split user rejoins on a local server with the same nick before the client processes the QUIT for them in the netsplit batch. The timing window for this is tighter but if you assume a laggy remote server then it is still possible.