Граф коммитов

636 Коммитов

Автор SHA1 Сообщение Дата
Lars Eggert 3c63b138ba
chore: Fix clippy `this map_or is redundant` (#2232)
* chore: Fix clippy `this map_or is redundant`

* Update neqo-bin/src/server/mod.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-11-18 10:04:29 +00:00
Max Inden fe76cdc6c2
refactor(transport): reuse `now` in qlog wherever available (#2216)
* refactor(transport): reuse `now` in qlog whereever available

Instead of using `QLogStream::add_event_data_now`, which internally calls
`std::time::Instant::now()`, pass `now to
`QLogStream::add_event_data_with_instant`.

* Move regex to workspace dep

* Don't prefix now, before and after with time_

* Document preference for _with_time

---------

Co-authored-by: Lars Eggert <lars@eggert.org>
2024-11-14 16:18:24 +02:00
Lars Eggert 84bf552aab
chore: Bump some dependency versions that changed upstream (#2225)
And also convert some that are used in multiple crates to workspace
dependencies.
2024-11-12 16:28:37 +00:00
Max Inden 1f0106e900
chore: make url crate a workspace dependency (#2221) 2024-11-06 11:06:45 +00:00
Max Inden ad2c7d290d
deps: enable std feature of url crate (#2219)
`url` `v0.5.3` and `idna` `v1.0.3` added no-std support:
https://github.com/servo/rust-url/pull/831

Since Neqo sets `default-features = false`, the above would break Neqo.

Related: https://github.com/servo/rust-url/pull/831
2024-11-06 10:05:17 +00:00
Max Inden 934b62d5b2
feat: don't allocate in UDP recv path (#2184)
* feat(common): make Datagram generic over payload type

Previously the payload type of `Datagram` was `Vec<u8>`, thus the `Datagram`
always owned the UDP datagram payload.

This change enables `Datagram` to represent both (a) an owned payload allocation
(i.e. `Vec<u8>`), but also represent (b) a view into an existing payload (e.g. a
long lived receive buffer via `&[u8]`).

The default payload type stays `Vec<u8>`, thus not breaking existing usage of
`Datagram`.

* feat(transport): accept borrowed instead of owned input datagram

Previously `process_input` (and the like) took a `Datagram<Vec<u8>>` as input.
In other words, it required allocating each UDP datagram payload in a dedicated
`Vec<u8>` before passing it to `process_input`.

With this patch, `process_input` accepts a `Datagram<&[u8]>`. In other words, it
accepts a `Datagram` with a borrowed view into an existing buffer (`&[u8]`),
e.g. a long lived receive buffer.

* feat(udp): return borrowed Datagram on receive

Previously `recv_inner` would return `Datagram<Vec<u8>>`. In other words, it
would allocate a new `Vec<u8>` for each UDP datagram payload.

Now `recv_inner` reads into a provided buffer and returns `Datagram<&[u8]>`,
i.e. it returns a view into the provided buffer without allocating.

* feat(bin): don't allocate in UDP recv path (#2189)

Pass a long lived receive buffer to `neqo_udp::recv_inner`, receiving an
iterator of `Datagram<&[u8]>`s pointing into that buffer, thus no longer
allocating in UDP receive path.
2024-10-23 10:36:49 +00:00
Max Inden b5e03744c5
chore(http3): fix typo (#2196)
Signed-off-by: Max Inden <mail@max-inden.de>
2024-10-22 15:59:34 +00:00
Lars Eggert 9f1c2f3ab0
chore: Fix new clippy warning (#2194) 2024-10-21 12:13:54 +00:00
Lars Eggert d6cc30ec80
chore: Address new nightly clippy warnings (#2151) 2024-10-07 11:47:52 +00:00
Kershaw eb92e43dfd
make process_output be able to return keep_alive timeout (#2136)
* make process_output be able to return keep_alive timeout

* address comments

* address more comments
2024-10-02 13:11:20 +00:00
Max Inden eb3e83506c
perf(transport): have add_datagram take Vec<u8> (#2120)
`add_datagram` takes a Quic datagram and adds it to the queue of datagrams to be
sent out. Previously it would take a reference (i.e. `&[u8]`) and would allocate
it into a new `Vec<u8>` before enqueuing. At the call-site the original
allocation (referenced by the `&[u8]`) would go out-of-scope and thus be
de-allocated. This is a wasted allocation for each Quic datagram to be send.

This commit has the call-site pass the owned `Vec<u8>` down right away.

Co-authored-by: Lars Eggert <lars@eggert.org>
2024-09-18 13:26:31 +03:00
Max Inden c76e8a151a
fix: typos (#2113)
* fix(qpack): typo

* typo
2024-09-16 09:54:07 +00:00
Lars Eggert fe2f0d03eb
fix: Handle H3 grease frame types (#1996)
* fix: Handle H3 grease stream types

Doesn't work yet, since it stops reading from the stream afterwards.

Fixes #1991

* Add test and fix bug

* Handle non-HEADERS first frames

* Update neqo-http3/src/stream_type_reader.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Suggestion from @martinthomson

* In debug builds, add a grease frame before the headers.

* Revert "In debug builds, add a grease frame before the headers."

This is breaking too many tests.

This reverts commit 7b9ea7ff7e.

* Simplify

* HFrameType is a struct now

* Bump coverage

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-08-12 15:49:00 +00:00
Lars Eggert b63e0ff567
chore: Remove `test_` from test names (#2024)
To make @martinthomson happy :-)
2024-07-31 08:09:02 +00:00
Lars Eggert 7a396756ef
chore: Remove superfluous clippy allows (#1997)
* chore: Remove superfluous clippy allows

Now that nightly has experimental support for
https://rust-lang.github.io/rfcs/2383-lint-reasons.html, use that to
identify superfluous clippy allows and remove them.

* Minimize diff

* fmt

* Minimize diff

* Fixes
2024-07-25 18:09:27 +03:00
Max Inden 19ec1a9e54
refactor(server): remove ServerConnectionIdGenerator (#1981)
* refactor(server): remove ServerConnectionIdGenerator

A `neqo_transport::Server` manages multiple `neqo_transport::Connection`s. A
`Server` keeps a `HashMap` of all `Connection`s, indexed by `ConnectionId`.

Indexing by `ConnectionId` is difficult as:

- The `ConnectionId` is not known before constructing the connection.
- The `ConnectionId` might change throughout the lifetime of a connection.

Previously the index was kept up-to-date through a wrapper around the
`ConnectionIdGenerator` provided to a `Connection` by a `Server`. This wrapper
would be provided a shared reference to the `Server`s `HashMap` of
`Connection`s. Whenever the `Server` would `process` a `Connection` and that `Connection` would generate a new `ConnectionId` via
`ConnectionIdGenerator::generate_cid`, the wrapped `ConnectionIdGenerator` would
also insert the `Connection` keyed by the new `ConnectionId` into the `Server`'s
`HashMap` of `Connection`s.

This has two problems:

- Complexity through indirection where a `Connection` owned by a `Server` can
indirectly mutate the `Server` through the provided wrapped
`ConnectionIdGenerator` having access to the `Server`'s set of `Connection`s.

- Double `RefCell` borrow e.g. when a `Server` would iterate its `Connection`s,
process each, where one of them might generate a new `ConnectionId` via the
provided `ConnectionIdGenerator`, which in turn would insert the `Connection`
into the currently iterated set of `Connection`s of the `Server`.

This commit replaces the `HashMap<ConnectionId, Connection>` of the `Server`
with a simple `Vec<Connection>`. Given the removal of the index, the
`ConnectionIdGenerator` wrapper (i.e. `ServerConnectionIdGenerator`) is no
longer needed and removed and thus the shared reference to the `Server`s
`Connection` `HashMap` is no longer needed and thus the above mentioned double
borrow is made impossible.

Downside to the removal of the index by `ConnectionId` is a potential
performance hit. When the `Server` manages a large set of `Connection`s, finding
the `Connection` corresponding to a `ConnectionId` (e.g. from an incoming
`Datagram`) is `O(n)` (`n` equal the number of connections).

* A server SHOULD ignore a packet with the same destination conn id

* Remove unused and re-introduce `[self]`

* Remove AttemptKey

Two packets with the same connection id but different source addresses are
assigned to the same connection. Thus there is no need to use the remote address
to disambiguate the packets. Thus there is no need for `AttemptKey`.
2024-07-17 17:54:42 +00:00
Lars Eggert 80c7969fb3
ci: Use cargo-machete to check for unused dependencies (#1974)
* ci: Use cargo-machete to check for unused dependencies

And remove the ones it found.

* --with-metadata has false positives

* Remove --no-fallback

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
2024-07-12 12:26:51 +00:00
Lars Eggert f1c04d22bc
ci: Fix the fuzz targets (#1972)
* ci: Fix the fuzz targets

And check them during CI, so they keep building.

* Fix

* Fix

* Add cargo-fuzz

* Fix the fuzzers

* Fix two clippy nightly things while I'm here
2024-07-12 09:45:33 +00:00
Lars Eggert 4852dc6b43
feat: DPLPMTUD (#1903)
* WIP

* Fixes

* Minimize diff

* Progress

* Fix clippy

* Reduce diff to main

* Use RefCell

* Make Pacer use PmtudState

* Renamings

* Fix tests broken by changing PATH_MTU_V6

* WIP

* Finalize

* Update neqo-transport/src/path.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Address comments

* Update neqo-transport/src/pmtud.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Remove PmtudRef from ClassicCongestionControl

* Disable PMTUD by default, except for demo client and server, and simulator

* Fix clippy

* Make Pmtud part of Pacer only

* These are now `const_assert`s

* Cleanups

* Address more comments

* Cleanups

* Add some initial tests

* Fix clippy

* Minimize diff

* Probe with non-padding data

* Search table based on TMA paper

* Deal with PMTU reductions

* Fix crypto invocation limits

* Fix comment

* More comments

* Add PMTU_RAISE_TIMER

* Lost PMTUD probes do not elicit a congestion control reaction

* Update pacer when MTU changes

* Better way to update pacer

* Fix last commit

* Potential fix for bench

* Update neqo-transport/src/pmtud.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/pmtud.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/pmtud.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/cc/classic_cc.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Undo

* Simplifications

* rustfmt

* Disarm raise timer when it fired

* test script that triggers the bug

* Revert test.sh (modulo bug fix)

* Increase coverage

* Better test

* Another test

* let Some(...) instead of testing

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Martin Thomson <mt@lowentropy.net>

* Fix

* static_assertions to dev-dependencies

* Panic on failure

* Fixes after merge

* Make test-only plpmtu() panic on error

* set_confirmed

* invocations_base -> largest_packet_len

* Simplify

* Set builder limit in output_path()

* fmt

* A bunch of changes based on Martin's review

* Avoid spurious PMTUD restarts better. Possible perf. optimizations.

* Improve coverage

* Enable PMTUD for simulator

* Update neqo-transport/src/connection/mod.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/connection/mod.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/connection/mod.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/packet/mod.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Update neqo-transport/src/stats.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Suggestions from Max

* Update neqo-transport/src/pmtud.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Suggestions from Martin

* More suggestions

* Add TODO

* Use filter fn

Follow-up on https://github.com/mozilla/neqo/pull/1903#discussion_r1617011637

* clippy

* Fixes

* doc fix

* refactor(pmtud): implement Copy for Probe

`Probe` is a small simple enum on the stack, thus convention is to implement
`Copy` instead of only `Clone` with a call to `clone()`.

The following helped me in the past:

> When should my type be Copy?
>
> Generally speaking, if your type can implement Copy, it should. Keep in mind,
> though, that implementing Copy is part of the public API of your type. If the
> type might become non-Copy in the future, it could be prudent to omit the Copy
> implementation now, to avoid a breaking API change.

https://doc.rust-lang.org/std/marker/trait.Copy.html#when-should-my-type-be-copy

* Make search_tables identical length, and deal with the fallout

* More

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Signed-off-by: Martin Thomson <mt@lowentropy.net>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
Co-authored-by: Max Inden <mail@max-inden.de>
2024-07-10 14:50:32 +00:00
Lars Eggert c209c439e2
chore: Turn on more clippy lints, and fix the warnings (#1956)
* chore: Turn on more clippy lints, and fix the warnings

* Fixes

* Fixes

* Fixes

* Update neqo-transport/src/addr_valid.rs

Co-authored-by: Martin Thomson <mt@lowentropy.net>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Suggestions from @martinthomson

* More from @martinthomson

* More from @martinthomson

* And more

* Fixes after rebase

* Better Cubic fix

* let _ -> _

* Add reason to `#[allow(clippy::mutable_key_type)]`

* fmt

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-07-04 05:50:45 +00:00
Max Inden 8d23703912
refactor(transport/server): always process each connection (#1929)
* refactor(transport/server): always iterate each connection

Say a `neqo_transport::Server` is managing a single `neqo_transport::Connection`
in `Server::connections`. Assume the following chain of events:

1. A user (e.g. `neqo-http3`) calls `Server::process`.

    ``` rust
    pub fn process(&mut self, dgram: Option<&Datagram>, now: Instant) -> Output {
        if self.wake_at.map_or(false, |c| c <= now) {
            self.wake_at = None;
        }

        dgram
            .and_then(|d| self.process_input(d, now))
            .or_else(|| self.process_next_output(now))
            .map(|d| {
                qtrace!([self], "Send packet: {:?}", d);
                Output::Datagram(d)
            })
            .or_else(|| self.wake_at.take().map(|c| Output::Callback(c - now)))
            .unwrap_or_else(|| {
                qtrace!([self], "Go dormant");
                Output::None
            })
    }
    ```

    6664452e2b/neqo-transport/src/server.rs (L660-L677)

    2. `self.wake_at` is `None`.
    3. `dgram` is `None`, thus `self.process_input` is never called.
    4. `self.process_next_output(now)` is called.
        ``` rust
        fn process_next_output(&mut self, now: Instant) -> Option<Datagram> {
            qtrace!([self], "No packet to send, look at waiting connections");
            while let Some(c) = self.waiting.pop_front() {
                if let Some(d) = self.process_connection(&c, None, now) {
                    return Some(d);
                }
            }
        ```

        6664452e2b/neqo-transport/src/server.rs (L636-L642)
        1. It attains a reference to the one `Connection` through `self.waiting.pop_front()`.
        2. It calls self.process_connection which in turn calls
        `Connection::process`, returning a `Output::Callback(_)`, which is stored in `self.wake_at`.
  5. `self.wake_at.take()` takes the callback and returns it to the user as `Output::Callback`.
6. The user calls `Server::process` again.
    1. `self.wake_at` is `None`.
    2. `dgram` is `None`, thus `self.process_input` isn't called.
    3. `Server::process` calls `Server::process_next_output`.
        1. `Server::process_next_output` finds no connection reference in
        `self.waiting` and thus returns `None`.
    4. `self.wake_at.take()` is `None`
    5. `Server::process` returns `None`

Result is that the user received an `Output::None` even though the one `Connection` managed
by the `Server` is waiting for a callback. Thus the server stalls.

The single source of truth of whether a `Connection` needs a callback or not is
the `Connection` itself. Instead of duplicating this information in
`Server::wake_at`, `Server::waiting`, `ServerConnectionState::wake_at`, always
ask the single source of truth, i.e. the `Connection`.

More concretely, with this patch `Server::process` always calls
`Connection::process` for each of its `Connection`s. It does not try to be smart
on whether a `Connection` needs `process`ing or not.

* Don't duplicate active state

* Don't duplicate attempt state

* Simplify process_connection call

* Deduplicate active connections

* Attempt fix for zerortt

* clippy

* Attempt fix for same_initial_after_connected

* Address minor TODOs

* Remove Server::add_to_waiting

It is no longer needed as each connection is always processed.

* Allow connected_server with more than one connection

* Remove unnecessary TODO

* Simplify closed connection clean up
2024-07-02 08:11:20 +00:00
Lars Eggert 9732a12c1c
chore: Fix new clippy issues found by Rust 1.81.0-nightly (#1930) 2024-06-18 05:20:02 +00:00
Kershaw 590940b38c
remove trailing comma (#1907) 2024-05-17 11:46:26 +00:00
Kershaw cb343dad92
A test to trigger 'earliest > now' assertion (#1491)
* make expiry return longer timeout

* fix tests

* again

* address comments

* only compare pto

* address comments
2024-05-16 09:25:09 +00:00
Lars Eggert d7f33e2054
chore: Use `MIN_INITIAL_PACKET_SIZE` instead of literal `1200` (#1895) 2024-05-13 11:22:22 +00:00
Lars Eggert 6979f019b6
chore: Fix new clippy lints in cargo 1.80.0-nightly (#1883)
* chore: Fix new clippy lints in cargo 1.80.0-nightly (05364cb2f 2024-05-03)

* No need for `#[allow(clippy::mutable_key_type)]`

* No need for `build = "build.rs"`
2024-05-07 13:13:26 +03:00
Max Inden bb88aab452
fix(SendMessage): use SendStream::set_writable_event_low_watermark (#1838)
* fix(SendMessage): use SendStream::set_writable_event_low_watermark

Previously `SendMessage::send_data` could stall, if less than the minimum
message size is available to be sent. See
https://github.com/mozilla/neqo/issues/1819 for details.

This commit implements solution (3) proposed in
https://github.com/mozilla/neqo/issues/1819.

This commit introduces `SendStream::set_writable_event_low_watermark` which is
then used in `SendMessage::send_data` to signal to `SendStream` the minimum
required send space (low watermark) for the next send. Once reached,
`SendStream` emits a `SendStreamWritable` eventually triggering another
`SendMessage::send_data`.

Alternative to https://github.com/mozilla/neqo/pull/1835. Compared to
https://github.com/mozilla/neqo/pull/1835, this fix does not utilize the
`SendMessage` buffer, thus does not introduce an indirection to the send path.
In addition, under the assumption that available send space is increased in
larger batches, this fix does not send tiny data frames (2 byte header, 1 byte
goodput). Downside, compared to https://github.com/mozilla/neqo/pull/1835, is
that it requires both changes in `neqo-transport` and `neqo-http3`.

Secondarily, this fixes https://github.com/mozilla/neqo/pull/1821 as well.

* Move const

* Add documentation

* Add SendStream test

* Fix intra doc links

* Add neqo-http3 test

* Replace goodput with payload

* Re-trigger benchmarks

Let's see whether the "Download" benchmark is consistent.

* Rename emit_writable_event to maybe_emit_writable_event

* Replace expect with unwrap

* Use NonZeroUsize::get

* Replace expect with unwrap

* %s/Actually sending/Sending

* Typo

* Have update() return available amount

* Document setting once would suffice

* Reduce verbosity

* fix: drop RefCell mutable borrow early
2024-05-07 00:51:29 +00:00
Max Inden e467273e1a
fix(http3): always qlog on send_buffer() (#1876)
* fix(http3): always qlog on send_buffer()

`neqo_http3::SendMessage` calls `qlog::h3_data_moved_down()` whenever it moves
data down to the QUIC layer. `SendMessage` moves data down to the QUIC layer
either directly via `self.stream.send_atomic` or indirectly buffered through `self.stream.send_buffer`.

Previously only one of the 3 calls to `self.stream.send_buffer` would thereafter
call `qlog::h3_data_moved_down()`.

This commit moves the `h3_data_moved_down` call into `self.stream.send_buffer`, thus
ensuring the function is always called when data is moved. In addition,
`self.stream.send_atomic` now as well does the qlog call, thus containing all
qlog logic in `buffered_send_stream.rs` instead of `send_message.rs`.

* Trigger benchmark run

* Don't qlog if buffer is empty

* Fix typo

* Use early return to keep indentation short

* Don't qlog if sent is 0
2024-05-06 05:25:53 +00:00
Max Inden ed19eb229d
refactor: rename ConnectionError to CloseReason (#1872)
The `neqo_transport::ConnectionError` enum contains the two non-error variants
`Error::NoError` and `CloseReason::Application(0)`. In other words,
`ConnectionError` contains variants that are not errors.

This commit renames `ConnectionError` to the more descriptive name
`CloseReason`.

See suggestion in https://github.com/mozilla/neqo/pull/1866#issuecomment-2091654649.

To ease the upgrade for downstream users, this commit adds a deprecated
`ConnectionError`, guiding users to rename to `CloseReason` via a deprecation warning.

``` rust
pub type ConnectionError = CloseReason;
```
2024-05-03 08:03:45 +00:00
Lars Eggert 3e537097cb
chore: Bump qlog to 0.13 and deal with the fallout (#1827)
* chore: Bump qlog to 0.13 and deal with the fallout

Fixes #1826

* Update qlog.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Make `log` and `qlog` workspace dependencies

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Max Inden <mail@max-inden.de>
2024-04-16 11:37:14 +00:00
Max Inden 7feb7cb19a
fix(http3): only add to stream_has_pending_data on has_data_to_send (#1793)
* fix(http3): only add to stream_has_pending_data on has_data_to_send

`<SendMessage as Sendstream>::send_data` attempts to send a slice of data down
into the QUIC layer, more specifically `neqo_transport::Connection::stream_send_atomic`.

While it attempts to send any existing buffered data at the http3 layer first,
it does not itself fill the http3 layer buffer, but instead only sends data, if
the lower QUIC layer has capacity, i.e. only if it can send the data down to the
QUIC layer right away.

5dfe106669/neqo-http3/src/send_message.rs (L168-L221)

`<SendMessage as Sendstream>::send_data` is called via
`Http3ServerHandler::send_data`. The wrapper first marks the stream as
`stream_has_pending_data`, marks itself as `needs_processing` and then calls
down into `<SendMessage as Sendstream>::send_data`.

5dfe106669/neqo-http3/src/connection_server.rs (L51-L74)

Thus the latter always marks the former as `stream_has_pending_data` even though
the former never writes into the buffer and thus might actually not have pending
data.

Why is this problematic?

1. Say that the buffer of the `BufferedStream` of `SendMessage` is empty.

2. Say that the user attempts to write data via `Http3ServerHandler::send_data`.
Despite not filling the http3 layer buffer, the stream is marked as
`stream_has_pending_data`.

3. Say that next the user calls `Http3Server::process`, which will call
`Http3Server::process_http3`, which will call
`Http3ServerHandler::process_http3`, which will call
`Http3Connection::process_sending`, which will call `Http3Connection::send_non_control_streams`.

`Http3Connection::send_non_control_streams` will attempt to flush all http3
layer buffers of streams marked via `stream_has_pending_data`, e.g. the stream
from step (2). Thus it will call `<SendMessage as SendStream>::send` (note
`send` and not the previous `send_data`). This function will attempt the
stream's http3 layer buffer. In the case where the http3 layer stream buffer is
empty, it will enqueue a `DataWritable` event for the user. Given that the
buffer of our stream is empty (see (1)) such `DataWritable` event is always emitted.

5dfe106669/neqo-http3/src/send_message.rs (L236-L264)

The user, on receiving the `DataWritable` event will attempt to write to it via
`Http3ServerHandler::send_data`, back to step (2), thus closing the busy loop.

How to break the loop?

This commit adds an additional check to the `stream_has_pending_data` function to
ensure it indeed does have pending data. This breaks the above busy loop. In
addition, it renames the function to `stream_might_have_pending_data`.

* Address review

* Revert comment but keep links
2024-04-09 05:49:35 +00:00
Max Inden 5f9c3e7096
refactor(client): use process_output and process_multiple_input (#1794)
* refactor(client): use process_output and process_multiple_input

`neqo_transport::Connection` offers 4 process methods:

- `process`
- `process_output`
- `process_input`
- `process_multiple_input`

Where `process` is a wrapper around `process_input` and `process_output` calling
both in sequence.

5dfe106669/neqo-transport/src/connection/mod.rs (L1099-L1107)

Where `process_input` delegates to `process_multiple_input`.

5dfe106669/neqo-transport/src/connection/mod.rs (L979-L1000)

Previously `neqo-client` would use `process` only. Thus continuously
interleaving output and input. Say `neqo-client` would have multiple datagrams
buffered through a GRO read, it could potentially have to do a write in between
each `process` calls, as each call to `process` with an input datagram might
return an output datagram to be written.

With this commit `neqo-client` uses `process_output` and `process_multiple_input`
directly, thus reducing interleaving on batch reads (GRO and in the future
recvmmsg) and in the future batch writes (GSO and sendmmsg).

By using `process_multiple_input` instead of `process` or `process_input`,
auxiliarry logic, like `self.cleanup_closed_streams` only has to run per input
datagram batch, and not for each input datagram.

Extracted from https://github.com/mozilla/neqo/pull/1741.

* process_output before handle

* process_ouput after each input batch
2024-04-09 05:47:49 +00:00
Max Inden 5dfe106669
refactor: have process_input delegate to process_multiple_input (#1792)
The `Connection::process_input` and `Connection::process_multiple_input`
functions are identical, except that the latter handles multiple `Datagram`s.

To avoid any changes to one without updating the other, have `process_input`
simply delegate to `process_multiple_input`.

Commit also does the equivalent change to `neqo_http3::Http3Client`.
2024-04-05 04:52:38 +00:00
Lars Eggert f1560abfee
chore: Rename feature `fuzzing` to `disable-encryption` (#1767)
* chore: Rename feature `fuzzing` to `disable-encryption`

Because `cargo fuzz` relies on being able to use `fuzzing`

* WIP

* More

* Add `disable-encryption` feature to CI, to make sure it doesn't rot

* shellcheck

* Undo

* Fix

* Address code review and rename `fuzzing` -> `null`

* Fix clippy

* Address code review

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
2024-03-27 10:39:57 +02:00
Max Inden e4bc0c1ed4
feat(client,server): rework logging (#1692)
* feat(client,server): rework logging

- In `neqo-client` and `neqo-server` use `neqo_common::log` instead of `println!`
  and `eprintln!`.
- Add `-q`, `-v`, `-vv`, `-vvv`, `-vvvv` log level flags via
  `clap_verbosity_flag`.
- Set default log level to INFO. Demote many `qinfo!` to `qdebug!`.

* fix(upload_test.sh): set RUST_LOG debug for neqo_transport::cc

Needed in order for mozlog_neqo_cwnd.py to analyze cc.

* Additional level reductions

* Trigger CI

---------

Co-authored-by: Lars Eggert <lars@eggert.org>
2024-03-21 22:47:58 +00:00
Max Inden f9253bd5a3
fix(http3): typos (#1735) 2024-03-12 11:58:47 +00:00
Lars Eggert d48fbed733
fix: Disable generation of criterion HTML graphs (#1728)
* fix: Disable generation of criterion HTML graphs

Because we pin the benchmark runs to single cores, and criterion hence
runs the report generation also on those cores, and based on `top`
output it appears as this is parallelized and hence may interfere
with the benchmark runs.

* Try `--noplot` (and patch things so that actually works)

* Missed one

* Don't post comment, since this is being refactored

* Fix merge

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
2024-03-12 06:49:43 +00:00
Valentin Gosu 869afeaad0
Priority headers should be set by the application (#1725)
Co-authored-by: Lars Eggert <lars@eggert.org>
2024-03-11 17:10:15 +00:00
Lars Eggert 06b5f29b34
chore: Enable `clippy::pedantic` at the workspace level, globally (#1701)
* chore: Enable `clippy::pedantic` at the workspace level, globally

* Fix issues

---------

Signed-off-by: Martin Thomson <mt@lowentropy.net>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-03-04 09:52:46 +02:00
Lars Eggert 4c3ccfdc4b
chore: Set `default-features=false`, to eliminate some unneeded deps (#1704)
* chore: Set `default-features=false`, to eliminate some unneeded deps

* More

* More
2024-03-04 00:06:31 +00:00
Lars Eggert e826698005
chore: Add the missing license blurb where it was missing (#1702) 2024-03-03 23:01:45 +00:00
Lars Eggert a9ed8d5c78
chore: Fix clippy nightly issues (#1680) 2024-02-27 13:05:05 +02:00
Max Inden 5d80d09383
refactor: derive default for unit enum variants (#1667)
For unit enum default variants, derive `Default` and use the `#[default]` attribute.

See https://doc.rust-lang.org/std/default/trait.Default.html#enums for details.

Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-02-22 12:05:32 +11:00
Martin Thomson 649994e1af
Extra clippy (#1664)
* Add some more doc-stuff

* Get rid of redundant imports

No more use of `use super::*` in tests.
Avoid importing things that are in the rust prelude.
2024-02-22 12:05:15 +11:00
Max Inden 9b6215364d
feat: update to Rust 2021 edition (#1671)
* feat: update to Rust 2021 edition

See transition docs:

https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html

The described `cargo fix --edition` does not yield any suggestions.

* fix: clippy

---------

Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-02-22 09:17:12 +11:00
Max Inden 0162014423
chore: remove neqo-interop (#1672)
`neqo-interop` is replaced by `neqo-client` and `neqo-server` and thus unused.
2024-02-22 08:46:21 +11:00
Max Inden 3024cbb181
refactor: remove dead fairness and sendorder fn on SendStream (#1668)
Removes `fn` `set_sendorder` and `set_fairness` on `SendStream` trait.

The `SendStream` trait is not publicly exposed. Neither `set_sendorder` nor
`set_fairness` is called within `neqo-http3`.

Co-authored-by: Martin Thomson <mt@lowentropy.net>
2024-02-21 10:06:06 +11:00
Max Inden f7a9de9e78
fix(http3): typos (#1669) 2024-02-21 09:46:31 +11:00
Martin Thomson 836e852616
Clippy pedantic (#1649)
* Add must_use everywhere clippy thinks we need to

* Add panics docs everywhere

* Remove some redundant else blocks

* Fix or suppress similar_names lint

* Automatic fix for doc_markdown lint

* Remove unnecessary `Res` wrappings

These are mostly the result of removing internal errors in our code.
The cleanup there was incomplete.

* Cleanup some unused_self instances, including some dead code

* Use String::new instead of String::from("")

* Remove deny-warnings feature

Enable warnings for clippy::pedantic
Disable clippy::module_name_repetitions for all lib.rs

* Fix missing error doc on one! function

* Invert the test in the pre-commit hook

* Document errors on all public interfaces

* Suppress excessive bools lint for args struct

* Take suggested tweak for map_unwrap_or lint

* Take Copy argument by value

* Nest or patterns as suggested

* Suppress one struct_field_names lint because I can't think of a better name

* Remove unnecessary async on functions

* Remove unnecessary wrap again

* Remove implicit clone calls

* Refactor client main a little to reduce its length

* Pass by reference where the linter says we can

* Remove some easy lints in the server main.rs

* Another simple auto-fix lint

* Merging match arms automatically

* Avoid manual assertion

* Remove integer casts where possible

* Invert some conditions to avoid inversions

* Suppress some too_many_lines lints

* Remove some unnecessary borrows

* Add some missing semicolons

* Avoid a closure when not needed

* Remove some Default::default usage

* Fix some unreadable literals

* qlog needs f32, which means precision loss

* Stop allocating large buffers on the stack

* Avoid wildcard matches

* Fix panics doc

* Reorder items

* Remove extra deref

* Fix format args

* Iterate better

* Update neqo-transport/src/qlog.rs

Co-authored-by: Max Inden <mail@max-inden.de>
Signed-off-by: Lars Eggert <lars@eggert.org>

* Remove unused path from Db arm of enum

* Fix unknown lint warning

* Clone directly rather than indirectly

* Those any functions aren't used

* Suppress warnings here for now

* Fix some thread_local usages

* Unused, remove

* Update SharedVec as suggested, plus a bonus default thing

---------

Signed-off-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Max Inden <mail@max-inden.de>
2024-02-14 11:33:12 +02:00
Martin Thomson bb74821940
Cache random (#1640)
* Avoid allocation in random()

This makes the function take its argument as a const generic argument,
which allows the allocation to be performed on the stack.

There are a few cases where we need to do in-place randomization of a
different type of object (`SmallVec` in a few places) so I've also
exposed an in-place mutation function.

Next step is to cache the slot that this uses.

* Cache randomness

* Add a test for the cache

* Remove dead code

---------

Co-authored-by: Lars Eggert <lars@eggert.org>
2024-02-09 09:58:23 +02:00