Skip to content

Commit

Permalink
Sync upstream (#14)
Browse files Browse the repository at this point in the history
* fix: streams awaiting capacity lockout (#730) (#734)

This PR changes the the assign-capacity queue to prioritize streams that
are send-ready.

This is necessary to prevent a lockout when streams aren't able to proceed while
waiting for connection capacity, but there is none.

Closes hyperium/hyper#3338

Co-authored-by: dswij <dharmasw@outlook.com>

* v0.3.23

* streams: limit error resets for misbehaving connections

This change causes GOAWAYs to be issued to misbehaving connections which for one reason or another cause us to emit lots of error resets.

Error resets are not generally expected from valid implementations anyways.

The threshold after which we issue GOAWAYs is tunable, and will default to 1024.

* Prepare v0.3.24

* perf: optimize header list size calculations (#750)

This speeds up loading blocks in cases where we have many headers already.

* v0.3.25

* refactor: cleanup new unused warnings (#757)

* fix: limit number of CONTINUATION frames allowed

Calculate the amount of allowed CONTINUATION frames based on other
settings.

    max_header_list_size / max_frame_size

That is about how many CONTINUATION frames would be needed to send
headers up to the max allowed size. We then multiply by that by a small
amount, to allow for implementations that don't perfectly pack into the
minimum frames *needed*.

In practice, *much* more than that would be a very inefficient peer, or
a peer trying to waste resources.

See https://seanmonstar.com/blog/hyper-http2-continuation-flood/ for
more info.

* v0.3.26

* fix: return a WriteZero error if frames cannot be written (#783)

Some operating systems will allow you continually call `write()` on a closed socket, and will return `Ok(0)` instead of an error. This patch checks for a zero write, and instead of looping forever trying to write, returns a proper error.

Closes #781

Co-authored-by: leibeiyi <leibeiyi@coocaa.com>

* lints: fix unexpected cfgs warnings

* ci: pin deps for MSRV

* ci: pin more deps for MSRV job (#817)

* fix: notify_recv after send_reset() in reset_on_recv_stream_err() to ensure local stream is released properly (#816)

Similar to what have been done in fn send_reset<B>(), we should notify RecvStream that is parked after send_reset().

Co-authored-by: Jiahao Liang <gzliangjiahao@gmail.com>

---------

Co-authored-by: Sean McArthur <sean@seanmonstar.com>
Co-authored-by: dswij <dharmasw@outlook.com>
Co-authored-by: Noah Kennedy <nkennedy@cloudflare.com>
Co-authored-by: beiyi lei <niceskylei@gmail.com>
Co-authored-by: leibeiyi <leibeiyi@coocaa.com>
Co-authored-by: Jiahao Liang <gzliangjiahao@gmail.com>
  • Loading branch information
7 people authored Nov 15, 2024
1 parent 6d8f48c commit d1e3f57
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 29 deletions.
45 changes: 43 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,44 @@ jobs:

- run: cargo fmt --all --check

test:
name: Test
needs: [style]
runs-on: ubuntu-latest
env:
RUSTFLAGS: -Dwarnings
strategy:
matrix:
rust:
- beta
- stable
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust (${{ matrix.rust }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}

- name: Install libssl-dev
run: sudo apt-get update && sudo apt-get install libssl-dev
- name: Build without unstable flag
run: cargo build

- name: Check with unstable flag
run: cargo check --features unstable

- name: Run lib tests and doc tests
run: cargo test

- name: Run integration tests
run: cargo test -p h2-tests

- name: Run h2spec
run: ./ci/h2spec.sh
if: matrix.rust == 'stable'

#clippy_check:
# runs-on: ubuntu-latest
# steps:
Expand Down Expand Up @@ -49,9 +87,12 @@ jobs:
with:
toolchain: ${{ steps.msrv.outputs.version }}

- name: Make sure tokio 1.38.1 is used for MSRV
- name: Pin some dependencies for MSRV
run: |
cargo update
cargo update --package tokio --precise 1.38.1
cargo update --package tokio-util --precise 0.7.11
cargo update --package hashbrown --precise 0.15.0
- run: cargo check -p h2

- run: cargo check -p rh2
27 changes: 3 additions & 24 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
# 0.4.5 (May 17, 2024)

* Fix race condition that sometimes hung connections during shutdown.
* Fix pseudo header construction for CONNECT and OPTIONS requests.

# 0.4.4 (April 3, 2024)
# 0.3.26 (April 3, 2024)

* Limit number of CONTINUATION frames for misbehaving connections.

# 0.4.3 (March 15, 2024)

* Fix flow control limits to not apply until receiving SETTINGS ack.
* Fix not returning an error if IO ended without `close_notify`.
* Improve performance of decoding many headers.

# 0.4.2 (January 17th, 2024)

* Limit error resets for misbehaving connections.
* Fix selecting MAX_CONCURRENT_STREAMS value if no value is advertised initially.

# 0.4.1 (January 8, 2024)

* Fix assigning connection capacity which could starve streams in some instances.

# 0.4.0 (November 15, 2023)
# 0.3.25 (March 15, 2024)

* Update to `http` 1.0.
* Remove deprecated `Server::poll_close()`.
* Improve performance decoding many headers.

# 0.3.24 (January 17, 2024)

Expand Down
8 changes: 7 additions & 1 deletion src/codec/framed_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ where

loop {
while !self.encoder.is_empty() {
match self.encoder.next {
let n = match self.encoder.next {
Some(Next::Data(ref mut frame)) => {
tracing::trace!(queued_data_frame = true);
let mut buf = (&mut self.encoder.buf).chain(frame.payload_mut());
Expand All @@ -148,6 +148,12 @@ where
))?
}
};
if n == 0 {
return Poll::Ready(Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write frame to socket",
)));
}
}

match self.encoder.unset_frame() {
Expand Down
2 changes: 2 additions & 0 deletions src/frame/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,8 @@ fn decoded_header_size(name: usize, value: usize) -> usize {

#[cfg(test)]
mod test {
use std::iter::FromIterator;

use super::*;
use crate::frame;
use crate::hpack::{huffman, Encoder};
Expand Down
3 changes: 3 additions & 0 deletions src/proto/streams/streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,9 @@ impl Actions {
// Reset the stream.
self.send
.send_reset(reason, initiator, buffer, stream, counts, &mut self.task);
self.recv.enqueue_reset_expiration(stream, counts);
// if a RecvStream is parked, ensure it's notified
stream.notify_recv();
Ok(())
} else {
tracing::warn!(
Expand Down
1 change: 1 addition & 0 deletions tests/h2-tests/tests/prioritization.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use futures::future::{join, select};
use futures::{pin_mut, FutureExt, StreamExt};

use h2_support::prelude::*;
Expand Down
1 change: 1 addition & 0 deletions tests/h2-tests/tests/server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![deny(warnings)]

use futures::future::join;
use futures::StreamExt;
use h2_support::prelude::*;
use tokio::io::AsyncWriteExt;
Expand Down
9 changes: 7 additions & 2 deletions tests/h2-tests/tests/stream_states.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![deny(warnings)]

use futures::future::lazy;
use futures::future::{join, join3, lazy, try_join};
use futures::{FutureExt, StreamExt, TryStreamExt};
use h2_support::prelude::*;
use h2_support::util::yield_once;
Expand Down Expand Up @@ -536,7 +536,12 @@ async fn recv_next_stream_id_updated_by_malformed_headers() {
client.recv_frame(frames::go_away(1).protocol_error()).await;
};
let srv = async move {
let mut srv = server::handshake(io).await.expect("handshake");
let mut srv = server::Builder::new()
// forget the bad stream immediately
.max_concurrent_reset_streams(0)
.handshake::<_, Bytes>(io)
.await
.expect("handshake");
let res = srv.next().await.unwrap();
let err = res.unwrap_err();
assert_eq!(err.reason(), Some(h2::Reason::PROTOCOL_ERROR));
Expand Down

0 comments on commit d1e3f57

Please sign in to comment.