1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
/* SPDX-License-Identifier: Apache-2.0
* Copyright(c) 2025 Cisco Systems, Inc.
*/
#ifndef SRC_PLUGINS_HTTP_HTTP2_FRAME_H_
#define SRC_PLUGINS_HTTP_HTTP2_FRAME_H_
#include <vppinfra/error.h>
#include <vppinfra/types.h>
#include <http/http2/http2.h>
#define HTTP2_FRAME_HEADER_SIZE 9
#define foreach_http2_frame_type \
_ (0x00, DATA, "DATA") \
_ (0x01, HEADERS, "HEADERS") \
_ (0x02, PRIORITY, "PRIORITY") \
_ (0x03, RST_STREAM, "RST_STREAM") \
_ (0x04, SETTINGS, "SETTINGS") \
_ (0x05, PUSH_PROMISE, "PUSH_PROMISE") \
_ (0x06, PING, "PING") \
_ (0x07, GOAWAY, "GOAWAY") \
_ (0x08, WINDOW_UPDATE, "WINDOW_UPDATE") \
_ (0x09, CONTINUATION, "CONTINUATION")
typedef enum
{
#define _(v, n, s) HTTP2_FRAME_TYPE_##n = v,
foreach_http2_frame_type
#undef _
} __clib_packed http2_frame_type_t;
STATIC_ASSERT_SIZEOF (http2_frame_type_t, 1);
#define foreach_http2_frame_flag \
_ (0, NONE) \
_ (1, END_STREAM) \
_ (1, ACK) \
_ (1 << 2, END_HEADERS) \
_ (1 << 3, PADED) \
_ (1 << 5, PRIORITY)
typedef enum
{
#define _(v, n) HTTP2_FRAME_FLAG_##n = v,
foreach_http2_frame_flag
#undef _
} __clib_packed http2_frame_flag_t;
STATIC_ASSERT_SIZEOF (http2_frame_flag_t, 1);
typedef struct
{
u32 length;
http2_frame_type_t type;
u8 flags;
u32 stream_id;
} http2_frame_header_t;
typedef struct
{
u16 identifier;
u32 value;
} __clib_packed http2_settings_entry_t;
/**
* Parse frame header
*
* @param src Pointer to the beginning of the frame
* @param fh Parsed frame header
*/
void http2_frame_header_read (u8 *src, http2_frame_header_t *fh);
/**
* Add 9 bytes (frame header size) to the end of given vector
*
* @param dst Pointer to vector
*
* @return Pointer to the frame header beginning
*/
static_always_inline u8 *
http2_frame_header_alloc (u8 **dst)
{
u8 *p;
vec_add2 (*dst, p, HTTP2_FRAME_HEADER_SIZE);
return p;
}
/**
* Parse SETTINGS frame payload
*
* @param settings Vector of HTTP/2 settings
* @param payload Payload to parse
* @param payload_len Payload length
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_settings (http2_conn_settings_t *settings,
u8 *payload, u32 payload_len);
/**
* Write SETTINGS ACK frame to the end of given vector
*
* @param dst Vector where SETTINGS ACK frame will be written
*/
void http2_frame_write_settings_ack (u8 **dst);
/**
* Write SETTINGS frame to the end of given vector
*
* @param settings Vector of HTTP/2 settings
* @param dst Vector where SETTINGS frame will be written
*/
void http2_frame_write_settings (http2_settings_entry_t *settings, u8 **dst);
/**
* Parse WINDOW_UPDATE frame payload
*
* @param increment Parsed window increment value
* @param payload Payload to parse
* @param payload_len Payload length
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_window_update (u32 *increment, u8 *payload,
u32 payload_len);
/**
* Write WINDOW_UPDATE frame to the end of given vector
*
* @param increment Window increment value
* @param stream_id Stream ID
* @param dst Vector where WINDOW_UPDATE frame will be written
*/
void http2_frame_write_window_update (u32 increment, u32 stream_id, u8 **dst);
/**
* Parse RST_STREAM frame payload
*
* @param error_code Parsed error code
* @param payload Payload to parse
* @param payload_len Payload length
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_rst_stream (u32 *error_code, u8 *payload,
u32 payload_len);
/**
* Write RST_STREAM frame to the end of given vector
*
* @param error_code Error code
* @param stream_id Stream ID, except 0
* @param dst Vector where RST_STREAM frame will be written
*/
void http2_frame_write_rst_stream (http2_error_t error_code, u32 stream_id,
u8 **dst);
/**
* Parse GOAWAY frame payload
*
* @param last_stream_id Parsed last stream ID
* @param error_code Parsed error code
* @param payload Payload to parse
* @param payload_len Payload length
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_goaway (u32 *last_stream_id, u32 *error_code,
u8 *payload, u32 payload_len);
/**
* Write GOAWAY frame to the end of given vector
* @param error_code Error code
* @param last_stream_id Last stream ID
* @param dst Vector where GOAWAY frame will be written
*/
void http2_frame_write_goaway (http2_error_t error_code, u32 last_stream_id,
u8 **dst);
/**
* Parse HEADERS frame payload
*
* @param headers Pointer to header block fragment
* @param headers_len Header block fragment length
* @param payload Payload to parse
* @param payload_len Payload length
* @param flags Flag field of frame header
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_headers (u8 **headers, u32 *headers_len,
u8 *payload, u32 payload_len,
u8 flags);
/**
* Write HEADERS frame header
*
* @param headers_len Header block fragment length
* @param stream_id Stream ID, except 0
* @param flags Frame header flags
* @param dst Pointer where frame header will be written
*
* @note Use @c http2_frame_header_alloc before
*/
void http2_frame_write_headers_header (u32 headers_len, u32 stream_id,
u8 flags, u8 *dst);
/**
* Parse DATA frame payload
*
* @param headers Pointer to data
* @param headers_len Data length
* @param payload Payload to parse
* @param payload_len Payload length
* @param flags Flag field of frame header
*
* @return @c HTTP2_ERROR_NO_ERROR on success, error otherwise
*/
http2_error_t http2_frame_read_data (u8 **data, u32 *data_len, u8 *payload,
u32 payload_len, u8 flags);
/**
* Write DATA frame header
*
* @param data_len Data length
* @param stream_id Stream ID, except 0
* @param flags Frame header flags
* @param dst Pointer where frame header will be written
*/
void http2_frame_write_data_header (u32 data_len, u32 stream_id, u8 flags,
u8 *dst);
#endif /* SRC_PLUGINS_HTTP_HTTP2_FRAME_H_ */
|