Skip to content

Commit 0a28e8e

Browse files
committed
Replace GFSM calls with direct calls to TLS and HTTP
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <[email protected]> Signed-off-by: Aleksey Mikhaylov <[email protected]>
1 parent abc9c21 commit 0a28e8e

14 files changed

+84
-145
lines changed

fw/connection.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Generic connection management.
55
*
66
* Copyright (C) 2014 NatSys Lab. ([email protected]).
7-
* Copyright (C) 2015-2021 Tempesta Technologies, Inc.
7+
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
88
*
99
* This program is free software; you can redistribute it and/or modify it
1010
* under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
2424
#include "gfsm.h"
2525
#include "log.h"
2626
#include "sync_socket.h"
27+
#include "http.h"
2728

2829
TfwConnHooks *conn_hooks[TFW_CONN_MAX_PROTOS];
2930

@@ -131,7 +132,7 @@ tfw_connection_recv(void *cdata, struct sk_buff *skb)
131132
.skb = skb,
132133
};
133134

134-
return tfw_gfsm_dispatch(&conn->state, conn, &fsm_data);
135+
return tfw_http_msg_process(conn, &fsm_data);
135136
}
136137

137138
void

fw/connection.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Definitions for generic connection management at OSI level 6 (presentation).
55
*
66
* Copyright (C) 2014 NatSys Lab. ([email protected]).
7-
* Copyright (C) 2015-2019 Tempesta Technologies, Inc.
7+
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
88
*
99
* This program is free software; you can redistribute it and/or modify it
1010
* under the terms of the GNU General Public License as published by
@@ -100,7 +100,7 @@ enum {
100100
struct sock *sk; \
101101
void (*destructor)(void *);
102102

103-
typedef struct {
103+
typedef struct TfwConn {
104104
TFW_CONN_COMMON;
105105
} TfwConn;
106106

fw/gfsm.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Tempesta FW
33
*
44
* Copyright (C) 2014 NatSys Lab. ([email protected]).
5-
* Copyright (C) 2015-2018 Tempesta Technologies, Inc.
5+
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
66
*
77
* This program is free software; you can redistribute it and/or modify it
88
* under the terms of the GNU General Public License as published by
@@ -88,7 +88,6 @@ enum {
8888
/* Security rules enforcement. */
8989
TFW_FSM_FRANG_REQ,
9090
TFW_FSM_FRANG_RESP,
91-
TFW_FSM_FRANG_TLS,
9291

9392
TFW_FSM_NUM /* Must be <= TFW_GFSM_FSM_N */
9493
};
@@ -178,11 +177,12 @@ typedef struct {
178177
unsigned short states[TFW_GFSM_FSM_NUM];
179178
} TfwGState;
180179

181-
#define TFW_GFSM_STATE(s) ((s)->states[(unsigned char)(s)->curr] \
182-
& ((TFW_GFSM_FSM_MASK << TFW_GFSM_FSM_SHIFT) \
183-
| TFW_GFSM_STATE_MASK))
180+
#define TFW_GFSM_STATE(s) ((s)->states[(unsigned char)(s)->curr] \
181+
& ((TFW_GFSM_FSM_MASK << TFW_GFSM_FSM_SHIFT) \
182+
| TFW_GFSM_STATE_MASK))
184183

185-
typedef int (*tfw_gfsm_handler_t)(void *obj, TfwFsmData *data);
184+
typedef struct TfwConn TfwConn;
185+
typedef int (*tfw_gfsm_handler_t)(TfwConn *conn, TfwFsmData *data);
186186

187187
void tfw_gfsm_state_init(TfwGState *st, void *obj, int st0);
188188
int tfw_gfsm_dispatch(TfwGState *st, void *obj, TfwFsmData *data);

fw/http.c

+14-28
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@
117117
#define RESP_BUF_LEN 128
118118

119119
static DEFINE_PER_CPU(char[RESP_BUF_LEN], g_buf);
120-
int ghprio; /* GFSM hook priority. */
121120

122121
#define TFW_CFG_BLK_DEF (TFW_BLK_ERR_REPLY)
123122
unsigned short tfw_blk_flags = TFW_CFG_BLK_DEF;
@@ -5240,12 +5239,11 @@ tfw_h1_req_process(TfwStream *stream, struct sk_buff *skb)
52405239
* TODO enter the function depending on current GFSM state.
52415240
*/
52425241
static int
5243-
tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
5242+
tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb)
52445243
{
52455244
bool block;
52465245
ss_skb_actor_t *actor;
52475246
unsigned int parsed;
5248-
struct sk_buff *skb = data->skb;
52495247
TfwHttpReq *req;
52505248
TfwHttpMsg *hmsib;
52515249
TfwFsmData data_up;
@@ -5276,7 +5274,7 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
52765274
skb->len, skb->next, parsed, req->msg.len, req->version, r);
52775275

52785276
/*
5279-
* We have to keep @data the same to pass it as is to FSMs
5277+
* We have to keep @skb the same to pass it as is to FSMs
52805278
* registered with lower priorities after us, but we must
52815279
* feed the new data version to FSMs registered on our states.
52825280
*/
@@ -5455,8 +5453,7 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
54555453
* the quickest way to obtain target VHost and target backend server
54565454
* connection since it allows to avoid expensive tables lookups.
54575455
*/
5458-
switch (tfw_http_sess_obtain(req))
5459-
{
5456+
switch (tfw_http_sess_obtain(req)) {
54605457
case TFW_HTTP_SESS_SUCCESS:
54615458
break;
54625459

@@ -5851,11 +5848,10 @@ tfw_http_resp_terminate(TfwHttpMsg *hm)
58515848
* TODO enter the function depending on current GFSM state.
58525849
*/
58535850
static int
5854-
tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
5851+
tfw_http_resp_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb)
58555852
{
58565853
int r = TFW_BLOCK;
58575854
unsigned int chunks_unused, parsed;
5858-
struct sk_buff *skb = data->skb;
58595855
TfwHttpReq *bad_req;
58605856
TfwHttpMsg *hmresp, *hmsib;
58615857
TfwFsmData data_up;
@@ -5890,7 +5886,7 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
58905886
skb->len, parsed, hmresp->msg.len, hmresp->version, r);
58915887

58925888
/*
5893-
* We have to keep @data the same to pass it as is to FSMs
5889+
* We have to keep @skb the same to pass it as is to FSMs
58945890
* registered with lower priorities after us, but we must
58955891
* feed the new data version to FSMs registered on our states.
58965892
*/
@@ -6075,7 +6071,8 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
60756071
* @return status (application logic decision) of the message processing.
60766072
*/
60776073
int
6078-
tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream, TfwFsmData *data)
6074+
tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream,
6075+
TfwFsmData *data)
60796076
{
60806077
if (WARN_ON_ONCE(!stream))
60816078
return -EINVAL;
@@ -6095,8 +6092,8 @@ tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream, TfwFsmData *data)
60956092
ss_skb_queue_tail(&stream->msg->skb_head, data->skb);
60966093

60976094
return (TFW_CONN_TYPE(conn) & Conn_Clnt)
6098-
? tfw_http_req_process(conn, stream, data)
6099-
: tfw_http_resp_process(conn, stream, data);
6095+
? tfw_http_req_process(conn, stream, data->skb)
6096+
: tfw_http_resp_process(conn, stream, data->skb);
61006097
}
61016098

61026099
/**
@@ -6108,7 +6105,7 @@ tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream, TfwFsmData *data)
61086105
* returned an error code on. The rest of skbs are freed by us.
61096106
*/
61106107
int
6111-
tfw_http_msg_process(void *conn, TfwFsmData *data)
6108+
tfw_http_msg_process(TfwConn *conn, TfwFsmData *data)
61126109
{
61136110
int r = T_OK;
61146111
TfwStream *stream = &((TfwConn *)conn)->stream;
@@ -6122,8 +6119,9 @@ tfw_http_msg_process(void *conn, TfwFsmData *data)
61226119
if (likely(r == T_OK || r == T_POSTPONE)) {
61236120
data->skb->next = data->skb->prev = NULL;
61246121
r = TFW_CONN_H2(conn)
6125-
? tfw_h2_frame_process(conn, data)
6126-
: tfw_http_msg_process_generic(conn, stream, data);
6122+
? tfw_h2_frame_process(conn, data->skb)
6123+
: tfw_http_msg_process_generic(conn, stream,
6124+
data);
61276125
} else {
61286126
__kfree_skb(data->skb);
61296127
}
@@ -6884,22 +6882,11 @@ tfw_http_init(void)
68846882
{
68856883
int r;
68866884

6887-
r = tfw_gfsm_register_fsm(TFW_FSM_HTTP, tfw_http_msg_process);
6888-
if (r)
6885+
if ((r = tfw_gfsm_register_fsm(TFW_FSM_HTTP, tfw_http_msg_process)))
68896886
return r;
68906887

68916888
tfw_connection_hooks_register(&http_conn_hooks, TFW_FSM_HTTP);
68926889

6893-
ghprio = tfw_gfsm_register_hook(TFW_FSM_TLS,
6894-
TFW_GFSM_HOOK_PRIORITY_ANY,
6895-
TFW_TLS_FSM_DATA_READY,
6896-
TFW_FSM_HTTP, TFW_HTTP_FSM_INIT);
6897-
if (ghprio < 0) {
6898-
tfw_connection_hooks_unregister(TFW_FSM_HTTP);
6899-
tfw_gfsm_unregister_fsm(TFW_FSM_HTTP);
6900-
return ghprio;
6901-
}
6902-
69036890
tfw_mod_register(&tfw_http_mod);
69046891

69056892
return 0;
@@ -6909,7 +6896,6 @@ void
69096896
tfw_http_exit(void)
69106897
{
69116898
tfw_mod_unregister(&tfw_http_mod);
6912-
tfw_gfsm_unregister_hook(TFW_FSM_TLS, ghprio, TFW_TLS_FSM_DATA_READY);
69136899
tfw_connection_hooks_unregister(TFW_FSM_HTTP);
69146900
tfw_gfsm_unregister_fsm(TFW_FSM_HTTP);
69156901
}

fw/http.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ tfw_h2_pseudo_index(unsigned short status)
668668
typedef void (*tfw_http_cache_cb_t)(TfwHttpMsg *);
669669

670670
/* External HTTP functions. */
671-
int tfw_http_msg_process(void *conn, TfwFsmData *data);
671+
int tfw_http_msg_process(TfwConn *conn, TfwFsmData *data);
672672
int tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream,
673673
TfwFsmData *data);
674674
unsigned long tfw_http_req_key_calc(TfwHttpReq *req);

fw/http_frame.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Tempesta FW
33
*
4-
* Copyright (C) 2019-2021 Tempesta Technologies, Inc.
4+
* Copyright (C) 2019-2022 Tempesta Technologies, Inc.
55
*
66
* This program is free software; you can redistribute it and/or modify it
77
* under the terms of the GNU General Public License as published by
@@ -1698,14 +1698,14 @@ tfw_h2_context_reinit(TfwH2Ctx *ctx, bool postponed)
16981698
}
16991699

17001700
int
1701-
tfw_h2_frame_process(void *c, TfwFsmData *data)
1701+
tfw_h2_frame_process(TfwConn *c, struct sk_buff *skb)
17021702
{
17031703
int r;
17041704
bool postponed;
17051705
unsigned int parsed, unused;
17061706
TfwFsmData data_up = {};
17071707
TfwH2Ctx *h2 = tfw_h2_context(c);
1708-
struct sk_buff *nskb = NULL, *skb = data->skb;
1708+
struct sk_buff *nskb = NULL;
17091709

17101710
next_msg:
17111711
postponed = false;

fw/http_frame.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,13 @@ typedef struct {
200200
unsigned char data_off;
201201
} TfwH2Ctx;
202202

203+
typedef struct TfwConn TfwConn;
204+
203205
int tfw_h2_init(void);
204206
void tfw_h2_cleanup(void);
205207
int tfw_h2_context_init(TfwH2Ctx *ctx);
206208
void tfw_h2_context_clear(TfwH2Ctx *ctx);
207-
int tfw_h2_frame_process(void *c, TfwFsmData *data);
209+
int tfw_h2_frame_process(TfwConn *c, struct sk_buff *skb);
208210
void tfw_h2_conn_streams_cleanup(TfwH2Ctx *ctx);
209211
unsigned int tfw_h2_stream_id(TfwHttpReq *req);
210212
unsigned int tfw_h2_stream_id_close(TfwHttpReq *req, unsigned char type,

fw/http_limits.c

+9-38
Original file line numberDiff line numberDiff line change
@@ -855,13 +855,6 @@ enum {
855855
TFW_FRANG_RESP_FSM_DONE = TFW_GFSM_FRANG_RESP_STATE(TFW_GFSM_STATE_LAST)
856856
};
857857

858-
#define TFW_GFSM_FRANG_TLS_STATE(s) \
859-
((TFW_FSM_FRANG_TLS << TFW_GFSM_FSM_SHIFT) | (s))
860-
enum {
861-
TFW_FRANG_TLS_FSM_INIT = TFW_GFSM_FRANG_TLS_STATE(0),
862-
TFW_FRANG_TLS_FSM_DONE = TFW_GFSM_FRANG_TLS_STATE(TFW_GFSM_STATE_LAST)
863-
};
864-
865858
#define __FRANG_FSM_MOVE(st) T_FSM_MOVE(st, if (r) T_FSM_EXIT(); )
866859

867860
#define __FRANG_FSM_JUMP_EXIT(st) \
@@ -1245,10 +1238,9 @@ frang_http_req_process(FrangAcc *ra, TfwConn *conn, TfwFsmData *data,
12451238
}
12461239

12471240
static int
1248-
frang_http_req_handler(void *obj, TfwFsmData *data)
1241+
frang_http_req_handler(TfwConn *conn, TfwFsmData *data)
12491242
{
12501243
int r;
1251-
TfwConn *conn = (TfwConn *)obj;
12521244
FrangAcc *ra = conn->sk->sk_security;
12531245
TfwVhost *dvh = NULL;
12541246
TfwHttpReq *req = (TfwHttpReq *)data->req;
@@ -1411,10 +1403,9 @@ frang_resp_fwd_process(TfwHttpResp *resp)
14111403
}
14121404

14131405
static int
1414-
frang_resp_handler(void *obj, TfwFsmData *data)
1406+
frang_resp_handler(TfwConn *conn, TfwFsmData *data)
14151407
{
14161408
TfwHttpResp *resp = (TfwHttpResp *)data->resp;
1417-
TfwConn *conn = (TfwConn *)obj;
14181409
int r = TFW_PASS;
14191410

14201411
switch (TFW_GFSM_STATE(&conn->state)) {
@@ -1450,8 +1441,7 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
14501441
ra->history[i].ts = ts;
14511442
}
14521443

1453-
switch (hs_state)
1454-
{
1444+
switch (hs_state) {
14551445
case TTLS_HS_CB_FINISHED_NEW:
14561446
ra->history[i].tls_sess_new++;
14571447
break;
@@ -1472,8 +1462,7 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
14721462
sum_incomplete += ra->history[i].tls_sess_incomplete;
14731463
}
14741464

1475-
switch (hs_state)
1476-
{
1465+
switch (hs_state) {
14771466
case TTLS_HS_CB_FINISHED_NEW:
14781467
if (conf->tls_new_conn_rate
14791468
&& sum_new > conf->tls_new_conn_rate)
@@ -1510,12 +1499,11 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
15101499
return TFW_PASS;
15111500
}
15121501

1513-
static int
1514-
frang_tls_handler(void *obj, TfwFsmData *data)
1502+
int
1503+
frang_tls_handler(TlsCtx *tls, int state)
15151504
{
1516-
TfwCliConn *conn = (TfwCliConn *)obj;
1517-
FrangAcc *ra = conn->sk->sk_security;
1518-
int hs_state = -PTR_ERR(data->req);
1505+
TfwTlsConn *conn = container_of(tls, TfwTlsConn, tls);
1506+
FrangAcc *ra = conn->cli_conn.sk->sk_security;
15191507
TfwVhost *dflt_vh = tfw_vhost_lookup_default();
15201508
int r;
15211509

@@ -1524,7 +1512,7 @@ frang_tls_handler(void *obj, TfwFsmData *data)
15241512

15251513
spin_lock(&ra->lock);
15261514

1527-
r = frang_tls_conn_limit(ra, dflt_vh->frang_gconf, hs_state);
1515+
r = frang_tls_conn_limit(ra, dflt_vh->frang_gconf, state);
15281516
if (r == TFW_BLOCK && dflt_vh->frang_gconf->ip_block)
15291517
tfw_filter_block_ip(&FRANG_ACC2CLI(ra)->addr);
15301518

@@ -1595,14 +1583,6 @@ static FrangGfsmHook frang_gfsm_hooks[] = {
15951583
.st0 = TFW_FRANG_RESP_FSM_FWD,
15961584
.name = "response_fwd",
15971585
},
1598-
{
1599-
.prio = -1,
1600-
.hook_fsm = TFW_FSM_HTTPS,
1601-
.hook_state = TFW_TLS_FSM_HS_DONE,
1602-
.fsm_id = TFW_FSM_FRANG_TLS,
1603-
.st0 = TFW_FRANG_TLS_FSM_INIT,
1604-
.name = "tls_hs_done",
1605-
},
16061586
};
16071587

16081588
void
@@ -1663,21 +1643,13 @@ tfw_http_limits_init(void)
16631643
goto err_fsm_resp;
16641644
}
16651645

1666-
r = tfw_gfsm_register_fsm(TFW_FSM_FRANG_TLS, frang_tls_handler);
1667-
if (r) {
1668-
T_ERR_NL("frang: can't register frang tls fsm\n");
1669-
goto err_fsm_tls;
1670-
}
1671-
16721646
r = tfw_http_limits_hooks_register();
16731647
if (r)
16741648
goto err_hooks;
16751649

16761650
return 0;
16771651
err_hooks:
16781652
tfw_http_limits_hooks_remove();
1679-
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_TLS);
1680-
err_fsm_tls:
16811653
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_RESP);
16821654
err_fsm_resp:
16831655
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_REQ);
@@ -1693,7 +1665,6 @@ tfw_http_limits_exit(void)
16931665
T_DBG("frang exit\n");
16941666

16951667
tfw_http_limits_hooks_remove();
1696-
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_TLS);
16971668
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_RESP);
16981669
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_REQ);
16991670
tfw_classifier_unregister();

0 commit comments

Comments
 (0)