-
Notifications
You must be signed in to change notification settings - Fork 73
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
simplify the method of stream forward in dispatch_stream
#206
base: master
Are you sure you want to change the base?
Conversation
clash_lib/src/common/io.rs
Outdated
match res { | ||
Poll::Ready(Ok(count)) => { | ||
*a_to_b = TransferState::ShuttingDown(count); | ||
match tokio::time::timeout(a_to_b_timeout_duration, a_reader.read(&mut buf[..])).await { |
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.
have you tested this?
does this not break the long running connections ?
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.
As exposed by the signature copy_buf_bidirectional_with_timeout
, which is specified by timeout
, and this function is only called in dispatch_stream
in https://github.com/Watfaq/clash-rs/blob/master/clash_lib/src/app/dispatcher/dispatcher.rs#L138, which specifies the Duration::from_secs(10)
, so this is not for long-running connection. The current implementation does work for me.
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 think you are confused with the timeout. it's mean to be the connection idle timeout.
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.
can you test if your change can successfully request https://httpbin.yba.dev/drip\?duration\=11
?
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 am not confused by timeout
, tokio::time::timeout does mean the read should read data within the specified time duration. In other words, if the read future is idle over a specified time, the read future is cancelled.
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.
add a numbytes param to the url you'll see more *s https://httpbin.yba.dev/drip\?duration\=20\&numbytes\=20
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.
ok i finished the other stuff. now i'm getting back to this.
as you mentioned in the link, this timeout needs to be the duration during which no traffic is sent, not the entire time it takes to finish the connection.
think about you need to download a large file, it take 2hrs, but in the 2hrs, there's always data being transfered, you can't just give it a 10s timeout or whatever.
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.
think about you need to download a large file, it take 2hrs, but in the 2hrs, there's always data being transfered, you can't just give it a 10s timeout or whatever.
Consider this case, the peer sends a byte every 1hrs or 12hrs, is this permitted? In this implementation, the timeout just regulates that the peer must send some traffic within every specified time. In other words, if the peer occupies the connection and does not send some traffic within the specified time, the connection will be closed. Every send traffic within the specified time will make the timeout reset(i.e. recalculate the time)
I think the meaning of the timeout is to prevent "Slow HTTP Attack"/"Slowloris". If I didn't understand correctly, please tell me what the necessary logic here, and I will try to implement it in this PR.
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.
After reviewing the original implementation carefully, the timeout logic is, that only if one direction is complete, it will set the timeout for the other direction. In other words, if two directions are both pending(i.e. no traffic can be accepted), there is no timeout imposed on them. Is this really what we want here?
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.
To clarify what the #1
implementation does in the PR, I need to say the implementation cannot close a long-running traffic.
think about you need to download a large file, it take 2hrs, but in the 2hrs, there's always data being transfered, you can't just give it a 10s timeout or whatever.
The specified timeout 10
does not mean the whole data communication must be completed within 10s
, it's a misunderstanding of the implementation. The #1
implementation means when we do read
in each loop, some data traffic must be read within 10s
, and in the next loop, the timeout is re-calculated for the next read.
Consider this scenario, after A
and B
have been connected, B
writes some bytes to A
but is not end, then B
does not send any traffic to A
within 2hrs, and after 2hrs, B
then continues to send data to A
. Isn't the duration of the 2hrs considered an idle connection?
@ibigbug I have |
what are you exactly trying to do in your patch? could you add a description, what's the issue and why your change is useful? |
I'm trying to implement the original logic concisely and effectively. The original logic is a hand-write state machine, which mixes the In this patch, I divorce |
have you checked the tokio implementation? https://docs.rs/tokio/latest/src/tokio/io/util/copy_bidirectional.rs.html#72-91 does it have the same issue that you are mentioning here? i think i still don't understand how your change is different, i see that you are creating to tokio spawns and awaiting them in sequence, what's the difference of ready! two futures? isn't it the same thing. |
When a future is wakened, the other future will be polled again even though it is not notified by its In this patch, the implementation can make sure that they are wakened again by their |
this may not be a problem. |
i think this is not a big issue https://rust-lang.github.io/async-book/02_execution/02_future.html it's how Rust tell people to run 2 futures (the Join example) |
I think the main goal of this patch is the following:
|
No description provided.