Skip to content

Commit

Permalink
Merge pull request #1233 from tempesta-tech/ao-309-framing
Browse files Browse the repository at this point in the history
HTTP/2 Framing layer implementation (#309).
  • Loading branch information
aleksostapenko authored May 16, 2019
2 parents 0dc931b + dc1f523 commit aee18fe
Show file tree
Hide file tree
Showing 17 changed files with 2,527 additions and 106 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ DBG_HTTP_PARSER ?= 0
DBG_SS ?= 0
DBG_TLS ?= 0
DBG_APM ?= 0
DBG_HTTP_FRAME ?= 0
DBG_HTTP_STREAM ?= 0
TFW_CFLAGS += -DDBG_CFG=$(DBG_CFG) -DDBG_HTTP_PARSER=$(DBG_HTTP_PARSER)
TFW_CFLAGS += -DDBG_SS=$(DBG_SS) -DDBG_TLS=$(DBG_TLS) -DDBG_APM=$(DBG_APM)
TFW_CFLAGS += -DDBG_HTTP_FRAME=$(DBG_HTTP_FRAME)
TFW_CFLAGS += -DDBG_HTTP_STREAM=$(DBG_HTTP_STREAM)

PROC = $(shell cat /proc/cpuinfo)
ARCH = $(shell uname -m)
Expand Down
15 changes: 11 additions & 4 deletions etc/tempesta_fw.conf
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@
# Tempesta FW listening address.
#
# Syntax:
# listen PORT | IPADDR[:PORT] [proto=http|https]
# listen PORT | IPADDR[:PORT] [proto=http|https[:h2|http/1.1]]
#
# IPADDR may be either an IPv4 or IPv6 address, no host names allowed.
# IPv6 address must be enclosed in square brackets (e.g. "[::0]" but not "::0").
Expand All @@ -427,13 +427,20 @@
# If only IPADDR is given, then the default HTTP port 80 is used.
#
# It is allowed to specify the type of listening socket via the 'proto'. At
# the moment HTTP and HTTPS protos are supported. If no 'proto' option was
# given, then HTTP is supposed by the default.
# the moment HTTP and HTTPS protos are supported. For HTTPS proto (TLS actually)
# it is allowed the application level protocol (in context of ALPN extension of
# TLS) to be specified: HTTP/2 or HTTP/1.1 with RFC compliant names 'h2' and
# 'http/1.1' respectively. It is also possible to specify both protocols
# separated by comma; in this case, the protocols' order is significant for
# TLS ALPN: first specified protocol takes precedence over the last one in
# negotiation procedure. If no application level protocol is given, then
# HTTP/1.1 is default. If the entire 'proto' option is absent, then plain
# HTTP protocol (over TCP) is supposed by the default.
#
# Tempesta FW opens one socket for each 'listen' entry, so it may be repeated
# to listen on multiple addresses/ports. For example:
# listen 80;
# listen 443 proto=https;
# listen 443 proto=https:h2,http/1.1;
# listen [::0]:80;
# listen 127.0.0.1:8001;
# listen [::1]:8001;
Expand Down
14 changes: 13 additions & 1 deletion tempesta_fw/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "peer.h"
#include "http_parser.h"
#include "sync_socket.h"
#include "http_frame.h"
#include "tls.h"

/*
Expand Down Expand Up @@ -108,6 +109,7 @@ typedef struct {

#define TFW_CONN_TYPE(c) ((c)->proto.type)
#define TFW_CONN_PROTO(c) TFW_CONN_TYPE2IDX(TFW_CONN_TYPE(c))
#define TFW_CONN_TLS(c) (TFW_CONN_TYPE(c) & TFW_FSM_HTTPS)

/*
* Queues in client and server connections provide support for correct
Expand Down Expand Up @@ -209,7 +211,17 @@ typedef struct {
TlsCtx tls;
} TfwTlsConn;

#define tfw_tls_context(conn) (TlsCtx *)(&((TfwTlsConn *)conn)->tls)
#define tfw_tls_context(conn) ((TlsCtx *)(&((TfwTlsConn *)conn)->tls))

/**
* HTTP/2 connection.
*/
typedef struct {
TfwTlsConn tls_conn;
TfwH2Ctx h2;
} TfwH2Conn;

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

/* Callbacks used by l5-l7 protocols to operate on connection level. */
typedef struct {
Expand Down
9 changes: 6 additions & 3 deletions tempesta_fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "http_limits.h"
#include "http_tbl.h"
#include "http_parser.h"
#include "http_frame.h"
#include "client.h"
#include "http_msg.h"
#include "http_sess.h"
Expand Down Expand Up @@ -3884,8 +3885,8 @@ tfw_http_resp_process(TfwConn *conn, const TfwFsmData *data)
/**
* @return status (application logic decision) of the message processing.
*/
static int
__tfw_http_msg_process(void *conn, TfwFsmData *data)
int
tfw_http_msg_process_generic(void *conn, TfwFsmData *data)
{
TfwConn *c = (TfwConn *)conn;

Expand Down Expand Up @@ -3930,7 +3931,9 @@ tfw_http_msg_process(void *conn, TfwFsmData *data)
if (likely(r == T_OK || r == T_POSTPONE)) {
data->skb->next = data->skb->prev = NULL;
data->trail = !next ? trail : 0;
r = __tfw_http_msg_process(conn, data);
r = TFW_CONN_TLS((TfwConn *)conn) && TFW_CONN_H2(conn)
? tfw_h2_frame_process(conn, data)
: tfw_http_msg_process_generic(conn, data);
} else {
kfree(data->skb);
}
Expand Down
1 change: 1 addition & 0 deletions tempesta_fw/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ typedef void (*tfw_http_cache_cb_t)(TfwHttpMsg *);

/* External HTTP functions. */
int tfw_http_msg_process(void *conn, TfwFsmData *data);
int tfw_http_msg_process_generic(void *conn, TfwFsmData *data);
unsigned long tfw_http_req_key_calc(TfwHttpReq *req);
void tfw_http_req_destruct(void *msg);
void tfw_http_resp_fwd(TfwHttpResp *resp);
Expand Down
Loading

0 comments on commit aee18fe

Please sign in to comment.