-
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
Fix invalid stream processing #1887
Fix invalid stream processing #1887
Conversation
5aeebde
to
c7f3e00
Compare
2f51a38
to
1021f5f
Compare
1021f5f
to
6e9c512
Compare
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.
Part related to stream processing looks good.
int | ||
tfw_h2_stream_process(TfwH2Ctx *ctx, TfwStream *stream, unsigned char type) | ||
TfwStreamFsmRes | ||
tfw_h2_stream_process(TfwH2Ctx *ctx, TfwStream *stream, |
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.
Seems tfw_h2_stream_process()
must be called only if stream->xmit.b_len == 0
or stream->xmit.h_len == 0
otherwise it looks dangerous. Now it's ok, but maybe add BUG?
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.
Yes fixed
fw/sock_clnt.c
Outdated
#define H2_PROCESS_STREAM(h2, stream, type) \ | ||
r = tfw_h2_stream_process(h2, stream, type); \ | ||
if (unlikely(r != STREAM_FSM_RES_OK)) { \ | ||
T_WARN("Failed tp process stream %d", (int)r); \ |
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.
tp
typo.
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.
Fixed
fa7df28
to
f62e4c2
Compare
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.
LGTM with minor cleanups
@@ -22,6 +22,7 @@ | |||
#include <asm/fpu/api.h> |
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.
Please update the copyright year
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.
fixed
@@ -409,6 +471,14 @@ static struct ctl_table tfw_sysctl_tbl[] = { | |||
.mode = 0644, | |||
.proc_handler = tfw_ctlfn_state_io, | |||
}, | |||
#ifdef DBG_ERRINJ | |||
{ | |||
.procname = "errinj", |
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 short, there is some runtime API and some C API and we do not have any examples of the usage at the moment. Could you please add an example and a short HowTo to the wiki? Maybe extend https://github.com/tempesta-tech/tempesta/wiki/Debugging-and-troubleshooting or create a new page under Contributing.
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.
Fixed
lib/errinj.c
Outdated
* on top on native Linux socket buffers. The helpers provide common and | ||
* convenient wrappers for skb processing. | ||
* | ||
* Copyright (C) 2015-2023 Tempesta Technologies, Inc. |
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.
Usually for new files we use only current year, so there should be just 2023
. If you see 2015-2023
, then it's quite an old file ;)
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.
Fixed
lib/errinj.c
Outdated
* | ||
* Application protocol handler layers must implement zero data copy logic | ||
* on top on native Linux socket buffers. The helpers provide common and | ||
* convenient wrappers for skb processing. |
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 didn't get the comment - why error injection file comments something about skb? A dirty copy & paste? BTW it'd be good to write some description about the error injection design, maybe some usage example
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.
Fixed
ERRINJ_LIST(ERRINJ_MEMBER) | ||
}; | ||
EXPORT_SYMBOL(errinjs); | ||
|
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.
extra empty line
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.
Fixed
lib/errinj.c
Outdated
|
||
#include "errinj.h" | ||
|
||
#define ERRINJ_MEMBER(n, t, s) { /* .name = */ #n, /* .type = */ t, /* .state = */ s }, |
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.
too long line
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.
Fixed
union { | ||
/** bool parameter */ | ||
bool bparam; | ||
/** integer parameter */ |
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.
Usually we write a single comment on top of a structure describing all the members - it's not good or bad, but it'd be good to adjust for code consistency
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.
Fixed
lib/errinj.h
Outdated
# define ERROR_INJECT(ID, CODE) \ | ||
do { \ | ||
if (errinj_get(ID, ERRINJ_BOOL)->bparam) \ | ||
CODE; \ |
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.
Let's place all \
aligned as for ERROR_INJECT_COUNTDOWN
and around the code
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.
Fixed
6bb718c
to
f2ebd63
Compare
e2b9ec1
to
d097b03
Compare
f20dc6e
to
1f866aa
Compare
Implement error injection to test difficult cases, which can't be simulated by usual python tests.
We should split stream processing into two parts: in first part we pass `HTTP2_HEADERS` type and `HTTP2_F_END_HEADERS` flag to `STREAM_SEND_PROCESS` and later in `xmit` callback we should pass `HTTP2_F_END_STREAM` flag and appropriate type when we finish send all data for corresponding stream. Also rename `tfw_h2_stream_id_unlink` to `tfw_h2_stream_unlink_from_req`
1f866aa
to
09891fb
Compare
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.
LGTM
fw/http_frame.c
Outdated
|| (max_streams == ctx->streams_num | ||
&& closed_streams->num)) |
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.
IIUC this condition need to not delete streams if we have maximum streams and some streams in closed queue. These streams will be deleted on closing connection. Is there any reason to remove it?
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.
Yes, fixed during discussion. Add comment to #1346 to don't forget to change this condition later
fw/http_frame.h
Outdated
@@ -228,6 +228,7 @@ int tfw_h2_context_init(TfwH2Ctx *ctx); | |||
void tfw_h2_context_clear(TfwH2Ctx *ctx); | |||
int tfw_h2_frame_process(TfwConn *c, struct sk_buff *skb); | |||
void tfw_h2_conn_streams_cleanup(TfwH2Ctx *ctx); | |||
TfwStream *tfw_h2_find_stream_if_not_closed(TfwH2Ctx *ctx, unsigned int id); |
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.
It's not mandatory, but I suggest to renaming tfw_h2_find_stream_if_not_closed
to tfw_h2_find_stream_not_closed
or to tfw_h2_find_not_closed_stream
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.
yes, fixed
Tempesta uses delayed streams deletion (closed streams add to special queue and remove later, when there count become greater than appropriate constant). We should not work with such streams except cases, when we process HTTP2_PRIORITY, HTTP2_WINDOW_UPDATE or HTTP2_RST_STREAM frames (according to RFC 9113), for this cases we should ignore such frames. Also remove strange condition from function `tfw_h2_closed_streams_shrink` (we can't delete streams from closed queue if there count in this queue is equal to zero). Closes #1800
09891fb
to
a88e643
Compare
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've only reviewed part related to tfw_h2_stream_id_verify
, and it looks similar to what I did in #1913.
We should split stream processing into two
parts: in first part we pass
HTTP2_HEADERS
type and
HTTP2_F_END_HEADERS
flag toSTREAM_SEND_PROCESS
and later inxmit
callback we should pass
HTTP2_F_END_STREAM
flag and appropriate type when we finish
send all data to corrsponding stream.