-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTTP/2 Framing layer implementation (#309). #1233
Changes from 12 commits
3d77573
10be35a
7139f53
26cc780
fe57412
ed79830
f6e8edc
79fcd17
05bd194
23d53db
5b93ee8
1e8be28
1d962dd
b22c1f7
5515e82
ad183a6
dc1f523
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,6 +110,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 | ||
|
@@ -209,9 +210,11 @@ enum { | |
typedef struct { | ||
TfwCliConn cli_conn; | ||
TlsCtx tls; | ||
TfwHttp2Ctx *h2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The structure name becomes misleading, now it's more than TLS connection, it also stores the HTTP2 context. And a new issue is introduced: HTTP2 context is not allocated for non-TLS HTTP2 connections (which are allowed by standard). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In result of discussion in #309 and in chat - it has been decided not to support non-TLS HTTP/2 in TempestaFW.
Yes, agree with that. The similar approach is proposed in #309 (comment) (in |
||
} TfwTlsConn; | ||
|
||
#define tfw_tls_context(conn) (TlsCtx *)(&((TfwTlsConn *)conn)->tls) | ||
#define tfw_http2_context(conn) ((TfwHttp2Ctx *)((TfwTlsConn *)conn)->h2) | ||
|
||
/* Callbacks used by l5-l7 protocols to operate on connection level. */ | ||
typedef struct { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bad naming. It's not generic. It's HTTP1 processing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the nearest future PRs (in context of #309) this function is planned for usage for HTTP/2 processing too, so I have run a little forward here. In my opinion, most part of |
||
{ | ||
TfwConn *c = (TfwConn *)conn; | ||
|
||
|
@@ -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_http2_context(conn) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has been decided not to support non-TLS HTTP/2 in TempestaFW: standard allows HTTP/2 over plain TCP, but does not force to use it. |
||
? tfw_http2_frame_process(conn, data) | ||
: tfw_http_msg_process_generic(conn, data); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In #309 we discussed that we should split HTTP parser in at least 2 pieces: headers and body and both the parsers will be called separately from H2 layer. How do you see the split in current code? Check H2 state in Frankly, now we have single-jump cost in our parser to enter any state and I believe we're able to make GCC, probably with some assembly help, to generate proper FSM code layout to make the large parser code faster (after all, even after the parser split, we'll have complex FSM due to many checks), so probably we'll be fine with current code if it simpler than possible split parser. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah - this must be a frame type and, maybe, a stream state (since we have to track request's start/end, and this exactly matches with stream's states, as mentioned in penultimate paragraph in https://tools.ietf.org/html/rfc7540#section-8.1). Сurrently I'm not very optimistic about parser division into separate parts: indeed, we have rather effective implementation with single-jump cost to enter any state; and with divided parser we will get costs of additional function calls (if not inlined) and necessity for additional branching to call separate parser parts (with associated costs). But in general, I am still thinking about this point. |
||
} else { | ||
kfree(data->skb); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I bet there will be families of debug functions for HTTP2: for frames, HPACK, and what ever else. The whole group will have the same meaning to HTTP2 as
DBG_HTTP_PARSER
for HTTP1.1. Should we rename it asDBG_HTTP2_FRAME
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now I cannot do such separation: these sets do not intersect yet; also both HTTP/1.1 and HTTP/2 protocols belong to the same HTTP domain, so there is no contradiction here. But in the nearest future (e.g. during HTTP parser implementation changing in context of HTTP/2 processing) mentioned intersections may appear, and in this case the separation for
HTTP1_*
andHTTP2_*
may be really needed and will be made for preprocessor variables (and possibly for filenames too, e.g.http_frame.c/h
,http_stream.c/h
).