/
cache_http2.h
275 lines (225 loc) · 7.12 KB
/
cache_http2.h
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
/*-
* Copyright (c) 2016 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
struct h2_sess;
struct h2_req;
struct h2h_decode;
struct h2_frame_s;
#include "hpack/vhp.h"
/**********************************************************************/
struct h2_error_s {
const char *name;
const char *txt;
uint32_t val;
int stream;
int connection;
int send_goaway;
stream_close_t reason;
};
typedef const struct h2_error_s *h2_error;
#define H2_ERROR_MATCH(err, target) \
((err) != NULL && (err)->val == (target)->val)
#define H2_CUSTOM_ERRORS
#define H2EC1(U,v,g,r,d) extern const struct h2_error_s H2CE_##U[1];
#define H2EC2(U,v,g,r,d) extern const struct h2_error_s H2SE_##U[1];
#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
#define H2_ERROR(NAME, val, sc, goaway, reason, desc) \
H2EC##sc(NAME, val, goaway, reason, desc)
#include "tbl/h2_error.h"
#undef H2EC1
#undef H2EC2
#undef H2EC3
/**********************************************************************/
typedef h2_error h2_rxframe_f(struct worker *, struct h2_sess *,
struct h2_req *);
typedef const struct h2_frame_s *h2_frame;
struct h2_frame_s {
const char *name;
h2_rxframe_f *rxfunc;
uint8_t type;
uint8_t flags;
h2_error act_szero;
h2_error act_snonzero;
h2_error act_sidle;
int respect_window;
h2_frame continuation;
uint8_t final_flags;
int overhead;
};
#define H2_FRAME(l,U,...) extern const struct h2_frame_s H2_F_##U[1];
#include "tbl/h2_frames.h"
/**********************************************************************/
struct h2_settings {
#define H2_SETTING(U,l,...) uint32_t l;
#include "tbl/h2_settings.h"
};
typedef void h2_setsetting_f(struct h2_settings*, uint32_t);
struct h2_setting_s {
const char *name;
h2_setsetting_f *setfunc;
uint16_t ident;
uint32_t defval;
uint32_t minval;
uint32_t maxval;
h2_error range_error;
};
#define H2_SETTING(U,...) extern const struct h2_setting_s H2_SET_##U[1];
#include "tbl/h2_settings.h"
/**********************************************************************/
enum h2_stream_e {
H2_STREAM__DUMMY = -1,
#define H2_STREAM(U,s,d) H2_S_##U,
#include "tbl/h2_stream.h"
};
#define H2_FRAME_FLAGS(l,u,v) extern const uint8_t H2FF_##u;
#include "tbl/h2_frames.h"
struct h2_rxbuf {
unsigned magic;
#define H2_RXBUF_MAGIC 0x73f9fb27
unsigned size;
uint64_t tail;
uint64_t head;
struct stv_buffer *stvbuf;
uint8_t data[];
};
struct h2_req {
unsigned magic;
#define H2_REQ_MAGIC 0x03411584
uint32_t stream;
int scheduled;
enum h2_stream_e state;
int counted;
struct h2_sess *h2sess;
struct req *req;
double t_send;
double t_winupd;
pthread_cond_t *cond;
VTAILQ_ENTRY(h2_req) list;
int64_t t_window;
int64_t r_window;
/* Where to wake this stream up */
struct worker *wrk;
struct h2_rxbuf *rxbuf;
VTAILQ_ENTRY(h2_req) tx_list;
h2_error error;
};
VTAILQ_HEAD(h2_req_s, h2_req);
struct h2_sess {
unsigned magic;
#define H2_SESS_MAGIC 0xa16f7e4b
pthread_t rxthr;
pthread_cond_t *cond;
pthread_cond_t winupd_cond[1];
struct sess *sess;
int refcnt;
int open_streams;
int winup_streams;
uint32_t highest_stream;
int goaway;
int bogosity;
int do_sweep;
struct h2_req *req0;
struct h2_req_s streams;
struct req *srq;
struct ws *ws;
struct http_conn *htc;
struct vsl_log *vsl;
struct h2h_decode *decode;
struct vht_table dectbl[1];
unsigned rxf_len;
unsigned rxf_type;
unsigned rxf_flags;
unsigned rxf_stream;
uint8_t *rxf_data;
struct h2_settings remote_settings;
struct h2_settings local_settings;
struct req *new_req;
uint32_t goaway_last_stream;
VTAILQ_HEAD(,h2_req) txqueue;
h2_error error;
// rst rate limit parameters, copied from h2_* parameters
vtim_dur rapid_reset;
int64_t rapid_reset_limit;
vtim_dur rapid_reset_period;
// rst rate limit state
double rst_budget;
vtim_real last_rst;
};
#define ASSERT_RXTHR(h2) do {assert(h2->rxthr == pthread_self());} while(0)
/* http2/cache_http2_panic.c */
#ifdef TRANSPORT_MAGIC
vtr_sess_panic_f h2_sess_panic;
#endif
/* http2/cache_http2_deliver.c */
#ifdef TRANSPORT_MAGIC
vtr_deliver_f h2_deliver;
vtr_minimal_response_f h2_minimal_response;
#endif /* TRANSPORT_MAGIC */
/* http2/cache_http2_hpack.c */
struct h2h_decode {
unsigned magic;
#define H2H_DECODE_MAGIC 0xd092bde4
unsigned has_authority:1;
unsigned has_scheme:1;
h2_error error;
enum vhd_ret_e vhd_ret;
char *out;
char *reset;
size_t out_l;
size_t out_u;
size_t namelen;
struct vhd_decode vhd[1];
};
void h2h_decode_init(const struct h2_sess *h2);
h2_error h2h_decode_fini(const struct h2_sess *h2);
h2_error h2h_decode_bytes(struct h2_sess *h2, const uint8_t *ptr,
size_t len);
/* cache_http2_send.c */
void H2_Send_Get(struct worker *, struct h2_sess *, struct h2_req *);
void H2_Send_Rel(struct h2_sess *, const struct h2_req *);
void H2_Send_Frame(struct worker *, struct h2_sess *,
h2_frame type, uint8_t flags, uint32_t len, uint32_t stream,
const void *);
void H2_Send_RST(struct worker *wrk, struct h2_sess *h2,
const struct h2_req *r2, uint32_t stream, h2_error h2e);
void H2_Send(struct worker *, struct h2_req *, h2_frame type, uint8_t flags,
uint32_t len, const void *, uint64_t *acct);
/* cache_http2_proto.c */
struct h2_req * h2_new_req(struct h2_sess *, unsigned stream, struct req *);
h2_error h2_stream_tmo(struct h2_sess *, const struct h2_req *, vtim_real);
void h2_del_req(struct worker *, struct h2_req *);
void h2_kill_req(struct worker *, struct h2_sess *, struct h2_req *, h2_error);
int h2_rxframe(struct worker *, struct h2_sess *);
h2_error h2_set_setting(struct h2_sess *, const uint8_t *);
void h2_req_body(struct req*);
task_func_t h2_do_req;
#ifdef TRANSPORT_MAGIC
vtr_req_fail_f h2_req_fail;
#endif