Skip to content

Instantly share code, notes, and snippets.

@eaglgenes101
Created October 3, 2018 02:02
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/55466ff21a2e7184e6499211086ea725 to your computer and use it in GitHub Desktop.
Save eaglgenes101/55466ff21a2e7184e6499211086ea725 to your computer and use it in GitHub Desktop.
Protocol first sketch
Mostly based on QUIC.
Long Header:
0.......1.......2.......3.......4.......5.......6.......7.......
[Flags ][ Magic number "Jet" ][ Connection ID ]
[ Connection ID ][ Version Number ]
[ Packet Number ][ Payload... ]
Flags: Most significant bit set to 1 to signify long header, the other 7 are used to specify long packet type.
Magic number "Jet": This field is unused in QUIC, so I'm using it for magic numbering. Set it to the ASCII representation of "Jet".
Connection ID: Unique identifier of a connection session.
Version number: A version number for the protocol, starting with "4C", in reference to the 4 C's of diamonds. This will also cause QUIC servers that don't know the Amethyst protocol to reject this connection for at least a few millennia. Version number 0x4C000000 is specified for Amethyst protocol version negotiation.
Packet number: Number for the sequential enumeration of packets. Follows QUIC packet enumeration rules.
Payload: Dependent on type. Occupies the remainder of the packet space.
Short Header:
0.......1.......2.......3.......4.......5.......6.......7.......
[Flags ][ Magic number "Jet" ][ (Connection ID) ]
[ (Connection ID) ][ Packet Number ]
[ Payload... ]
Flags: In order from most significant to least significant:
- 0 to signify short header header,
- Connection ID bit as defined in QUIC,
- Key phase bit as defined in QUIC,
- The next two bits are reserved, and should be set to 0b10 while I figure out a use for them,
- and the last three bits short packet type, as defined in QUIC.
Magic number "Jet": This field is unused in QUIC, so I'm using it for magic numbering. Set it to the ASCII representation of "Jet".
Connection ID: If present, unique identifier of a connection session.
Packet number: Number for the sequential enumeration of packets. Like QUIC, this may actually be 8, 16, or 32 bits, depending on short packet type.
Payload: Where all the juicy data is kept, in the form of frames. Occupies the remainder of the packet space.
Version Negotiation:
0.......1.......2.......3.......4.......5.......6.......7.......
[Flags ][ Magic number "Jet" ][ Connection ID ]
[ Connection ID ][ Magic number 0x4C000000 ]
[ Version Number 1 ][ (Version Number 2) ]
[ (Version Number 3) ][ (Version Number 4) ]
[ (Version Number 5) ][ (Version Number 6) ]
[ (More version numbers...) ]
Flags: Most significant bit set to 1, all others are disregarded in this context.
Magic number "Jet": Magic number "Jet", to assist recognition of Amethyst protocol packets.
Connection ID: Unique identifier of a connection session.
Magic number 0x4C000000: Version negotiation number, reserved for this purpose. Not 0x00000000, so that QUIC servers don't try to negotiate with us and subsequently cause network confusion.
Version numbers: Protocol version numbers, in decreasing order of preference, up to 32 of them.
=========================================
All the long packet types in QUIC and their semantic meanings should be mentally copypasted here. They're perfectly good for their intended purpose, and ours. Also, most of the handshaking beyond the initial part is just the same as in QUIC.
The only change I can think of so far, other than the changes to the headers above, are in the addition of new channel types.
NEW_CONNECTION_ID is redefined as follows:
0.......1.......2.......3.......4.......5.......6.......7.......
[ Sequence ][ Type ][ Flags][ Time ]
[ Connection ID ]
[ Connection ID ]
[ Stateless Reset Token ]
[ Stateless Reset Token ]
[ Stateless Reset Token ]
[ Stateless Reset Token ]
The fields are:
Sequence: Variable-length sequence number, following the same rules as NEW_CONNECTION_ID.
Type: Type of the channel.
- 00: Reliable stream
- 01: Reliable messages
- 02: Unreliable messages with feedback (ACKs are sent back, but only to monitor packet loss, not for retransmission)
- 03: Unreliable messages without feedback (ACKs are not sent back)
- 04-EF: Reserved for us to define
- F0-FF: Reserved for others to experiment with
Flags: Reserved, please set to 0 while I figure out a use for them.
Time: The guaranteed retransmission period of a packet, in hundreths of a second. Beyond this period, retransmits of a packet are not guaranteed, but are allowed to still happen.
Connection ID: ID to assign to the new channel.
Stateless reset token: Token to send back to cause a stateless reset.
The STREAM frame remains the same for the reliable stream, but for the other channel types redefine it:
STREAM for all message-based types:
0.......1.......2.......3.......4.......5.......6.......7.......
[ Stream ID ]
[ (Number) ]
[ (Length) ]
[Offset][ Data... ]
Stream ID: Stream ID for this frame to be associated with.
Number: If the offset bit is set, a monotonic, sequential enumeration associated with the channel. 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. If the length bit is not set, then the field is absent, and the data field extends to the rest of the packet.
Offset: If not all bits are set, then indicates the offset from the beginning of the data of the beginning of the first whole message after it. If all bits are set, then the entirety of the following data is a fragment of a larger message.
Data: The acutal portion of length and data pairs. The channel itself encodes messages as a sequence of length-data pairs, with the lengths encoded using QUIC's variable length integer encoding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment