-
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 4 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 |
---|---|---|
|
@@ -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.
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).
In the same time HTTP2 connections will have two contexts in the same time: HTTP2 and HTTP1. HTTP1 context is stored as
TfwConn->TfwHttpParser
. Probably we should introduce a union inTfwConn
class to store 'protocol context' whatever http2 or http1. Seems like we never want both. Even is the HTTP1 connection is upgraded to HTTP2 we can easily re-init the field.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.
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
Stream Priority/Dependencies
). These changes is part of future PRs in context of #309 ("Request HTTP/2 -> HTTP/1.1"
or more soon"Disable @seq_queue for HTTP/2"
). During implementation of Framing, Scheduler and Stream States - I temporary left that part as is - for testing/debugging purposes.