summaryrefslogtreecommitdiffstats
path: root/include/haproxy/quic_frame-t.h
blob: 5e91f93208aa52ba23d225ccbc08b71fff895c22 (plain)
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
 * include/types/quic_frame.h
 * This file contains QUIC frame definitions.
 *
 * Copyright 2019 HAProxy Technologies, Frederic Lecaille <flecaille@haproxy.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _TYPES_QUIC_FRAME_H
#define _TYPES_QUIC_FRAME_H
#ifdef USE_QUIC
#ifndef USE_OPENSSL
#error "Must define USE_OPENSSL"
#endif

#include <inttypes.h>
#include <stdlib.h>

#include <import/ebtree-t.h>
#include <haproxy/buf-t.h>
#include <haproxy/list.h>
#include <haproxy/quic_stream-t.h>

extern struct pool_head *pool_head_quic_frame;
extern struct pool_head *pool_head_qf_crypto;

/* forward declarations from xprt-quic */
struct quic_arngs;
struct quic_enc_level;
struct quic_tx_packet;

/* QUIC frame types. */
enum quic_frame_type {
	QUIC_FT_PADDING      = 0x00,
	QUIC_FT_PING         = 0x01,
	QUIC_FT_ACK          = 0x02,
	QUIC_FT_ACK_ECN      = 0x03,
	QUIC_FT_RESET_STREAM = 0x04,
	QUIC_FT_STOP_SENDING = 0x05,
	QUIC_FT_CRYPTO       = 0x06,
	QUIC_FT_NEW_TOKEN    = 0x07,

	QUIC_FT_STREAM_8     = 0x08,
	QUIC_FT_STREAM_9     = 0x09,
	QUIC_FT_STREAM_A     = 0x0a,
	QUIC_FT_STREAM_B     = 0x0b,
	QUIC_FT_STREAM_C     = 0x0c,
	QUIC_FT_STREAM_D     = 0x0d,
	QUIC_FT_STREAM_E     = 0x0e,
	QUIC_FT_STREAM_F     = 0x0f,

	QUIC_FT_MAX_DATA             = 0x10,
	QUIC_FT_MAX_STREAM_DATA      = 0x11,
	QUIC_FT_MAX_STREAMS_BIDI     = 0x12,
	QUIC_FT_MAX_STREAMS_UNI      = 0x13,
	QUIC_FT_DATA_BLOCKED         = 0x14,
	QUIC_FT_STREAM_DATA_BLOCKED  = 0x15,
	QUIC_FT_STREAMS_BLOCKED_BIDI = 0x16,
	QUIC_FT_STREAMS_BLOCKED_UNI  = 0x17,
	QUIC_FT_NEW_CONNECTION_ID    = 0x18,
	QUIC_FT_RETIRE_CONNECTION_ID = 0x19,
	QUIC_FT_PATH_CHALLENGE       = 0x1a,
	QUIC_FT_PATH_RESPONSE        = 0x1b,
	QUIC_FT_CONNECTION_CLOSE     = 0x1c,
	QUIC_FT_CONNECTION_CLOSE_APP = 0x1d,
	QUIC_FT_HANDSHAKE_DONE       = 0x1e,
	/* Do not insert enums after the following one. */
	QUIC_FT_MAX
};

#define QUIC_FT_PKT_TYPE_I_BITMASK (1 << QUIC_PACKET_TYPE_INITIAL)
#define QUIC_FT_PKT_TYPE_0_BITMASK (1 << QUIC_PACKET_TYPE_0RTT)
#define QUIC_FT_PKT_TYPE_H_BITMASK (1 << QUIC_PACKET_TYPE_HANDSHAKE)
#define QUIC_FT_PKT_TYPE_1_BITMASK (1 << QUIC_PACKET_TYPE_SHORT)

#define QUIC_FT_PKT_TYPE_IH01_BITMASK \
	(QUIC_FT_PKT_TYPE_I_BITMASK | QUIC_FT_PKT_TYPE_H_BITMASK | \
	 QUIC_FT_PKT_TYPE_0_BITMASK | QUIC_FT_PKT_TYPE_1_BITMASK)

#define QUIC_FT_PKT_TYPE_IH_1_BITMASK \
	(QUIC_FT_PKT_TYPE_I_BITMASK | QUIC_FT_PKT_TYPE_H_BITMASK | \
	 QUIC_FT_PKT_TYPE_1_BITMASK)

#define QUIC_FT_PKT_TYPE___01_BITMASK \
	(QUIC_FT_PKT_TYPE_0_BITMASK | QUIC_FT_PKT_TYPE_1_BITMASK)

#define QUIC_FT_PKT_TYPE____1_BITMASK QUIC_FT_PKT_TYPE_1_BITMASK


/* Flag a TX frame as acknowledged */
#define QUIC_FL_TX_FRAME_ACKED             0x01

#define QUIC_STREAM_FRAME_TYPE_FIN_BIT     0x01
#define QUIC_STREAM_FRAME_TYPE_LEN_BIT     0x02
#define QUIC_STREAM_FRAME_TYPE_OFF_BIT     0x04

/* Servers have the stream initiator bit set. */
#define QUIC_STREAM_FRAME_ID_INITIATOR_BIT 0x01
/* Unidirectional streams have the direction bit set. */
#define QUIC_STREAM_FRAME_ID_DIR_BIT       0x02

#define QUIC_PATH_CHALLENGE_LEN         8
/* Maximum phrase length in CONNECTION_CLOSE frame */
#define QUIC_CC_REASON_PHRASE_MAXLEN   64

struct qf_padding {
	size_t len;
};

struct qf_ack {
	uint64_t largest_ack;
	uint64_t ack_delay;
	uint64_t ack_range_num;
	uint64_t first_ack_range;
};

/* Structure used when emitting ACK frames. */
struct qf_tx_ack {
	uint64_t ack_delay;
	struct quic_arngs *arngs;
};

struct qf_reset_stream {
	uint64_t id;
	uint64_t app_error_code;
	uint64_t final_size;
};

struct qf_stop_sending {
	uint64_t id;
	uint64_t app_error_code;
};

struct qf_crypto {
	struct list list;
	uint64_t offset;
	uint64_t len;
	const struct quic_enc_level *qel;
	const unsigned char *data;
};

struct qf_new_token {
	uint64_t len;
	const unsigned char *data;
};

struct qf_stream {
	uint64_t id;
	struct qc_stream_desc *stream;

	/* used only on TX when constructing frames.
	 * Data cleared when processing ACK related to this STREAM frame.
	 *
	 * A same buffer may be shared between several STREAM frames. The
	 * <data> field of each quic_stream serves to differentiate the payload
	 * of each of these.
	 */
	struct buffer *buf;

	struct eb64_node offset;
	uint64_t len;

	/* for TX pointer into <buf> field.
	 * for RX pointer into the packet buffer.
	 */
	const unsigned char *data;

	char dup; /* set for duplicated frame : this forces to check for the underlying qc_stream_buf instance before emitting it. */
};

struct qf_max_data {
	uint64_t max_data;
};

struct qf_max_stream_data {
	uint64_t id;
	uint64_t max_stream_data;
};

struct qf_max_streams {
	uint64_t max_streams;
};

struct qf_data_blocked {
	uint64_t limit;
};

struct qf_stream_data_blocked {
	uint64_t id;
	uint64_t limit;
};

struct qf_streams_blocked {
	uint64_t limit;
};

struct qf_new_connection_id {
	uint64_t seq_num;
	uint64_t retire_prior_to;
	struct {
		unsigned char len;
		const unsigned char *data;
	} cid;
	const unsigned char *stateless_reset_token;
};

struct qf_retire_connection_id {
	uint64_t seq_num;
};

struct qf_path_challenge {
	unsigned char data[QUIC_PATH_CHALLENGE_LEN];
};

struct qf_path_challenge_response {
	unsigned char data[QUIC_PATH_CHALLENGE_LEN];
};

struct qf_connection_close {
	uint64_t error_code;
	uint64_t frame_type;
	uint64_t reason_phrase_len;
	unsigned char reason_phrase[QUIC_CC_REASON_PHRASE_MAXLEN];
};

struct qf_connection_close_app {
	uint64_t error_code;
	uint64_t reason_phrase_len;
	unsigned char reason_phrase[QUIC_CC_REASON_PHRASE_MAXLEN];
};

struct quic_frame {
	struct list list;           /* List elem from parent elem (typically a Tx packet instance, a PKTNS or a MUX element). */
	struct quic_tx_packet *pkt; /* Last Tx packet used to send the frame. */
	unsigned char type;         /* QUIC frame type. */
	union {
		struct qf_padding padding;
		struct qf_ack ack;
		struct qf_tx_ack tx_ack;
		struct qf_crypto crypto;
		struct qf_reset_stream reset_stream;
		struct qf_stop_sending stop_sending;
		struct qf_new_token new_token;
		struct qf_stream stream;
		struct qf_max_data max_data;
		struct qf_max_stream_data max_stream_data;
		struct qf_max_streams max_streams_bidi;
		struct qf_max_streams max_streams_uni;
		struct qf_data_blocked data_blocked;
		struct qf_stream_data_blocked stream_data_blocked;
		struct qf_streams_blocked streams_blocked_bidi;
		struct qf_streams_blocked streams_blocked_uni;
		struct qf_new_connection_id new_connection_id;
		struct qf_retire_connection_id retire_connection_id;
		struct qf_path_challenge path_challenge;
		struct qf_path_challenge_response path_challenge_response;
		struct qf_connection_close connection_close;
		struct qf_connection_close_app connection_close_app;
	};
	struct quic_frame *origin;  /* Parent frame. Set if frame is a duplicate (used for retransmission). */
	struct list reflist;        /* List head containing duplicated children frames. */
	struct list ref;            /* List elem from parent frame reflist. Set if frame is a duplicate (used for retransmission). */
	unsigned int flags;         /* QUIC_FL_TX_FRAME_* */
	unsigned int loss_count;    /* Counter for each occurrence of this frame marked as lost. */
};


/* QUIC error codes */
struct quic_err {
	uint64_t code;  /* error code */
	int app;        /* set for Application error code */
};

/* Transport level error codes. */
#define QC_ERR_NO_ERROR                     0x00
#define QC_ERR_INTERNAL_ERROR               0x01
#define QC_ERR_CONNECTION_REFUSED           0x02
#define QC_ERR_FLOW_CONTROL_ERROR           0x03
#define QC_ERR_STREAM_LIMIT_ERROR           0x04
#define QC_ERR_STREAM_STATE_ERROR           0x05
#define QC_ERR_FINAL_SIZE_ERROR             0x06
#define QC_ERR_FRAME_ENCODING_ERROR         0x07
#define QC_ERR_TRANSPORT_PARAMETER_ERROR    0x08
#define QC_ERR_CONNECTION_ID_LIMIT_ERROR    0x09
#define QC_ERR_PROTOCOL_VIOLATION           0x0a
#define QC_ERR_INVALID_TOKEN                0x0b
#define QC_ERR_APPLICATION_ERROR            0x0c
#define QC_ERR_CRYPTO_BUFFER_EXCEEDED       0x0d
#define QC_ERR_KEY_UPDATE_ERROR             0x0e
#define QC_ERR_AEAD_LIMIT_REACHED           0x0f
#define QC_ERR_NO_VIABLE_PATH               0x10
/* 256 TLS reserved errors 0x100-0x1ff. */
#define QC_ERR_CRYPTO_ERROR                0x100

#endif /* USE_QUIC */
#endif /* _TYPES_QUIC_FRAME_H */