Skip to content

Commit

Permalink
Merge pull request #1643 from tempesta-tech/ak-h2-vs-https
Browse files Browse the repository at this point in the history
HTTP/2 vs HTTPS handling
  • Loading branch information
krizhanovsky authored Sep 6, 2022
2 parents 1414cf5 + 96ba4f5 commit b547241
Show file tree
Hide file tree
Showing 40 changed files with 651 additions and 2,171 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ Module.symvers
*~
\#*\#
.\#*
*.orig
.*.swp

# ctags and cscope
cscope.*
tags

# eclipse project settings
.pydevproject
Expand Down
4 changes: 2 additions & 2 deletions fw/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Tempesta FW
*
* Copyright (C) 2014 NatSys Lab. (info@natsys-lab.com).
* Copyright (C) 2015-2018 Tempesta Technologies, Inc.
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -43,7 +43,7 @@ int tfw_client_for_each(int (*fn)(void *));
void tfw_client_set_expires_time(unsigned int expires_time);
void tfw_cli_conn_release(TfwCliConn *cli_conn);
int tfw_cli_conn_send(TfwCliConn *cli_conn, TfwMsg *msg);
int tfw_cli_conn_close_all_sync(TfwClient *cli);
void tfw_cli_abort_all(void);

void tfw_tls_connection_lost(TfwConn *conn);

Expand Down
20 changes: 6 additions & 14 deletions fw/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,13 @@ tfw_connection_repair(TfwConn *conn)
int
tfw_connection_close(TfwConn *conn, bool sync)
{
int r;

/*
* This function might be called from process context on Tempesta FW
* start or stop operation or from softirq, so need to save FPU context
* to call autovectorized synchronous sockets code.
*/
kernel_fpu_begin_mask(KFPU_MXCSR);

r = TFW_CONN_HOOK_CALL(conn, conn_close, sync);

kernel_fpu_end();
return TFW_CONN_HOOK_CALL(conn, conn_close, sync);
}

return r;
void
tfw_connection_abort(TfwConn *conn)
{
TFW_CONN_HOOK_CALL(conn, conn_abort);
}

/**
Expand All @@ -93,7 +86,6 @@ tfw_connection_drop(TfwConn *conn)
{
/* Ask higher levels to free resources at connection close. */
TFW_CONN_HOOK_CALL(conn, conn_drop);
BUG_ON(conn->stream.msg);
}

/*
Expand Down
44 changes: 39 additions & 5 deletions fw/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ enum {
Conn_HttpsClnt = Conn_Clnt | TFW_FSM_HTTPS,
Conn_HttpsSrv = Conn_Srv | TFW_FSM_HTTPS,

/* HTTP/2 */
Conn_H2Clnt = Conn_Clnt | TFW_FSM_H2,
Conn_H2Srv = Conn_Srv | TFW_FSM_H2,

/* Websocket plain */
Conn_WsClnt = Conn_HttpClnt | TFW_FSM_WEBSOCKET,
Conn_WsSrv = Conn_HttpSrv | TFW_FSM_WEBSOCKET,
Expand Down Expand Up @@ -235,11 +239,6 @@ typedef struct {

#define tfw_h2_context(conn) ((TfwH2Ctx *)(&((TfwH2Conn *)conn)->h2))

#define TFW_CONN_H2(c) \
(TFW_CONN_TLS((TfwConn *)c) \
&& tfw_tls_context(c)->alpn_chosen \
&& tfw_tls_context(c)->alpn_chosen->id == TTLS_ALPN_ID_HTTP2)

/* Callbacks used by l5-l7 protocols to operate on connection level. */
typedef struct {
/*
Expand All @@ -263,6 +262,13 @@ typedef struct {
*/
int (*conn_close)(TfwConn *conn, bool sync);

/*
* Called to abort a connection intentionally on Tempesta side.
* This is rough connection closing without any notifications like TLS
* alerts, probably with TCP RST or just silent connection termination.
*/
void (*conn_abort)(TfwConn *conn);

/*
* Called when closing a connection (client or server,
* as in conn_init()). This is required for modules that
Expand Down Expand Up @@ -518,6 +524,33 @@ tfw_connection_validate_cleanup(TfwConn *conn)
BUG_ON(rc && rc != TFW_CONN_DEATHCNT);
}

static inline int
tfw_peer_for_each_conn(TfwPeer *p, int (*cb)(TfwConn *))
{
int r = 0;
TfwConn *conn, *tmp_conn;

spin_lock_bh(&p->conn_lock);

/*
* @cb() may delete connections from the list.
* Typically, this happens on connection_drop callbacks on sockets closing.
* However, note that client and server connections drops are logically
* different: client connections are just freed with all linked resources,
* while the high level server connection handlers are preserved for
* connection repair and freed on shutdown only.
*/
list_for_each_entry_safe(conn, tmp_conn, &p->conn_list, list) {
r = cb(conn);
if (unlikely(r))
break;
}

spin_unlock_bh(&(p)->conn_lock);

return r;
}

void tfw_connection_hooks_register(TfwConnHooks *hooks, int type);
void tfw_connection_hooks_unregister(int type);
int tfw_connection_send(TfwConn *conn, TfwMsg *msg);
Expand All @@ -530,6 +563,7 @@ void tfw_connection_link_peer(TfwConn *conn, TfwPeer *peer);
int tfw_connection_new(TfwConn *conn);
void tfw_connection_repair(TfwConn *conn);
int tfw_connection_close(TfwConn *conn, bool sync);
void tfw_connection_abort(TfwConn *conn);
void tfw_connection_drop(TfwConn *conn);
void tfw_connection_release(TfwConn *conn);

Expand Down
24 changes: 2 additions & 22 deletions fw/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ static unsigned int
tfw_ipv4_nf_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
{
int r;
const struct iphdr *ih;
struct in6_addr addr6;

Expand All @@ -161,16 +160,7 @@ tfw_ipv4_nf_hook(void *priv, struct sk_buff *skb,
if (tfw_filter_check_ip(&addr6) == TFW_BLOCK)
return NF_DROP;

/* Check classifiers for Layer 3. */
r = tfw_classify_ipv4(skb);
switch (r) {
case TFW_PASS:
return NF_ACCEPT;
case TFW_POSTPONE:
return NF_STOLEN;
}

return NF_DROP;
return NF_ACCEPT;
}

static u8 *
Expand Down Expand Up @@ -233,7 +223,6 @@ static unsigned int
tfw_ipv6_nf_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
{
int r;
struct ipv6hdr *ih;

ih = __ipv6_hdr_check(skb);
Expand All @@ -243,16 +232,7 @@ tfw_ipv6_nf_hook(void *priv, struct sk_buff *skb,
if (tfw_filter_check_ip(&ih->saddr) == TFW_BLOCK)
return NF_DROP;

/* Check classifiers for Layer 3. */
r = tfw_classify_ipv6(skb);
switch (r) {
case TFW_PASS:
return NF_ACCEPT;
case TFW_POSTPONE:
return NF_STOLEN;
}

return NF_DROP;
return NF_ACCEPT;
}

static struct nf_hook_ops tfw_nf_ops[] __read_mostly = {
Expand Down
18 changes: 15 additions & 3 deletions fw/gfsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,25 @@
* build real stack. This simplifies the protocols handling, makes it faster
* and provides more flexibility to set classification FSMs' hooks for
* specific secured application protocol.
*
* The constants are used in the less significant byte for connection or socket
* type, see also enums in connection.h and sync_socket.h.
*
* TODO #77: probably we should get rid of the FRANG states, call the http
* limiting callbacks directly and make the enum purely for the protocol
* type. Then the enum in connection.h determines server/client connection
* and from sync_socket.h the state of the connection. Now this enum looks
* inconsistent.
*/
enum {
/* Protocols */
TFW_FSM_HTTP,
TFW_FSM_HTTPS,
TFW_FSM_HTTP = 0,
TFW_FSM_HTTPS = 1,
/* h2c isn't supported, so HTTP/2 is always HTTPS */
TFW_FSM_H2 = 2 | TFW_FSM_HTTPS,

/* Not really a FSM, used for connection hook registration only */
TFW_FSM_WEBSOCKET,
TFW_FSM_WEBSOCKET = 4,
TFW_FSM_WS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTP,
TFW_FSM_WSS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTPS,

Expand Down
5 changes: 2 additions & 3 deletions fw/hpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,6 @@ do { \
WARN_ON_ONCE(hp->length); \
} while (0)

static unsigned long act_hp_str_n;

void
write_int(unsigned long index, unsigned short max, unsigned short mask,
TfwHPackInt *__restrict res_idx)
Expand Down Expand Up @@ -1093,8 +1091,10 @@ tfw_hpack_init(TfwHPack *__restrict hp, unsigned int htbl_sz)

err_et:
tfw_pool_destroy(dt->h_pool);
dt->h_pool = NULL;
err_dt:
tfw_pool_destroy(dt->pool);
dt->pool = NULL;

return -ENOMEM;
}
Expand All @@ -1105,7 +1105,6 @@ tfw_hpack_clean(TfwHPack *__restrict hp)
tfw_pool_destroy(hp->enc_tbl.pool);
tfw_pool_destroy(hp->dec_tbl.h_pool);
tfw_pool_destroy(hp->dec_tbl.pool);
WARN_ON_ONCE(act_hp_str_n);
}

/*
Expand Down
16 changes: 9 additions & 7 deletions fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -2538,7 +2538,7 @@ tfw_http_conn_msg_alloc(TfwConn *conn, TfwStream *stream)
else
tfw_http_init_parser_resp((TfwHttpResp *)hm);

if (TFW_CONN_H2(conn)) {
if (TFW_FSM_TYPE(conn->proto.type) == TFW_FSM_H2) {
TfwHttpReq *req = (TfwHttpReq *)hm;

if(!(req->pit.pool = __tfw_pool_new(0)))
Expand Down Expand Up @@ -2739,7 +2739,7 @@ static void tfw_http_resp_terminate(TfwHttpMsg *hm);
static void
tfw_http_conn_drop(TfwConn *conn)
{
bool h2_mode = TFW_CONN_H2(conn);
bool h2_mode = TFW_FSM_TYPE(conn->proto.type) == TFW_FSM_H2;

T_DBG2("%s: conn=[%p]\n", __func__, conn);

Expand Down Expand Up @@ -6545,14 +6545,16 @@ tfw_http_msg_process_generic(TfwConn *conn, TfwStream *stream,
int
tfw_http_msg_process(TfwConn *conn, struct sk_buff *skb)
{
int r;
TfwStream *stream = &((TfwConn *)conn)->stream;

r = TFW_CONN_H2(conn)
? tfw_h2_frame_process(conn, skb)
: tfw_http_msg_process_generic(conn, stream, skb);
WARN_ON_ONCE(TFW_CONN_TLS(conn) && tfw_tls_context(conn)->alpn_chosen
&& tfw_tls_context(conn)->alpn_chosen->id
== TTLS_ALPN_ID_HTTP2
&& TFW_FSM_TYPE(conn->proto.type) != TFW_FSM_H2);

return r;
if (TFW_FSM_TYPE(conn->proto.type) == TFW_FSM_H2)
return tfw_h2_frame_process(conn, skb);
return tfw_http_msg_process_generic(conn, stream, skb);
}

/**
Expand Down
Loading

0 comments on commit b547241

Please sign in to comment.