Skip to content

Commit 2eae1da

Browse files
committed
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 (#77) and Tempesta Language (#102).
1 parent 27e65ef commit 2eae1da

13 files changed

+79
-157
lines changed

fw/connection.c

-11
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,6 @@ tfw_connection_send(TfwConn *conn, TfwMsg *msg)
123123
return TFW_CONN_HOOK_CALL(conn, conn_send, msg);
124124
}
125125

126-
int
127-
tfw_connection_recv(void *cdata, struct sk_buff *skb)
128-
{
129-
TfwConn *conn = cdata;
130-
TfwFsmData fsm_data = {
131-
.skb = skb,
132-
};
133-
134-
return tfw_gfsm_dispatch(&conn->state, conn, &fsm_data);
135-
}
136-
137126
void
138127
tfw_connection_hooks_register(TfwConnHooks *hooks, int type)
139128
{

fw/connection.h

-2
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,4 @@ int tfw_connection_close(TfwConn *conn, bool sync);
508508
void tfw_connection_drop(TfwConn *conn);
509509
void tfw_connection_release(TfwConn *conn);
510510

511-
int tfw_connection_recv(void *cdata, struct sk_buff *skb);
512-
513511
#endif /* __TFW_CONNECTION_H__ */

fw/gfsm.h

+1-2
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-2021 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
};

fw/http.c

+24-41
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@
121121
#define RESP_BUF_LEN 128
122122

123123
static DEFINE_PER_CPU(char[RESP_BUF_LEN], g_buf);
124-
int ghprio; /* GFSM hook priority. */
125124

126125
#define TFW_CFG_BLK_DEF (TFW_BLK_ERR_REPLY)
127126
unsigned short tfw_blk_flags = TFW_CFG_BLK_DEF;
@@ -5132,12 +5131,11 @@ tfw_h1_req_process(TfwStream *stream, struct sk_buff *skb)
51325131
* TODO enter the function depending on current GFSM state.
51335132
*/
51345133
static int
5135-
tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
5134+
tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb)
51365135
{
51375136
bool block;
51385137
ss_skb_actor_t *actor;
51395138
unsigned int parsed;
5140-
struct sk_buff *skb = data->skb;
51415139
TfwHttpReq *req;
51425140
TfwHttpMsg *hmsib;
51435141
TfwFsmData data_up;
@@ -5168,7 +5166,7 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
51685166
skb->len, skb->next, parsed, req->msg.len, req->version, r);
51695167

51705168
/*
5171-
* We have to keep @data the same to pass it as is to FSMs
5169+
* We have to keep @skb the same to pass it as is to FSMs
51725170
* registered with lower priorities after us, but we must
51735171
* feed the new data version to FSMs registered on our states.
51745172
*/
@@ -5339,8 +5337,7 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
53395337
* the quickest way to obtain target VHost and target backend server
53405338
* connection since it allows to avoid expensive tables lookups.
53415339
*/
5342-
switch (tfw_http_sess_obtain(req))
5343-
{
5340+
switch (tfw_http_sess_obtain(req)) {
53445341
case TFW_HTTP_SESS_SUCCESS:
53455342
break;
53465343

@@ -5710,11 +5707,10 @@ tfw_http_resp_terminate(TfwHttpMsg *hm)
57105707
* TODO enter the function depending on current GFSM state.
57115708
*/
57125709
static int
5713-
tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
5710+
tfw_http_resp_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb)
57145711
{
57155712
int r = TFW_BLOCK;
57165713
unsigned int chunks_unused, parsed;
5717-
struct sk_buff *skb = data->skb;
57185714
TfwHttpReq *bad_req;
57195715
TfwHttpMsg *hmresp, *hmsib;
57205716
TfwFsmData data_up;
@@ -5749,7 +5745,7 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
57495745
skb->len, parsed, hmresp->msg.len, hmresp->version, r);
57505746

57515747
/*
5752-
* We have to keep @data the same to pass it as is to FSMs
5748+
* We have to keep @skb the same to pass it as is to FSMs
57535749
* registered with lower priorities after us, but we must
57545750
* feed the new data version to FSMs registered on our states.
57555751
*/
@@ -5934,28 +5930,28 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, const TfwFsmData *data)
59345930
* @return status (application logic decision) of the message processing.
59355931
*/
59365932
int
5937-
tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream, TfwFsmData *data)
5933+
tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream,
5934+
struct sk_buff *skb)
59385935
{
59395936
if (WARN_ON_ONCE(!stream))
59405937
return -EINVAL;
59415938
if (unlikely(!stream->msg)) {
59425939
stream->msg = tfw_http_conn_msg_alloc(conn, stream);
59435940
if (!stream->msg) {
5944-
__kfree_skb(data->skb);
5941+
__kfree_skb(skb);
59455942
return TFW_BLOCK;
59465943
}
5947-
tfw_http_mark_wl_new_msg(conn, (TfwHttpMsg *)stream->msg,
5948-
data->skb);
5944+
tfw_http_mark_wl_new_msg(conn, (TfwHttpMsg *)stream->msg, skb);
59495945
T_DBG2("Link new msg %p with connection %p\n",
59505946
stream->msg, conn);
59515947
}
59525948

5953-
T_DBG2("Add skb %p to message %p\n", data->skb, stream->msg);
5954-
ss_skb_queue_tail(&stream->msg->skb_head, data->skb);
5949+
T_DBG2("Add skb %p to message %p\n", skb, stream->msg);
5950+
ss_skb_queue_tail(&stream->msg->skb_head, skb);
59555951

59565952
return (TFW_CONN_TYPE(conn) & Conn_Clnt)
5957-
? tfw_http_req_process(conn, stream, data)
5958-
: tfw_http_resp_process(conn, stream, data);
5953+
? tfw_http_req_process(conn, stream, skb)
5954+
: tfw_http_resp_process(conn, stream, skb);
59595955
}
59605956

59615957
/**
@@ -5967,24 +5963,25 @@ tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream, TfwFsmData *data)
59675963
* returned an error code on. The rest of skbs are freed by us.
59685964
*/
59695965
int
5970-
tfw_http_msg_process(void *conn, TfwFsmData *data)
5966+
tfw_http_msg_process(void *conn, struct sk_buff *skb)
59715967
{
59725968
int r = T_OK;
59735969
TfwStream *stream = &((TfwConn *)conn)->stream;
59745970
struct sk_buff *next;
59755971

5976-
if (data->skb->prev)
5977-
data->skb->prev->next = NULL;
5978-
for (next = data->skb->next; data->skb;
5979-
data->skb = next, next = next ? next->next : NULL)
5972+
if (skb->prev)
5973+
skb->prev->next = NULL;
5974+
for (next = skb->next; skb;
5975+
skb = next, next = next ? next->next : NULL)
59805976
{
59815977
if (likely(r == T_OK || r == T_POSTPONE)) {
5982-
data->skb->next = data->skb->prev = NULL;
5978+
skb->next = skb->prev = NULL;
59835979
r = TFW_CONN_H2(conn)
5984-
? tfw_h2_frame_process(conn, data)
5985-
: tfw_http_msg_process_generic(conn, stream, data);
5980+
? tfw_h2_frame_process(conn, skb)
5981+
: tfw_http_msg_process_generic(conn, stream,
5982+
skb);
59865983
} else {
5987-
__kfree_skb(data->skb);
5984+
__kfree_skb(skb);
59885985
}
59895986
}
59905987

@@ -6737,28 +6734,15 @@ TfwMod tfw_http_mod = {
67376734
* init/exit
67386735
* ------------------------------------------------------------------------
67396736
*/
6740-
67416737
int __init
67426738
tfw_http_init(void)
67436739
{
67446740
int r;
67456741

6746-
r = tfw_gfsm_register_fsm(TFW_FSM_HTTP, tfw_http_msg_process);
6747-
if (r)
6742+
if ((r = tfw_gfsm_register_fsm(TFW_FSM_HTTP, tfw_http_msg_process)))
67486743
return r;
67496744

67506745
tfw_connection_hooks_register(&http_conn_hooks, TFW_FSM_HTTP);
6751-
6752-
ghprio = tfw_gfsm_register_hook(TFW_FSM_TLS,
6753-
TFW_GFSM_HOOK_PRIORITY_ANY,
6754-
TFW_TLS_FSM_DATA_READY,
6755-
TFW_FSM_HTTP, TFW_HTTP_FSM_INIT);
6756-
if (ghprio < 0) {
6757-
tfw_connection_hooks_unregister(TFW_FSM_HTTP);
6758-
tfw_gfsm_unregister_fsm(TFW_FSM_HTTP);
6759-
return ghprio;
6760-
}
6761-
67626746
tfw_mod_register(&tfw_http_mod);
67636747

67646748
return 0;
@@ -6768,7 +6752,6 @@ void
67686752
tfw_http_exit(void)
67696753
{
67706754
tfw_mod_unregister(&tfw_http_mod);
6771-
tfw_gfsm_unregister_hook(TFW_FSM_TLS, ghprio, TFW_TLS_FSM_DATA_READY);
67726755
tfw_connection_hooks_unregister(TFW_FSM_HTTP);
67736756
tfw_gfsm_unregister_fsm(TFW_FSM_HTTP);
67746757
}

fw/http.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ tfw_h2_pseudo_index(unsigned short status)
646646
typedef void (*tfw_http_cache_cb_t)(TfwHttpMsg *);
647647

648648
/* External HTTP functions. */
649-
int tfw_http_msg_process(void *conn, TfwFsmData *data);
649+
int tfw_http_msg_process(TfwConn *conn, TfwFsmData *data);
650650
int tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream,
651651
TfwFsmData *data);
652652
unsigned long tfw_http_req_key_calc(TfwHttpReq *req);

fw/http_frame.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -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_limits.c

+7-33
Original file line numberDiff line numberDiff line change
@@ -856,13 +856,6 @@ enum {
856856
TFW_FRANG_RESP_FSM_DONE = TFW_GFSM_FRANG_RESP_STATE(TFW_GFSM_STATE_LAST)
857857
};
858858

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

868861
#define __FRANG_FSM_JUMP_EXIT(st) \
@@ -1451,8 +1444,7 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
14511444
ra->history[i].ts = ts;
14521445
}
14531446

1454-
switch (hs_state)
1455-
{
1447+
switch (hs_state) {
14561448
case TTLS_HS_CB_FINISHED_NEW:
14571449
ra->history[i].tls_sess_new++;
14581450
break;
@@ -1473,8 +1465,7 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
14731465
sum_incomplete += ra->history[i].tls_sess_incomplete;
14741466
}
14751467

1476-
switch (hs_state)
1477-
{
1468+
switch (hs_state) {
14781469
case TTLS_HS_CB_FINISHED_NEW:
14791470
if (conf->tls_new_conn_rate
14801471
&& sum_new > conf->tls_new_conn_rate)
@@ -1511,12 +1502,11 @@ frang_tls_conn_limit(FrangAcc *ra, FrangGlobCfg *conf, int hs_state)
15111502
return TFW_PASS;
15121503
}
15131504

1514-
static int
1515-
frang_tls_handler(void *obj, TfwFsmData *data)
1505+
int
1506+
frang_tls_handler(TlsCtx *tls, int state)
15161507
{
1517-
TfwCliConn *conn = (TfwCliConn *)obj;
1518-
FrangAcc *ra = conn->sk->sk_security;
1519-
int hs_state = -PTR_ERR(data->req);
1508+
TfwTlsConn *conn = container_of(tls, TfwTlsConn, tls);
1509+
FrangAcc *ra = conn->cli_conn.sk->sk_security;
15201510
TfwVhost *dflt_vh = tfw_vhost_lookup_default();
15211511
int r;
15221512

@@ -1525,7 +1515,7 @@ frang_tls_handler(void *obj, TfwFsmData *data)
15251515

15261516
spin_lock(&ra->lock);
15271517

1528-
r = frang_tls_conn_limit(ra, dflt_vh->frang_gconf, hs_state);
1518+
r = frang_tls_conn_limit(ra, dflt_vh->frang_gconf, state);
15291519
if (r == TFW_BLOCK && dflt_vh->frang_gconf->ip_block)
15301520
tfw_filter_block_ip(&FRANG_ACC2CLI(ra)->addr);
15311521

@@ -1596,14 +1586,6 @@ static FrangGfsmHook frang_gfsm_hooks[] = {
15961586
.st0 = TFW_FRANG_RESP_FSM_FWD,
15971587
.name = "response_fwd",
15981588
},
1599-
{
1600-
.prio = -1,
1601-
.hook_fsm = TFW_FSM_HTTPS,
1602-
.hook_state = TFW_TLS_FSM_HS_DONE,
1603-
.fsm_id = TFW_FSM_FRANG_TLS,
1604-
.st0 = TFW_FRANG_TLS_FSM_INIT,
1605-
.name = "tls_hs_done",
1606-
},
16071589
};
16081590

16091591
void
@@ -1664,20 +1646,13 @@ tfw_http_limits_init(void)
16641646
goto err_fsm_resp;
16651647
}
16661648

1667-
r = tfw_gfsm_register_fsm(TFW_FSM_FRANG_TLS, frang_tls_handler);
1668-
if (r) {
1669-
T_ERR_NL("frang: can't register frang tls fsm\n");
1670-
goto err_fsm_tls;
1671-
}
1672-
16731649
r = tfw_http_limits_hooks_register();
16741650
if (r)
16751651
goto err_hooks;
16761652

16771653
return 0;
16781654
err_hooks:
16791655
tfw_http_limits_hooks_remove();
1680-
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_TLS);
16811656
err_fsm_tls:
16821657
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_RESP);
16831658
err_fsm_resp:
@@ -1694,7 +1669,6 @@ tfw_http_limits_exit(void)
16941669
T_DBG("frang exit\n");
16951670

16961671
tfw_http_limits_hooks_remove();
1697-
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_TLS);
16981672
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_RESP);
16991673
tfw_gfsm_unregister_fsm(TFW_FSM_FRANG_REQ);
17001674
tfw_classifier_unregister();

fw/http_limits.h

+4-1
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-2020 Tempesta Technologies, Inc.
5+
* Copyright (C) 2015-2021 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
@@ -24,6 +24,7 @@
2424
#include <linux/in6.h>
2525
#include <net/sock.h>
2626
#include <net/tcp.h>
27+
#include <net/tls_hs.h>
2728

2829
#include "tempesta_fw.h"
2930
#include "connection.h"
@@ -238,4 +239,6 @@ struct frang_vhost_cfg_t {
238239
bool http_method_override;
239240
};
240241

242+
int frang_tls_handler(TlsCtx *tls, int state);
243+
241244
#endif /* __HTTP_LIMITS__ */

0 commit comments

Comments
 (0)