Skip to content

Instantly share code, notes, and snippets.

@eaglgenes101
Created October 3, 2018 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eaglgenes101/7c1b61a387ab970ed63d1445aef6ef46 to your computer and use it in GitHub Desktop.
Save eaglgenes101/7c1b61a387ab970ed63d1445aef6ef46 to your computer and use it in GitHub Desktop.
Second sketch
The protocol is implemented as a QUIC extension.
First, the server and client must agree on implementing the Amethyst protocol extension, and check that in fact they agree on the precise game. This is done by setting transport parameter 0xCCCC to the value 1. This value may be set higher in future versions.
Once this check passes, a few new frame types are enabled:
- Type 0x4C00 is GUID_TRANSMISSION. Every frame of this type is a fixed 128-bit frame whose only contents are a game version GUID.
- Type 0x4C01 is NEW_CHANNEL_ID. It is described in more detail later.
- Type 0x4C02 is EXPIRED_STREAM_DATA, and follows the syntax and semantics described in detailed at https://datatracker.ietf.org/doc/draft-lubashev-quic-partial-reliability/ .
Then, the server and client must double-check that they are in fact compatible. The solution to this, as with many other problems involving multiple mutually incompatible but similar protocols, is a GUID. For the first version of the game, the end developer should choose a random GUID in 128-bit GUID space, and then for subsequent versions which change the game networking data, increment this GUID to signify a new version. This GUID is then sent by the client, and echoed back by the server if supported.
NEW_CHANNEL_ID is defined as follows:
0.......1.......2.......3.......4.......5.......6.......7.......
[ Sequence ][ Type ][ Ack time ][CIDLen]
[ Connection ID ]
[ Stateless Reset Token ]
[ Stateless Reset Token ]
Sequence: Variable-length sequence number, following the same rules as NEW_CONNECTION_ID.
Connection type: A byte indicating the type of connection:
- 00: Reliable stream
- 01: Reliable messages
- 02: Unreliable messages
- 03-EF: Reserved for us to define
- F0-FF: Reserved for others to experiment with
Ack time: The period during which the receiver is expected to send back acknowledgement information about this packet, as a 16-bit unsigned integer in hundredths of a second. Beyond this period, the client is not expected to send back acknowledgement of packets containing frames for this channel, but is allowed to do so.
Connection ID Length: The length of the connection ID field, in bytes. Must be between 4 and 18, inclusive.
Connection ID: ID to assign to the new channel, following QUIC channel numbering.
Stateless reset token: Token to send back to cause a stateless reset.
The STREAM frame remains the same for the reliable stream, but are changed for the message channels.
STREAM for reliable message channels:
0.......1.......2.......3.......4.......5.......6.......7.......
[ Stream ID ]
[ (Portion offset) ]
[ (Length) ]
[Flags ][ Data... ]
Stream ID: Stream ID for this frame to be associated with.
Portion offset: If the offset bit is set, this is the number of bytes total of all the previous data portions encoded through QUIC's variable length integer encoding (which is almost always more than the sum of lengths of messages). If the offset bit is not set, then the field is absent, and this is the first frame of this stream ID.
Length: If the length bit is set, the total length of the stream data field, following QUIC length encoding. If the length bit is not set, then the field is absent, and the data field fills the remaining space on the packet.
Flags: Set the most significant bit to indicate that the beginning of the data portion also begins a message, and set the next most significant bit to indicate that the end of the data portion also ends a message. The other 6 bits are reserved; leave them unset for now.
Data: The actual portion of data. Every data frame is associated with at most one message.
STREAM for unreliable message channels:
[ Stream ID ]
[ (Portion offset) ]
[ (Length) ]
[Flags ][ Data... ]
Stream ID: Stream ID for this frame to be associated with.
Portion offset: If the offset bit is set, this is the number of bytes total of all the previous data portions which were not encompassed within a single frame, encoded through QUIC's variable length integer encoding (which is almost always more than the sum of lengths of messages). If the offset bit is not set, then the field is absent, and this frame contains either the first fragment of the first multi-fragment message of this channel, or the message is entirely contained within the portion.
Length: If the length bit is set, the total length of the stream data field, following QUIC length encoding. If the length bit is not set, then the field is absent, and the data field fills the remaining space on the packet.
Flags: Set the most significant bit to indicate that the beginning of the data portion also begins a message, and set the next most significant bit to indicate that the end of the data portion also ends a message. The other 6 bits are reserved; leave them unset for now.
Data: The actual portion of data. Every data frame is associated with at most one message.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment