Bladeren bron

[peerdist] Add support for constructing and decoding retrieval messages

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 jaren geleden
bovenliggende
commit
a8d9cd9485
1 gewijzigde bestanden met toevoegingen van 376 en 0 verwijderingen
  1. 376
    0
      src/include/ipxe/pccrr.h

+ 376
- 0
src/include/ipxe/pccrr.h Bestand weergeven

@@ -0,0 +1,376 @@
1
+#ifndef _IPXE_PCCRR_H
2
+#define _IPXE_PCCRR_H
3
+
4
+/** @file
5
+ *
6
+ * Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR]
7
+ *
8
+ * All fields are in network byte order.
9
+ *
10
+ */
11
+
12
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
13
+
14
+#include <stdint.h>
15
+#include <ipxe/uaccess.h>
16
+
17
+/** Magic retrieval URI path */
18
+#define PEERDIST_MAGIC_PATH "/116B50EB-ECE2-41ac-8429-9F9E963361B7/"
19
+
20
+/** Retrieval protocol version */
21
+union peerdist_msg_version {
22
+	/** Raw version number */
23
+	uint32_t raw;
24
+	/** Major:minor version number */
25
+	struct {
26
+		/** Minor version number */
27
+		uint16_t minor;
28
+		/** Major version number */
29
+		uint16_t major;
30
+	} __attribute__ (( packed ));
31
+} __attribute__ (( packed ));
32
+
33
+/** Retrieval protocol version 1.0 */
34
+#define PEERDIST_MSG_VERSION_1_0 0x00000001UL
35
+
36
+/** Retrieval protocol version 2.0 */
37
+#define PEERDIST_MSG_VERSION_2_0 0x00000002UL
38
+
39
+/** Retrieval protocol supported versions */
40
+struct peerdist_msg_versions {
41
+	/** Minimum supported protocol version */
42
+	union peerdist_msg_version min;
43
+	/** Maximum supported protocol version */
44
+	union peerdist_msg_version max;
45
+} __attribute__ (( packed ));
46
+
47
+/** Retrieval protocol block range */
48
+struct peerdist_msg_range {
49
+	/** First block in range */
50
+	uint32_t first;
51
+	/** Number of blocks in range */
52
+	uint32_t count;
53
+} __attribute__ (( packed ));
54
+
55
+/** Retrieval protocol segment ID header */
56
+struct peerdist_msg_segment {
57
+	/** Digest size (i.e. length of segment ID) */
58
+	uint32_t digestsize;
59
+	/* Followed by a single variable-length ID and padding:
60
+	 *
61
+	 * uint8_t id[digestsize];
62
+	 * uint8_t pad[ (-digestsize) & 0x3 ];
63
+	 */
64
+} __attribute__ (( packed ));
65
+
66
+/** Retrieval protocol segment ID
67
+ *
68
+ * @v digestsize	Digest size
69
+ */
70
+#define peerdist_msg_segment_t( digestsize )				\
71
+	struct {							\
72
+		struct peerdist_msg_segment segment;			\
73
+		uint8_t id[digestsize];					\
74
+		uint8_t pad[ ( -(digestsize) ) & 0x3 ];			\
75
+	} __attribute__ (( packed ))
76
+
77
+/** Retrieval protocol block range list header */
78
+struct peerdist_msg_ranges {
79
+	/** Number of ranges */
80
+	uint32_t count;
81
+	/* Followed by an array of block ranges:
82
+	 *
83
+	 * struct peerdist_msg_range range[count];
84
+	 */
85
+} __attribute__ (( packed ));
86
+
87
+/** Retrieval protocol block range list
88
+ *
89
+ * @v count		Number of ranges
90
+ */
91
+#define peerdist_msg_ranges_t( count )					\
92
+	struct {							\
93
+		struct peerdist_msg_ranges ranges;			\
94
+		struct peerdist_msg_range range[count];			\
95
+	} __attribute__ (( packed ))
96
+
97
+/** Retrieval protocol data block header */
98
+struct peerdist_msg_block {
99
+	/** Length of data block */
100
+	uint32_t len;
101
+	/* Followed by the (encrypted) data block:
102
+	 *
103
+	 * uint8_t data[len];
104
+	 */
105
+} __attribute__ (( packed ));
106
+
107
+/** Retrieval protocol data block */
108
+#define peerdist_msg_block_t( len )					\
109
+	struct {							\
110
+		struct peerdist_msg_block block;			\
111
+		uint8_t data[len];					\
112
+	} __attribute__ (( packed ))
113
+
114
+/** Retrieval protocol initialisation vector header */
115
+struct peerdist_msg_iv {
116
+	/** Cipher block size */
117
+	uint32_t blksize;
118
+	/* Followed by the initialisation vector:
119
+	 *
120
+	 * uint8_t data[blksize];
121
+	 */
122
+} __attribute__ (( packed ));
123
+
124
+/** Retrieval protocol initialisation vector */
125
+#define peerdist_msg_iv_t( blksize )					\
126
+	struct {							\
127
+		struct peerdist_msg_iv iv;				\
128
+		uint8_t data[blksize];					\
129
+	} __attribute__ (( packed ))
130
+
131
+/** Retrieval protocol useless VRF data header */
132
+struct peerdist_msg_useless_vrf {
133
+	/** Length of useless VRF data */
134
+	uint32_t len;
135
+	/* Followed by a variable-length useless VRF data block and
136
+	 * padding:
137
+	 *
138
+	 * uint8_t data[len];
139
+	 * uint8_t pad[ (-len) & 0x3 ];
140
+	 */
141
+} __attribute__ (( packed ));
142
+
143
+/** Retrieval protocol useless VRF data */
144
+#define peerdist_msg_useless_vrf_t( vrf_len )				\
145
+	struct {							\
146
+		struct peerdist_msg_useless_vrf vrf;			\
147
+		uint8_t data[vrf_len];					\
148
+		uint8_t pad[ ( -(vrf_len) ) & 0x3 ];			\
149
+	} __attribute__ (( packed ))
150
+
151
+/** Retrieval protocol message header */
152
+struct peerdist_msg_header {
153
+	/** Protocol version
154
+	 *
155
+	 * This is the protocol version in which the message type was
156
+	 * first defined.
157
+	 */
158
+	union peerdist_msg_version version;
159
+	/** Message type */
160
+	uint32_t type;
161
+	/** Message size (including this header) */
162
+	uint32_t len;
163
+	/** Cryptographic algorithm ID */
164
+	uint32_t algorithm;
165
+} __attribute__ (( packed ));
166
+
167
+/** Retrieval protocol cryptographic algorithm IDs */
168
+enum peerdist_msg_algorithm {
169
+	/** No encryption */
170
+	PEERDIST_MSG_PLAINTEXT = 0x00000000UL,
171
+	/** AES-128 in CBC mode */
172
+	PEERDIST_MSG_AES_128_CBC = 0x00000001UL,
173
+	/** AES-192 in CBC mode */
174
+	PEERDIST_MSG_AES_192_CBC = 0x00000002UL,
175
+	/** AES-256 in CBC mode */
176
+	PEERDIST_MSG_AES_256_CBC = 0x00000003UL,
177
+};
178
+
179
+/** Retrieval protocol transport response header */
180
+struct peerdist_msg_transport_header {
181
+	/** Length (excluding this header)
182
+	 *
183
+	 * This seems to be identical in both purpose and value to the
184
+	 * length found within the message header, and therefore
185
+	 * serves no useful purpose.
186
+	 */
187
+	uint32_t len;
188
+} __attribute__ (( packed ));
189
+
190
+/** Retrieval protocol negotiation request */
191
+struct peerdist_msg_nego_req {
192
+	/** Message header */
193
+	struct peerdist_msg_header hdr;
194
+	/** Supported versions */
195
+	struct peerdist_msg_versions versions;
196
+} __attribute__ (( packed ));
197
+
198
+/** Retrieval protocol negotiation request version */
199
+#define PEERDIST_MSG_NEGO_REQ_VERSION PEERDIST_MSG_VERSION_1_0
200
+
201
+/** Retrieval protocol negotiation request type */
202
+#define PEERDIST_MSG_NEGO_REQ_TYPE 0x00000000UL
203
+
204
+/** Retrieval protocol negotiation response */
205
+struct peerdist_msg_nego_resp {
206
+	/** Message header */
207
+	struct peerdist_msg_header hdr;
208
+	/** Supported versions */
209
+	struct peerdist_msg_versions versions;
210
+} __attribute__ (( packed ));
211
+
212
+/** Retrieval protocol negotiation response version */
213
+#define PEERDIST_MSG_NEGO_RESP_VERSION PEERDIST_MSG_VERSION_1_0
214
+
215
+/** Retrieval protocol negotiation response type */
216
+#define PEERDIST_MSG_NEGO_RESP_TYPE 0x00000001UL
217
+
218
+/** Retrieval protocol block list request header */
219
+struct peerdist_msg_getblklist {
220
+	/** Message header */
221
+	struct peerdist_msg_header hdr;
222
+	/* Followed by a segment ID and a block range list:
223
+	 *
224
+	 * peerdist_msg_segment_t(digestsize) segment;
225
+	 * peerdist_msg_ranges_t(count) ranges;
226
+	 */
227
+} __attribute__ (( packed ));
228
+
229
+/** Retrieval protocol block list request
230
+ *
231
+ * @v digestsize	Digest size
232
+ * @v count		Block range count
233
+ */
234
+#define peerdist_msg_getblklist_t( digestsize, count )			\
235
+	struct {							\
236
+		struct peerdist_msg_getblklist getblklist;		\
237
+		peerdist_msg_segment_t ( digestsize ) segment;		\
238
+		peerdist_msg_ranges_t ( count ) ranges;			\
239
+	} __attribute__ (( packed ))
240
+
241
+/** Retrieval protocol block list request version */
242
+#define PEERDIST_MSG_GETBLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
243
+
244
+/** Retrieval protocol block list request type */
245
+#define PEERDIST_MSG_GETBLKLIST_TYPE 0x00000002UL
246
+
247
+/** Retrieval protocol block fetch request header */
248
+struct peerdist_msg_getblks {
249
+	/** Message header */
250
+	struct peerdist_msg_header hdr;
251
+	/* Followed by a segment ID, a block range list, and a useless
252
+	 * VRF block:
253
+	 *
254
+	 * peerdist_msg_segment_t(digestsize) segment;
255
+	 * peerdist_msg_ranges_t(count) ranges;
256
+	 * peerdist_msg_vrf_t(vrf_len) vrf;
257
+	 */
258
+} __attribute__ (( packed ));
259
+
260
+/** Retrieval protocol block fetch request
261
+ *
262
+ * @v digestsize	Digest size
263
+ * @v count		Block range count
264
+ * @v vrf_len		Length of uselessness
265
+ */
266
+#define peerdist_msg_getblks_t( digestsize, count, vrf_len )		\
267
+	struct {							\
268
+		struct peerdist_msg_getblks getblks;			\
269
+		peerdist_msg_segment_t ( digestsize ) segment;		\
270
+		peerdist_msg_ranges_t ( count ) ranges;			\
271
+		peerdist_msg_useless_vrf_t ( vrf_len );			\
272
+	} __attribute__ (( packed ))
273
+
274
+/** Retrieval protocol block fetch request version */
275
+#define PEERDIST_MSG_GETBLKS_VERSION PEERDIST_MSG_VERSION_1_0
276
+
277
+/** Retrieval protocol block fetch request type */
278
+#define PEERDIST_MSG_GETBLKS_TYPE 0x00000003UL
279
+
280
+/** Retrieval protocol block list response header */
281
+struct peerdist_msg_blklist {
282
+	/** Message header */
283
+	struct peerdist_msg_header hdr;
284
+	/* Followed by a segment ID, a block range list, and a next
285
+	 * block index:
286
+	 *
287
+	 * peerdist_msg_segment_t(digestsize) segment;
288
+	 * peerdist_msg_ranges_t(count) ranges;
289
+	 * uint32_t next;
290
+	 */
291
+} __attribute__ (( packed ));
292
+
293
+/** Retrieval protocol block list response
294
+ *
295
+ * @v digestsize	Digest size
296
+ * @v count		Block range count
297
+ */
298
+#define peerdist_msg_blklist_t( digestsize, count )			\
299
+	struct {							\
300
+		struct peerdist_msg_blklist blklist;			\
301
+		peerdist_msg_segment_t ( digestsize ) segment;		\
302
+		peerdist_msg_ranges_t ( count ) ranges;			\
303
+		uint32_t next;						\
304
+	} __attribute__ (( packed ))
305
+
306
+/** Retrieval protocol block list response version */
307
+#define PEERDIST_MSG_BLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
308
+
309
+/** Retrieval protocol block list response type */
310
+#define PEERDIST_MSG_BLKLIST_TYPE 0x00000004UL
311
+
312
+/** Retrieval protocol block fetch response header */
313
+struct peerdist_msg_blk {
314
+	/** Message header */
315
+	struct peerdist_msg_header hdr;
316
+	/* Followed by a segment ID, a block index, a next block
317
+	 * index, a data block, a useless VRF block, and an
318
+	 * initialisation vector:
319
+	 *
320
+	 * peerdist_msg_segment_t(digestsize) segment;
321
+	 * uint32_t index;
322
+	 * uint32_t next;
323
+	 * peerdist_msg_block_t(len) data;
324
+	 * peerdist_msg_useless_vrf_t(vrf_len) vrf;
325
+	 * peerdist_msg_iv_t(blksize) iv;
326
+	 */
327
+} __attribute__ (( packed ));
328
+
329
+/** Retrieval protocol block fetch response
330
+ *
331
+ * @v digestsize	Digest size
332
+ * @v len		Data block length
333
+ * @v vrf_len		Length of uselessness
334
+ * @v blksize		Cipher block size
335
+ */
336
+#define peerdist_msg_blk_t( digestsize, len, vrf_len, blksize )		\
337
+	struct {							\
338
+		struct peerdist_msg_blk blk;				\
339
+		peerdist_msg_segment_t ( digestsize ) segment;		\
340
+		uint32_t index;						\
341
+		uint32_t next;						\
342
+		peerdist_msg_block_t ( len ) block;			\
343
+		peerdist_msg_useless_vrf_t ( vrf_len ) vrf;		\
344
+		peerdist_msg_iv_t ( blksize ) iv;			\
345
+	} __attribute__ (( packed ))
346
+
347
+/** Retrieval protocol block fetch response version */
348
+#define PEERDIST_MSG_BLK_VERSION PEERDIST_MSG_VERSION_1_0
349
+
350
+/** Retrieval protocol block fetch response type */
351
+#define PEERDIST_MSG_BLK_TYPE 0x00000005UL
352
+
353
+/**
354
+ * Parse retrieval protocol block fetch response
355
+ *
356
+ * @v raw		Raw data
357
+ * @v raw_len		Length of raw data
358
+ * @v digestsize	Digest size
359
+ * @v blksize		Cipher block size
360
+ * @v blk		Structure to fill in
361
+ * @ret rc		Return status code
362
+ */
363
+#define peerdist_msg_blk( raw, raw_len, digestsize, blksize, blk ) ( {	\
364
+	assert ( sizeof ( (blk)->segment.id ) == (digestsize) );	\
365
+	assert ( sizeof ( (blk)->block.data ) == 0 );			\
366
+	assert ( sizeof ( (blk)->vrf.data ) == 0 );			\
367
+	assert ( sizeof ( (blk)->iv.data ) == blksize );		\
368
+	peerdist_msg_blk_untyped ( (raw), (raw_len), (digestsize),	\
369
+				   (blksize), blk );			\
370
+	} )
371
+
372
+extern int peerdist_msg_blk_untyped ( userptr_t raw, size_t raw_len,
373
+				      size_t digestsize, size_t blksize,
374
+				      void *out );
375
+
376
+#endif /* _IPXE_PCCRR_H */

Laden…
Annuleren
Opslaan