Skip to content

STANDARD.md: connect token lifecycle states and the mandatory restart rule - #183

Merged
gafferongames merged 1 commit into
mainfrom
standard-token-lifecycle
Sep 4, 2026
Merged

STANDARD.md: connect token lifecycle states and the mandatory restart rule#183
gafferongames merged 1 commit into
mainfrom
standard-token-lifecycle

Conversation

@gafferongames

Copy link
Copy Markdown
Contributor

The spec half of the connect token lifecycle work. STANDARD.md only, no code and no wire change: the protocol version stays NETCODE 1.02 and no packet layout moves.

Connect token history

A new Connect Token History section states the rules that were previously spread across one line of the connection request steps:

  • An entry holds the private connect token hmac, the address that presented it, the connect token expire timestamp, the time the entry was created, and a state: pending or consumed.
  • An entry is created pending when the server accepts a connection request for a connect token it has not seen.
  • It becomes consumed when the server accepts the connection response for that token and assigns the client to a slot.
  • A pending entry admits a connection request presenting its token from the same address and no other, so a client can retransmit its connection request during a handshake.
  • A consumed entry admits nothing, whatever the source address and whether or not the client is still in its slot. A connect token is usable for exactly one connection, and the keys it carries encrypt exactly one session.
  • Entries live until their connect token expires. A history whose entries all hold unexpired tokens refuses a new connect token rather than evicting one, so a flood of tokens cannot reopen a token that has been used.
  • An entry's time is set at creation and never refreshed.

The connection request steps now defer to that section, and the connection response steps mark the entry consumed.

Server restarts

Rejecting connect tokens that could have been issued before the server started is now mandatory: the server is configured with the maximum connect token lifetime its deployment issues, and ignores any connection request whose connect token expire timestamp minus that lifetime is earlier than the server start time. It needs no persistent state and no data beyond the expire timestamp already in the connection request packet.

Persisting the connect token history stays optional, and the section now says it is meaningful only together with the consumed state, since a restored entry is only useful if it refuses the address that used the token as well as every other address.

The implementation of all of this in netcode.c follows in a second PR on top of this one.

🤖 Generated with Claude Code

A connect token history entry now carries a state. It is created pending when
the server accepts a connection request for a token it has not seen, and becomes
consumed when the server accepts the connection response and installs the client.
A pending entry admits a retransmitted connection request from the same address,
so a handshake that loses a packet still completes. A consumed entry admits
nothing, whatever the source address, so the keys a connect token carries encrypt
exactly one session.

Entries live until their connect token expires. A history whose entries all hold
unexpired tokens refuses a new connect token instead of evicting one, and an
entry's time is set at creation and never refreshed.

The restart rule is mandatory: the server is configured with the maximum connect
token lifetime its deployment issues, and ignores any connection request whose
connect token expire timestamp minus that lifetime is earlier than the server
start time. Persisting the history stays optional, and is meaningful only
together with the consumed state.

Nothing on the wire moves and the protocol version stays NETCODE 1.02.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gafferongames
gafferongames marked this pull request as ready for review September 4, 2026 07:09
@gafferongames
gafferongames merged commit 9ff6a3d into main Sep 4, 2026
14 checks passed
@gafferongames
gafferongames deleted the standard-token-lifecycle branch September 4, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant