Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resume extension #306

Closed
wants to merge 36 commits into from
Closed
Changes from 8 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
817b817
Add `resume` extension
DanielOaks Apr 13, 2017
7d4ff28
resume: Add some implementation considerations around reconnecting
DanielOaks Apr 13, 2017
a65d5e5
resume: Fix some bugs brought up
DanielOaks Apr 13, 2017
cc11591
examples: Add some more examples
DanielOaks Apr 13, 2017
3fa7b2a
resume: Correct a few issues, specify things more closely
DanielOaks Apr 13, 2017
f327f95
resume: Add security considerations around a concern brought up
DanielOaks Apr 13, 2017
7f91189
resume: Clarify language a bit more, make clear that it's the credent…
DanielOaks Apr 13, 2017
75b022f
resume: Fix some numerics, put RESUME after SASL
DanielOaks Apr 13, 2017
f0e6a51
resume: Add requested note to implementation considerations around re…
DanielOaks Apr 13, 2017
5de34e0
resume: Fix example
DanielOaks Jan 19, 2018
2f502f4
resume: Fix issues pointed out by @jwheare, suggest that servers exte…
DanielOaks Jan 20, 2018
6451d1f
resume: Note that SASL also needs to be advertised by servers. Fix so…
DanielOaks Jan 21, 2018
36cd5d3
resume: Rewrite the specification, add some security considerations, …
DanielOaks Nov 7, 2018
f4cc7ad
resume: Bump draft cap version since it's already implemented in ora
DanielOaks Nov 7, 2018
1a6c707
resume: Fix draft cap identifier, update copyright date
DanielOaks Nov 7, 2018
32ed73b
resume: Make resume token reuse more explicitly barred, make sure cli…
DanielOaks Nov 7, 2018
c7d3c16
resume: Remove reference to SASL being required (that was in the old …
DanielOaks Nov 7, 2018
3cf73fd
resume: Fix minor stuffup with example
DanielOaks Nov 7, 2018
a728385
resume: Update considerations to match new spec
DanielOaks Nov 7, 2018
937f41f
resume: Add some more concrete token restrictions
DanielOaks Nov 7, 2018
a521018
resume: Try not to imply that the feature's for stealing connections
DanielOaks Nov 7, 2018
1b39c39
Review fixes, <oldnick> no longer required, tokens enhanced
DanielOaks Feb 12, 2019
0844bc2
Cleaned up the language a little, made it explicit this is the 'typic…
DanielOaks Feb 12, 2019
67e370a
Review fixes, more appropriately restrict which clients can resume
DanielOaks Feb 12, 2019
d0b44cc
Add non-normative note suggesting reconnecting to the same server
DanielOaks Feb 14, 2019
d5f9665
Add non-normative note suggesting servers allow reconnecting across s…
DanielOaks Feb 14, 2019
584c88d
resume: Review fixes
DanielOaks Apr 8, 2019
4ba3ca9
resume: draft/resume-0.3 -> draft/resume-0.4
DanielOaks Apr 8, 2019
08dfd7a
resume: Update to use FAIL
DanielOaks Apr 8, 2019
8ffb5b8
resume: Integrate the BRB command
DanielOaks Apr 8, 2019
00945da
resume:
DanielOaks May 20, 2019
41b2512
don't transfer user/ident from old to new clients
slingamn May 21, 2019
6c838ba
two updates (#2)
slingamn Jun 9, 2019
cfa1d23
Word the fallback line better
DanielOaks Jun 9, 2019
28294d4
resume: Bump to -0.5
DanielOaks Jun 9, 2019
ea8e543
Review fix
DanielOaks Jun 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
162 changes: 162 additions & 0 deletions extensions/resume.md
@@ -0,0 +1,162 @@
---
title: IRCv3 `resume` extension
layout: spec
work-in-progress: true
copyrights:
-
name: Daniel Oakley
period: 2017
email: daniel@danieloaks.net
---
## Introduction

Occasionally, clients disconnect from IRC. What happens these days is that the client connects with a different nick, joins all their old channels again, waits for the old connection to time out (or manually kills it using services), and then changes back to their original nickname.

This feature intends to vastly simplify this form of reconnection, and reduce the amount of nick-switching, `JOIN` and `QUIT` notices, and general disruption that other clients see when this happens. At the same time, one vital piece of information to convey on reconnection is that chat history may have been lost. This feature conveys this and also makes such a notice more specific than it currently is (by allowing reconnecting clients to specify exactly how much history they may have lost).


## Architecture

This feature is enabled using the `draft/resume` capability, and uses various new messages and numerics to convey state about reconnecting clients.

### Capabilities

The `draft/resume` capability is advertised by servers that support resuming connections. This capability is requested by clients that reconnect in this way with the `RESUME` command and have the ability to correctly parse the `RESUMED` message as described in this specification.

### Messages

There are two new messages defined by this specification:

- `RESUME`: Indicates that the client wishes to resume a previous connection.
- `RESUMED`: Indicates that a client has disconnected+reconnected to the server.

Below, we go through both of these.

#### `RESUME` Command

This command is sent before starting SASL authentication, and indicates that the client wishes to resume a previous connection to the server which may still be active. The command is sent with the following format:
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

RESUME oldnick [timestamp]

`oldnick` is the nickname the client had when they last disconnected. `timestamp`, if it is given, is a timestamp which indicates when they received the last message from the server on the old connection. This timestamp is used to indicate to other clients how long the disconnection was for, and uses the same format as the IRCv3 `server-time` extension (i.e. `YYYY-MM-DDThh:mm:ss.sssZ`, or in UTC using extended format as specified by ISO 8601:2004(E) 4.3.2).

This command is sent after SASL authentication has successfully completed. After sending this command, the client continues connection registration as usual.

If the client's able to successfully resume their connection, the server sends them a `RESUMED` message (and their nickname is set to `<oldnick>`). Otherwise, the server sends the `ERR_CANNOT_RESUME` numeric (and optional additional error numerics).

If successful, the `RESUMED` message is sent to the connecting user after ident lookups and similar have been completed completes. When this message is sent out, the connecting client's nickname is updated to be the old client's nick. From this point forward, the combination of old nickname and new connecting client's username+hostname is used to identify the client from that point forward.
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

Connection resumption is done on a best-effort basis. If the resumption fails clients SHOULD continue with a regular reconnection.

#### `RESUMED` Message

This message is sent when a client successfully resumes a connection. For clients that have not received numerics indicating that their connection registration is completed, this numeric means that their `RESUME` attempt was successful. For registered clients, this indicates that the given client disconnected and reconnected to the server.

This message has the following format:

:nick!olduser@oldhost RESUMED nick user host [timestamp]
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

`nick` is the nickname of the client whose connection has been resumed. `user` and `host` are the username and hostname that the new connecting client has. The client receiving this message MUST update the username and hostname they have stored for the given client, in the same way that the `CHGHOST` message is parsed. `timestamp` if given, shows when the reconnecting client received their last message from the server. The timestamp may be used as a rough indication of how much message history has been lost.
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

When sent to other clients, the `RESUMED` message MUST have the source of the old client's nickmask. This is illustrated in the examples below.

### Numerics

Here are the new numerics that this extension defines:

| No. | Label | Format |
| --- | ----------------------- | ---------------------------------------------------------------- |
| ??? | `ERR_CANNOT_RESUME` | `:<server> ??? <oldnick> :Cannot resume connection[, <details>]` |
| ??? | `ERR_HISTORY_TRUNCATED` | `:<server> ??? <client/channel> :Chat history may be truncated` |

`ERR_CANNOT_RESUME` is used to indicate a failure to resume a connection for a specific reason. The purpose of this numeric is to indicate that resumption was not successful and optionally provide a human-readable explanation. If a more appropriate numeric for conveying the issue already exists (for example, `ERR_NOSUCHNICK` may indicate that the old nickname is no longer being present on the network), then it should be sent after this numeric is sent (i.e. both numerics will be sent).
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

`ERR_HISTORY_TRUNCATED` is used to indicate that chat history may be truncated for a given client/channel. It may be sent during a `chathistory` batch or otherwise during history playback. Bouncers that reconnect may also find this useful to send to their connected clients, to indicate that there may be missed history.


## Connection Registration

Upon connection, clients request the `draft/resume` capability. If they receive both this capability and the SASL capability, they can continue attempting to resume their old connection.
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

After successfully completing SASL authentication, clients wishing to resume an old connection send an appropriate `RESUME` command indicating the nickname they wish to take over and how long they've been disconnected for. If resuming is successful, clients are sent the `RESUMED` message and then connection registration continues, eventually ending in the registration burst (`001`-`005` and all).

Once the registration burst has been received, the server sends the client channel `JOIN` messages as appropriate (and the usual numerics that are sent on joining a channel), and dispatches the relevant messages and numerics to other clients in related channels. The new client is also given the user modes that were active on the old client, as appropriate.
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

Other clients that have the reconnecting user `MONITOR`'d MUST be sent one `RPL_MONOFFLINE` numeric and one `RPL_MONONLINE` numeric indicating that the user reconnected. The timestamps on both these messages, if sent, SHOULD be the current time.

Upon resuming the connection, servers close the old connection.

### TLS

Clients may initially connect with TLS, only to later attempt to `RESUME` from a connection without TLS. In this situation, servers SHOULD deny the attempt with a message such as _"Cannot resume connection, client is no longer using TLS"_.

This is intended to ensure that TLS-only channel modes are not bypassed, and that clients prefer continuing to use TLS.


## Examples

A client with the nick `dan` reconnecting. The old connection used the username `~old` and the host `192.168.0.5`, and the new connection uses the username `~d` and the host `127.0.0.1`:
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

C1 - C: PING 12345678
C1 - S: :irc.example.com PONG 12345678
C1 - C: PING 87654321
... C1 - Server does not send a response ...
... C1 disconnects and reconnects as C2 ...

C2 - C: CAP LS
C2 - C: NICK dan-
C2 - C: USER d * 0 :An example user!
C2 - S: :irc.example.com CAP * LS :sasl draft/resume
C2 - C: CAP REQ :sasl draft/resume
C2 - S: :irc.example.com CAP dan- ACK :sasl draft/resume
C2 - C: AUTHENTICATE PLAIN
C2 - S: :irc.example.com AUTHENTICATE +
C2 - C: AUTHENTICATE YnVubnkAYnVubnkAYnVubnk=
C2 - S: :irc.example.com 900 dan- * bunny :You are now logged in as bunny
C2 - S: :irc.example.com 903 dan- :SASL authentication successful
C2 - C: RESUME dan 2017-04-13T15:12:51.620Z
C2 - S: :irc.example.com RESUMED dan ~d 127.0.0.1 2017-04-13T15:12:51.620Z
... C1's connection is closed and C1's attributes are applied to C2 ...
C2 - C: CAP END
C2 - S: :irc.example.com 001 dan :Welcome to the Internet Relay Network dan
... C2 receives regular registration burst ...
C2 - S: :irc.example.com 376 dan :End of MOTD command
C2 - S: :dan!~d@127.0.0.1 JOIN #test
C2 - S: :irc.example.com 332 dan #test :Example topic
C2 - S: :irc.example.com 333 dan #test george 1442060874
C2 - S: :irc.example.com 353 dan @ #test :@dan @george +violet roger
C2 - S: :irc.example.com MODE #test +o dan

Here is this reconnection seen by `george`, a client that does not have the `draft/resume` capability enabled:

S: :dan!~old@192.168.0.5 QUIT :Client reconnected
S: :dan!~d@127.0.0.1 JOIN #test
S: :irc.example.com MODE #test +o dan
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

And here is this reconnection seen by `violet`, a client that has the `draft/resume` capability:

S: :dan!~old@192.168.0.5 RESUMED dan ~d 127.0.0.1 2017-04-13T15:12:51.620Z


## Implementation Considerations
DanielOaks marked this conversation as resolved.
Show resolved Hide resolved

This section notes considerations software authors will need to take into account while implementing this specification. This section is non-normative.

Right now, when clients detect that their connection to the server may have dropped they tend to send a `QUIT` command, close their current connection and then create a new connection to the server.

In cases where the server supports resuming connections and SASL is configured for this server, clients may find it more useful to attempt to establish a new link to the server and resume the connection before closing their old one. If this is done, clients should be able to better take advantage of connection resumption.

In addition, users sometimes manually reconnect when they see that their is lag on their connection. In these cases, clients may also wish to do the above rather than closing the connection and then reconnecting.

When clients see a `RESUMED` message for another client which contains a timestamp, they may calculate how much time has passed since the timestamp and the current time and then display this next to the reconnect notice. Displaying this may assist clients in knowing how much message history has been lost in private queries and channels.

Servers may wish to check the new hostmask of resuming clients, to ensure that it does not fall under their list of banned hosts or hostmasks.


## Security Considerations

This section notes security-specific considerations software authors will need to take into account while implementing this specification. This section is non-normative.

Without this specification, if you know a client's account credentials you can typically close their connection (using something like `/NS GHOST` or `/NS REGAIN`), and find out which non-hidden channels they're joined to with a regular `WHOIS`.

With this specification, if you have a client's account credentials you're able to see which hidden channels they've joined and essentially take-over their connection. This is a security concern that's not addressed by this specification (and is very difficult to address for explicitly unprepared reconnections such as the ones this specification focuses on). Clients should display incoming `RESUMED` messages in such a way that users are explicitly aware that the given client has reconnected, and servers may choose to limit connection resumption to cases where TLS is used on both the old and new connections.