Skip to content

Commit bcac772

Browse files
authored
Chunking 1.1: Split into reliable/ordered mode and unreliable/unordered mode (#153)
The reliable/ordered mode shortens the header to 1 byte and allows for implementation optimisations. The unreliable/unordered mode is backwards compatible with version 1.0. Further changes: - Add changelog - Make chunk duplication handling optional - Wording
1 parent 75e8691 commit bcac772

File tree

1 file changed

+89
-29
lines changed

1 file changed

+89
-29
lines changed

Chunking.md

+89-29
Original file line numberDiff line numberDiff line change
@@ -15,48 +15,77 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
1515
document are to be interpreted as described in [RFC
1616
2119](https://tools.ietf.org/html/rfc2119).
1717

18+
## Modes
19+
20+
This specification defines the following two modes:
21+
22+
* **Reliable/Ordered**: Intended for reliable and ordered transmission
23+
of chunks. The application that is reassembling chunks into a message
24+
MUST ensure that chunks of a message are not reordered. Furthermore,
25+
chunks of different messages SHALL NOT be interleaved.
26+
* **Unreliable/Unordered**: Intended for transmission of chunks where
27+
chunks MAY be lost or reordered. Additionally, an implementation MAY
28+
optionally be able to handle duplicated chunks.
29+
1830
## Chunk Size
1931

2032
The term *chunk size* is referring to the resulting size from the
2133
concatenation of *chunk header* and *chunk data* in bytes.
2234

2335
## Chunk Header
2436

25-
When converting data to chunks, a 9 byte header MUST be prepended to
26-
each chunk. This allows for sending a chunk over the network in any
27-
order.
28-
29-
### Length
30-
31-
The header is 9 bytes long.
37+
When converting data to chunks, a header MUST be prepended to each
38+
chunk of the following byte size:
3239

33-
### Format
40+
* 1 byte **short header** for reliable/ordered mode, and
41+
* 9 byte **long header** for unreliable/unordered mode.
3442

35-
The header is encoded in binary using network-oriented format (most
36-
significant byte first, also known as big-endian). It is structured as
37-
follows:
43+
Both header variants are encoded in binary using network-oriented format
44+
(most significant byte first, also known as big-endian).
3845

39-
|O|IIII|SSSS|
46+
### Short Header
4047

41-
- O: Options bit field (1 byte)
42-
- I: Message id (4 bytes)
43-
- S: Serial number (4 bytes)
48+
The short header contains a single byte called the *options bit field*:
4449

4550
**Options bit field**
4651

4752
The *options bit field* field is used to encode additional information
48-
about a chunk. Right now, only the least significant bit is being used.
49-
The other bits are reserved and MUST be set to `0`.
53+
about a chunk.
5054

5155
MSB LSB
5256
+---------------+
53-
|0 0 0 0 0 0 0 E|
57+
|R R R R R M M E|
5458
+---------------+
5559

60+
- R: Reserved, MUST be 0.
61+
62+
- M: Mode with the following values:
63+
64+
11 - reliable/ordered
65+
10 - reserved
66+
01 - reserved
67+
00 - unreliable/unordered
68+
5669
- E: End-of-message, this MUST be set to 1 if this is the
5770
last chunk of the message. Otherwise, it MUST be set
5871
to 0.
5972

73+
### Long Header
74+
75+
The long header contains a total of 9 bytes and is structured in the
76+
following way:
77+
78+
|O|IIII|SSSS|
79+
80+
- O: Options bit field (1 byte)
81+
- I: Message id (4 bytes)
82+
- S: Serial number (4 bytes)
83+
84+
**Options bit field**
85+
86+
Identical to the *options bit field* of the
87+
[Short Header](#short-header) format.
88+
6089
**Message id**
6190

6291
The *message id* SHALL be any 32 bit unsigned integer. It is RECOMMENDED
@@ -73,27 +102,58 @@ with 0 and MUST be incremented by 1 for every chunk.
73102
The chunk data MUST be appended to the chunk header. It MUST contain at
74103
least 1 byte of data.
75104

76-
Every chunk MUST contain up to `chunk size - 9` bytes of data. Only the
77-
last chunk of a message may contain less than `chunk size - 9` bytes of
78-
chunk data.
105+
Every chunk MUST contain up to `chunk size - header size` bytes of
106+
data unless it is the last chunk of a message in which case it MAY
107+
contain less than `chunk size - header size` bytes of data.
79108

80-
The chunk data MUST be chunked in a non-overlapping sequential way.
109+
The chunk data MUST be chunked in a non-overlapping, sequential way.
81110

82111
## Example
83112

84-
When chunking the byte sequence `12345678` with a chunk size of 12 and
85-
the message id 42, the data MUST be chunked into the following three
86-
chunks:
113+
### Reliable/Ordered Mode
114+
115+
When chunking the byte sequence `12345678` (where each digit is an 8
116+
bit unsigned integer) with a chunk size of 6, the data is being chunked
117+
into the following two chunks:
118+
119+
- First chunk: `0b00000110 || 0x0102030405`
120+
- Second chunk: `0b00000111 || 0x060708`
121+
122+
### Unreliable/Unordered Mode
123+
124+
When chunking the byte sequence `12345678` (where each digit is an 8
125+
bit unsigned integer) with a chunk size of 12 and the message id 42,
126+
the data is being chunked into the following three chunks:
87127

88128
- First chunk: `0b00000000 || 0x0000002a || 0x00000000 || 0x010203`
89129
- Second chunk: `0b00000000 || 0x0000002a || 0x00000001 || 0x040506`
90130
- Third chunk: `0b00000001 || 0x0000002a || 0x00000002 || 0x0708`
91131

92132
## Unchunking
93133

94-
Implementations MUST support unchunking of chunks that arrive in
95-
arbitrary order. This is usually done by keeping track of messages and
96-
the corresponding chunks.
97-
134+
In unordered/unreliable mode, implementations MUST support unchunking of
135+
chunks that arrive in arbitrary order. This is usually done by keeping
136+
track of messages and the corresponding chunks.
98137
In order to prevent memory leaks when chunks are lost in transmission,
99138
implementations SHOULD provide a way to clean up incomplete messages.
139+
140+
Implementations of the *unreliable/unordered* mode MAY optionally be
141+
able to handle duplicated chunks.
142+
143+
## Changelog
144+
145+
### 2019-02-06
146+
147+
Version 1.1
148+
149+
**Important**: Backwards compatibility to 1.0 can only be ensured by
150+
using the unreliable/unordered mode.
151+
152+
* Add reliable/ordered mode with 1 byte header
153+
154+
### 2016-09-29
155+
156+
Version 1.0
157+
158+
* Define unreliable/unordered mode with 9 byte header
159+

0 commit comments

Comments
 (0)