Skip to content

Commit b4a45a6

Browse files
Make http2 context in TfwH2Conn pointer.
In previous commit we decide to allocate 2 pages after http2 connection and use free space after http2 connection structure for stream schedulers. But for negotiable (which can be http1 or http2) we use http2 connection structure also. So for such connections (if it is http1 connection) we allocate 2 pages for stream schedulers which are not used in fact. Now allocation strategy was changed: we allocate 2 pages for http2 context, which now is a pointer in http2 connection, so we don't allocate extra memory for http1 negotiable connection.
1 parent 3c70aef commit b4a45a6

17 files changed

+167
-109
lines changed

fw/connection.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ enum {
269269
/**
270270
* TLS hardened connection.
271271
*/
272-
typedef struct {
272+
typedef struct tfw_tls_conn_t {
273273
TfwCliConn cli_conn;
274274
TlsCtx tls;
275275
} TfwTlsConn;
@@ -279,9 +279,9 @@ typedef struct {
279279
/**
280280
* HTTP/2 connection.
281281
*/
282-
typedef struct {
282+
typedef struct tfw_h2_conn_t {
283283
TfwTlsConn tls_conn;
284-
TfwH2Ctx h2;
284+
TfwH2Ctx *h2;
285285
} TfwH2Conn;
286286

287287
/*
@@ -291,9 +291,7 @@ typedef struct {
291291
* accessing http2 context, when we are sure and not sure that tls handskare
292292
* was finished.
293293
*/
294-
#define tfw_h2_context_unsafe(conn) ((TfwH2Ctx *)(&((TfwH2Conn *)conn)->h2))
295-
#define tfw_h2_context_safe(conn) \
296-
ttls_hs_done(tfw_tls_context(conn)) ? tfw_h2_context_unsafe(conn) : NULL
294+
#define tfw_h2_context(conn) ((TfwH2Conn *)conn)->h2
297295

298296

299297
/* Callbacks used by l5-l7 protocols to operate on connection level. */

fw/hpack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3564,7 +3564,7 @@ __tfw_hpack_encode(TfwHttpResp *__restrict resp, TfwStr *__restrict hdr,
35643564
bool st_full_index;
35653565
unsigned short st_index, index = 0;
35663566
TfwConn *conn = resp->req->conn;
3567-
TfwH2Ctx *ctx = tfw_h2_context_unsafe(conn);
3567+
TfwH2Ctx *ctx = tfw_h2_context(conn);
35683568
TfwHPackETbl *tbl = &ctx->hpack.enc_tbl;
35693569
int r = HPACK_IDX_ST_NOT_FOUND;
35703570
bool name_indexed = true;

fw/http.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,7 +3037,7 @@ tfw_http_conn_drop(TfwConn *conn)
30373037

30383038
if (TFW_CONN_TYPE(conn) & Conn_Clnt) {
30393039
if (h2_mode) {
3040-
TfwH2Ctx *ctx = tfw_h2_context_safe(conn);
3040+
TfwH2Ctx *ctx = tfw_h2_context(conn);
30413041

30423042
if (ctx)
30433043
tfw_h2_conn_streams_cleanup(ctx);
@@ -5305,7 +5305,7 @@ ALLOW_ERROR_INJECTION(tfw_h2_append_predefined_body, ERRNO);
53055305
int
53065306
tfw_http_on_send_resp(void *conn, struct sk_buff **skb_head)
53075307
{
5308-
TfwH2Ctx *ctx = tfw_h2_context_unsafe((TfwConn *)conn);
5308+
TfwH2Ctx *ctx = tfw_h2_context((TfwConn *)conn);
53095309
struct tfw_skb_cb *tfw_cb = TFW_SKB_CB(*skb_head);
53105310
TfwStream *stream;
53115311

@@ -5440,7 +5440,7 @@ tfw_h2_error_resp(TfwHttpReq *req, int status, bool reply, ErrorType type,
54405440
{
54415441
TfwStream *stream;
54425442
TfwConn *conn = READ_ONCE(req->conn);
5443-
TfwH2Ctx *ctx = tfw_h2_context_unsafe(conn);
5443+
TfwH2Ctx *ctx = tfw_h2_context(conn);
54445444
bool close_after_send = (type == TFW_ERROR_TYPE_ATTACK ||
54455445
type == TFW_ERROR_TYPE_BAD);
54465446

@@ -6493,7 +6493,7 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
64936493
HTTP2_ECODE_PROTO);
64946494
}
64956495
if (TFW_MSG_H2(req)) {
6496-
TfwH2Ctx *ctx = tfw_h2_context_unsafe(conn);
6496+
TfwH2Ctx *ctx = tfw_h2_context(conn);
64976497

64986498
/* Do not check the request validity until
64996499
* it has been fully parsed.

fw/http2.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
static void
4141
tfw_h2_apply_wnd_sz_change(TfwH2Ctx *ctx, long int delta)
4242
{
43-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
43+
TfwH2Conn *conn = ctx->conn;
4444
TfwStream *stream, *next;
4545

4646
/*
@@ -71,7 +71,7 @@ static void
7171
tfw_h2_apply_settings_entry(TfwH2Ctx *ctx, unsigned short id,
7272
unsigned int val)
7373
{
74-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
74+
TfwH2Conn *conn = ctx->conn;
7575
TfwSettings *dest = &ctx->rsettings;
7676
long int delta;
7777

@@ -120,7 +120,7 @@ tfw_h2_apply_settings_entry(TfwH2Ctx *ctx, unsigned short id,
120120
int
121121
tfw_h2_check_settings_entry(TfwH2Ctx *ctx, unsigned short id, unsigned int val)
122122
{
123-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
123+
TfwH2Conn *conn = ctx->conn;
124124

125125
assert_spin_locked(&((TfwConn *)conn)->sk->sk_lock.slock);
126126

@@ -163,7 +163,7 @@ tfw_h2_check_settings_entry(TfwH2Ctx *ctx, unsigned short id, unsigned int val)
163163
void
164164
tfw_h2_save_settings_entry(TfwH2Ctx *ctx, unsigned short id, unsigned int val)
165165
{
166-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
166+
TfwH2Conn *conn = ctx->conn;
167167

168168
assert_spin_locked(&((TfwConn *)conn)->sk->sk_lock.slock);
169169

@@ -178,7 +178,7 @@ tfw_h2_save_settings_entry(TfwH2Ctx *ctx, unsigned short id, unsigned int val)
178178
void
179179
tfw_h2_apply_new_settings(TfwH2Ctx *ctx)
180180
{
181-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
181+
TfwH2Conn *conn = ctx->conn;
182182
unsigned int id;
183183

184184
assert_spin_locked(&((TfwConn *)conn)->sk->sk_lock.slock);
@@ -204,14 +204,27 @@ tfw_h2_cleanup(void)
204204
tfw_h2_stream_cache_destroy();
205205
}
206206

207+
TfwH2Ctx *
208+
tfw_h2_context_alloc(void)
209+
{
210+
return (TfwH2Ctx *)kzalloc(sizeof(TfwH2Ctx), GFP_ATOMIC);
211+
}
212+
213+
void
214+
tfw_h2_context_free(TfwH2Ctx *ctx)
215+
{
216+
kfree(ctx);
217+
}
218+
207219
int
208-
tfw_h2_context_init(TfwH2Ctx *ctx)
220+
tfw_h2_context_init(TfwH2Ctx *ctx, TfwH2Conn *conn)
209221
{
210222
TfwStreamQueue *closed_streams = &ctx->closed_streams;
211223
TfwStreamQueue *idle_streams = &ctx->idle_streams;
212224
TfwSettings *lset = &ctx->lsettings;
213225
TfwSettings *rset = &ctx->rsettings;
214226

227+
BUG_ON(!conn || conn->h2 != ctx);
215228
bzero_fast(ctx, sizeof(*ctx));
216229

217230
ctx->state = HTTP2_RECV_CLI_START_SEQ;
@@ -235,6 +248,7 @@ tfw_h2_context_init(TfwH2Ctx *ctx)
235248

236249
lset->wnd_sz = DEF_WND_SIZE;
237250
rset->wnd_sz = DEF_WND_SIZE;
251+
ctx->conn = conn;
238252

239253
return tfw_hpack_init(&ctx->hpack, HPACK_TABLE_DEF_SIZE);
240254
}
@@ -255,7 +269,7 @@ void
255269
tfw_h2_conn_terminate_close(TfwH2Ctx *ctx, TfwH2Err err_code, bool close,
256270
bool attack)
257271
{
258-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
272+
TfwH2Conn *conn = ctx->conn;
259273

260274
if (tfw_h2_send_goaway(ctx, err_code, attack) && close)
261275
tfw_connection_close((TfwConn *)conn, true);
@@ -291,7 +305,7 @@ void
291305
tfw_h2_conn_streams_cleanup(TfwH2Ctx *ctx)
292306
{
293307
TfwStream *cur, *next;
294-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
308+
TfwH2Conn *conn = ctx->conn;
295309
TfwStreamSched *sched = &ctx->sched;
296310

297311
WARN_ON_ONCE(((TfwConn *)conn)->stream.msg);
@@ -413,7 +427,7 @@ void
413427
tfw_h2_req_unlink_stream(TfwHttpReq *req)
414428
{
415429
TfwStream *stream;
416-
TfwH2Ctx *ctx = tfw_h2_context_unsafe(req->conn);
430+
TfwH2Ctx *ctx = tfw_h2_context(req->conn);
417431

418432
spin_lock(&ctx->lock);
419433

@@ -437,7 +451,7 @@ void
437451
tfw_h2_req_unlink_and_close_stream(TfwHttpReq *req)
438452
{
439453
TfwStream *stream;
440-
TfwH2Ctx *ctx = tfw_h2_context_unsafe(req->conn);
454+
TfwH2Ctx *ctx = tfw_h2_context(req->conn);
441455

442456
spin_lock(&ctx->lock);
443457

fw/http2.h

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@
3939
* to accept;
4040
*/
4141
typedef struct {
42-
unsigned int hdr_tbl_sz;
43-
unsigned int push;
44-
unsigned int max_streams;
45-
unsigned int wnd_sz;
46-
unsigned int max_frame_sz;
47-
unsigned int max_lhdr_sz;
42+
unsigned int hdr_tbl_sz;
43+
unsigned int push;
44+
unsigned int max_streams;
45+
unsigned int wnd_sz;
46+
unsigned int max_frame_sz;
47+
unsigned int max_lhdr_sz;
4848
} TfwSettings;
4949

50+
typedef struct tfw_conn_t TfwConn;
51+
5052
/**
5153
* Context for HTTP/2 frames processing.
5254
*
@@ -80,6 +82,7 @@ typedef struct {
8082
* to save what @new_settings should be applyed. bits
8183
* from _HTTP2_SETTINGS_MAX are used to save what
8284
* settings we sent to the client;
85+
* @conn - pointer to h2 connection of this context;
8386
* @__off - offset to reinitialize processing context;
8487
* @skb_head - collected list of processed skbs containing HTTP/2
8588
* frames;
@@ -108,59 +111,62 @@ typedef struct {
108111
* stream (RFC 7540, sections 6.2, 6.10, 8.1).
109112
*/
110113
typedef struct tfw_h2_ctx_t {
111-
spinlock_t lock;
112-
TfwSettings lsettings;
113-
TfwSettings rsettings;
114-
unsigned int lstream_id;
115-
unsigned long streams_num;
116-
TfwStreamSched sched;
117-
TfwStreamQueue closed_streams;
118-
TfwStreamQueue idle_streams;
119-
long int loc_wnd;
120-
long int rem_wnd;
121-
TfwHPack hpack;
122-
TfwStream *cur_send_headers;
123-
TfwStream *cur_recv_headers;
124-
TfwStream *error;
125-
unsigned int new_settings[_HTTP2_SETTINGS_MAX - 1];
126-
DECLARE_BITMAP (settings_to_apply, 2 * _HTTP2_SETTINGS_MAX - 1);
127-
char __off[0];
128-
struct sk_buff *skb_head;
129-
TfwStream *cur_stream;
130-
TfwFramePri priority;
131-
TfwFrameHdr hdr;
132-
unsigned int plen;
133-
int state;
134-
int to_read;
135-
int rlen;
136-
unsigned char rbuf[FRAME_HEADER_SIZE];
137-
unsigned char padlen;
138-
unsigned char data_off;
114+
spinlock_t lock;
115+
TfwSettings lsettings;
116+
TfwSettings rsettings;
117+
unsigned int lstream_id;
118+
unsigned long streams_num;
119+
TfwStreamSched sched;
120+
TfwStreamQueue closed_streams;
121+
TfwStreamQueue idle_streams;
122+
long int loc_wnd;
123+
long int rem_wnd;
124+
TfwHPack hpack;
125+
TfwStream *cur_send_headers;
126+
TfwStream *cur_recv_headers;
127+
TfwStream *error;
128+
unsigned int new_settings[_HTTP2_SETTINGS_MAX - 1];
129+
DECLARE_BITMAP (settings_to_apply, 2 * _HTTP2_SETTINGS_MAX - 1);
130+
TfwH2Conn *conn;
131+
char __off[0];
132+
struct sk_buff *skb_head;
133+
TfwStream *cur_stream;
134+
TfwFramePri priority;
135+
TfwFrameHdr hdr;
136+
unsigned int plen;
137+
int state;
138+
int to_read;
139+
int rlen;
140+
unsigned char rbuf[FRAME_HEADER_SIZE];
141+
unsigned char padlen;
142+
unsigned char data_off;
139143
} TfwH2Ctx;
140144

141145
int tfw_h2_init(void);
142146
void tfw_h2_cleanup(void);
143-
int tfw_h2_context_init(TfwH2Ctx *ctx);
147+
TfwH2Ctx *tfw_h2_context_alloc(void);
148+
void tfw_h2_context_free(TfwH2Ctx *ctx);
149+
int tfw_h2_context_init(TfwH2Ctx *ctx, TfwH2Conn *conn);
144150
void tfw_h2_context_clear(TfwH2Ctx *ctx);
145151
int tfw_h2_check_settings_entry(TfwH2Ctx *ctx, unsigned short id,
146-
unsigned int val);
152+
unsigned int val);
147153
void tfw_h2_save_settings_entry(TfwH2Ctx *ctx, unsigned short id,
148-
unsigned int val);
154+
unsigned int val);
149155
void tfw_h2_apply_new_settings(TfwH2Ctx *ctx);
150156
void tfw_h2_conn_terminate_close(TfwH2Ctx *ctx, TfwH2Err err_code, bool close,
151-
bool attack);
157+
bool attack);
152158
void tfw_h2_conn_streams_cleanup(TfwH2Ctx *ctx);
153159
void tfw_h2_current_stream_remove(TfwH2Ctx *ctx);
154160
int tfw_h2_current_stream_send_rst(TfwH2Ctx *ctx, int err_code);
155161
void tfw_h2_remove_idle_streams(TfwH2Ctx *ctx, unsigned int id);
156162
void tfw_h2_closed_streams_shrink(TfwH2Ctx *ctx);
157163
void tfw_h2_check_current_stream_is_closed(TfwH2Ctx *ctx);
158164
TfwStream *tfw_h2_find_not_closed_stream(TfwH2Ctx *ctx, unsigned int id,
159-
bool recv);
165+
bool recv);
160166
void tfw_h2_req_unlink_stream(TfwHttpReq *req);
161167
void tfw_h2_req_unlink_and_close_stream(TfwHttpReq *req);
162168
int tfw_h2_stream_xmit_prepare_resp(TfwStream *stream);
163169
int tfw_h2_entail_stream_skb(struct sock *sk, TfwH2Ctx *ctx, TfwStream *stream,
164-
unsigned int *len, bool should_split);
170+
unsigned int *len, bool should_split);
165171

166172
#endif /* __HTTP2__ */

fw/http_frame.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ ctx_new_settings_flags[] = {
195195
static void
196196
tfw_h2_on_tcp_entail_ack(void *conn, struct sk_buff *skb_head)
197197
{
198-
TfwH2Ctx *ctx = tfw_h2_context_unsafe((TfwConn *)conn);
198+
TfwH2Ctx *ctx = tfw_h2_context((TfwConn *)conn);
199199

200200
if (test_bit(HTTP2_SETTINGS_NEED_TO_APPLY, ctx->settings_to_apply))
201201
tfw_h2_apply_new_settings(ctx);
@@ -204,7 +204,7 @@ tfw_h2_on_tcp_entail_ack(void *conn, struct sk_buff *skb_head)
204204
static int
205205
tfw_h2_on_send_goaway(void *conn, struct sk_buff **skb_head)
206206
{
207-
TfwH2Ctx *ctx = tfw_h2_context_unsafe((TfwConn *)conn);
207+
TfwH2Ctx *ctx = tfw_h2_context((TfwConn *)conn);
208208

209209
if (ctx->error && ctx->error->xmit.skb_head) {
210210
ss_skb_queue_splice(&ctx->error->xmit.skb_head, skb_head);
@@ -224,7 +224,7 @@ tfw_h2_on_send_goaway(void *conn, struct sk_buff **skb_head)
224224
static int
225225
tfw_h2_on_send_rst_stream(void *conn, struct sk_buff **skb_head)
226226
{
227-
TfwH2Ctx *ctx = tfw_h2_context_unsafe((TfwConn *)conn);
227+
TfwH2Ctx *ctx = tfw_h2_context((TfwConn *)conn);
228228
unsigned int stream_id = TFW_SKB_CB(*skb_head)->stream_id;
229229
TfwStream *stream;
230230

@@ -249,7 +249,7 @@ tfw_h2_on_send_rst_stream(void *conn, struct sk_buff **skb_head)
249249
static int
250250
tfw_h2_on_send_dflt(void *conn, struct sk_buff **skb_head)
251251
{
252-
TfwH2Ctx *ctx = tfw_h2_context_unsafe((TfwConn *)conn);
252+
TfwH2Ctx *ctx = tfw_h2_context((TfwConn *)conn);
253253

254254
if (ctx->cur_send_headers) {
255255
ss_skb_queue_splice(&ctx->cur_send_headers->xmit.postponed,
@@ -277,7 +277,7 @@ __tfw_h2_send_frame(TfwH2Ctx *ctx, TfwFrameHdr *hdr, TfwStr *data,
277277
TfwMsg msg = {};
278278
unsigned char buf[FRAME_HEADER_SIZE];
279279
TfwStr *hdr_str = TFW_STR_CHUNK(data, 0);
280-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
280+
TfwH2Conn *conn = ctx->conn;
281281

282282
BUG_ON(hdr_str->data);
283283
hdr_str->data = buf;
@@ -682,7 +682,7 @@ tfw_h2_wnd_update_process(TfwH2Ctx *ctx)
682682

683683
wnd_incr = ntohl(*(unsigned int *)ctx->rbuf) & ((1U << 31) - 1);
684684
if (wnd_incr) {
685-
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
685+
TfwH2Conn *conn = ctx->conn;
686686
long int *window = ctx->cur_stream ?
687687
&ctx->cur_stream->rem_wnd : &ctx->rem_wnd;
688688

@@ -1685,7 +1685,7 @@ tfw_h2_frame_process(TfwConn *c, struct sk_buff *skb, struct sk_buff **next)
16851685
int r;
16861686
bool postponed;
16871687
unsigned int parsed, unused;
1688-
TfwH2Ctx *h2 = tfw_h2_context_unsafe(c);
1688+
TfwH2Ctx *h2 = tfw_h2_context(c);
16891689
struct sk_buff *nskb = NULL;
16901690

16911691
next_msg:

fw/http_frame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ typedef enum {
153153
#define MAX_WND_SIZE ((1U << 31) - 1)
154154
#define DEF_WND_SIZE ((1U << 16) - 1)
155155

156-
typedef struct tfw_conn_t TfwConn;
156+
typedef struct tfw_h2_conn_t TfwH2Conn;
157157

158158
int tfw_h2_frame_process(TfwConn *c, struct sk_buff *skb,
159159
struct sk_buff **next);

0 commit comments

Comments
 (0)