Commit Graph

2620 Commits

Author SHA1 Message Date
Dirkjan Ochtman 17fe82b598 Apply clippy fixes for 1.49 2021-01-01 11:16:05 -08:00
Benjamin Saunders 70ba6b78a1 Add missing traits to UnknownStream errors 2021-01-01 14:25:50 +01:00
Benjamin Saunders 1717e9ad81 Return UnknownStream errors more consistently
Previously, these sometimes depended on whether the peer had
acknowledged an operation, which might lead users to incorrectly
believe that attempting to operate on a stream after stopping or
resetting it is sane.
2021-01-01 14:25:50 +01:00
Benjamin Saunders bd1c5b34d5 Tweak unknown stream error docs 2021-01-01 14:25:50 +01:00
Matthias Einwag 62ef3cc1f2 Allow to show connection stats in bulk benchmark
This allows to determine the impact of particular changes a
bit easier.

Example output:

```
Overall stats:

Sent 1073741824 bytes on 1 streams in 4.04s (253.61 MiB/s)

Stream metrics:

      │  Throughput   │ Duration
──────┼───────────────┼──────────
 AVG  │  253.56 MiB/s │     4.04s
 P0   │  253.50 MiB/s │     4.04s
 P10  │  253.62 MiB/s │     4.04s
 P50  │  253.62 MiB/s │     4.04s
 P90  │  253.62 MiB/s │     4.04s
 P100 │  253.62 MiB/s │     4.04s

Server connection stats:
ConnectionStats {
    udp_tx: UdpStats {
        datagrams: 26391,
        bytes: 1110961,
    },
    udp_rx: UdpStats {
        datagrams: 918524,
        bytes: 1116003172,
    },
    frame_tx: FrameStats {
        ACK: 26388,
        CRYPTO: 6,
        DATAGRAM: 0,
        HANDSHAKE_DONE: 4,
        MAX_DATA: 0,
        MAX_STREAM_DATA: 4984,
        MAX_STREAMS_BIDI: 0,
        MAX_STREAMS_UNI: 1,
        NEW_CONNECTION_ID: 16,
        PATH_CHALLENGE: 0,
        PATH_RESPONSE: 0,
        PING: 0,
        RESET_STREAM: 0,
        RETIRE_CONNECTION_ID: 3,
        STOP_SENDING: 0,
        STREAM: 0,
    },
}

Client connection stats:
ConnectionStats {
    udp_tx: UdpStats {
        datagrams: 918556,
        bytes: 1116042037,
    },
    udp_rx: UdpStats {
        datagrams: 26391,
        bytes: 1110961,
    },
    frame_tx: FrameStats {
        ACK: 918554,
        CRYPTO: 2,
        DATAGRAM: 0,
        HANDSHAKE_DONE: 0,
        MAX_DATA: 0,
        MAX_STREAM_DATA: 0,
        MAX_STREAMS_BIDI: 0,
        MAX_STREAMS_UNI: 0,
        NEW_CONNECTION_ID: 5,
        PATH_CHALLENGE: 0,
        PATH_RESPONSE: 0,
        PING: 0,
        RESET_STREAM: 0,
        RETIRE_CONNECTION_ID: 0,
        STOP_SENDING: 0,
        STREAM: 918552,
    },
}
```
2021-01-01 14:23:40 +01:00
Benjamin Saunders bc0648a518 Fix outdated docs 2021-01-01 08:22:52 +01:00
Benjamin Saunders 61a72a3836 Limit concurrent connections rather than accept queue size
Enables stronger latency guarantees, along the same lines as the
nearby change to streams.
2021-01-01 08:22:16 +01:00
Matthias Einwag 62a88008a7 Make connection stats public
So far those haven't been consumable by applications.
This makes the struct public, and adds an accessor
for `quinn_proto::Connection` and `quinn::Connection`.
2020-12-31 12:03:20 -08:00
Matthias Einwag de627437bc Don't assume that the send buffer capacity is exactly the MTU
Reserving capacity can provide more capacity than we asked for.
However we are not allowed to write more than MTU size. Therefore
the maximum allowed capacity is tracked separately.
2020-12-30 07:33:12 +01:00
Matthias Einwag 3c55123a9c Use initialized CMSG data on sending
The outgoing cmsgs can't be uninit because it breaks `CMSG_NXTHDR`.
The function will try to access the next cmsg in the buffer at
https://github.com/rust-lang/libc/blob/ae65df55fe2d0e1348fed575bfc8c0c3e4744c65/src/unix/linux_like/linux/mod.rs#L2585-L2589

This will yield an undefined result, and can let `CMSG_NEXT` return `None`.
This prevents more than 1 CMSG to be encoded. 0-initializing the
messages makes sure a length of 0 is read, and fixes the issue.

In addition this change improves an assert in the cmsg encoder, which
makes it easier to determine the required CMSG space.
2020-12-30 07:33:12 +01:00
Matthias Einwag 1aaff731ab Extend bulk benchmark
This change improves the bulk benchmark:
- The total amount of requests the benchmark performs can be configured
- The amount of concurrent requests on a given connection can be
  configured
- The amount of data to transfer per stream can be configured

E.g.

```
bulk --streams 300 --max_streams 100 --stream_size 10
```

will create 300 streams - with a maximum of 100 active streams at a time,
and send 10MB of data on each stream.

The "short" cli flags are taken form h2load where applicable.

The benchmark now also shows metrics which indicate the performance
of individual streams, which allows to judge fairness. Example output:

```
Overall stats:

Sent 3145728000 bytes on 300 streams in 12.11s (247.81 MiB/s)

Stream metrics:

      │  Throughput   │ Duration
──────┼───────────────┼──────────
 AVG  │  149.17 MiB/s │  396.00ms
 P0   │    0.83 MiB/s │   39.00ms
 P10  │   51.19 MiB/s │   40.00ms
 P50  │  129.75 MiB/s │   77.00ms
 P90  │  247.00 MiB/s │  195.00ms
 P100 │  254.75 MiB/s │    12.11s
```
2020-12-29 15:15:43 +01:00
Matthias Einwag 6d32b64d4c Extract data sending in bulk benchmark
This change moves establishing a stream and sending data into
a separate method.
2020-12-29 15:15:43 +01:00
Matthias Einwag 1bc75aa014 Allow to lookup the initial local IP address
When a listener is bound to multiple network interfaces (e.g. `::0`),
it is not obvious which IP the peer used to send a packet. We however
might need this information to send packets back to the peer with the
same source address.

This problem is described in #508.

This change makes the destination IP address which was used to send
the initial packet available in the `Conneting` and `Connection` types.

The information is far available only on Linux due to missing test on
other platforms.
2020-12-29 14:53:39 +01:00
Matthias Einwag 64c97b6af0 Extend benchmark for concurrent streams
This extends the "cargo bench" benchmark to test transmission of data
on multiple streams in parallel.

Ideally we would want all transmission to take a similar amount of time
(bandwidth shared fairly), and the overall throughput to stay the same
or increase (but never degrade) when multiple streams are in use.

The benchmark can not show the fairness aspect very well, since it only
prints an overall throughput. But it shows that performance with
multiple streams stays similar.

Output:

```
running 4 tests
test large_data_10_streams  ... bench: 180,761,260 ns/iter (+/- 12,090,679) = 58 MB/s
test large_data_1_stream    ... bench:  18,459,500 ns/iter (+/- 3,804,219) = 56 MB/s
test small_data_100_streams ... bench:   4,600,890 ns/iter (+/- 373,842)
test small_data_1_stream    ... bench:      71,019 ns/iter (+/- 34,298)
```

I also increased the size of the LARGE_DATA payload from 128kB to
1MB, since 128kB didn't show quinn peak performance.
2020-12-28 14:05:12 +01:00
Matthias Einwag c004ef0329 Improve fairness on stream transmissions
The current version of send multiplexing tries to send as much data from
a single stream as possible before switching over to the next stream.
The only situation where data from another stream than the original one
is sent is if there are no peer flow control credits available anymore,
or if the application didn't feed new data.
If none of this situations occur, other streams will be starved.

This is typically not what people expect, and can lead to high latencies
on streams which are queued behind earlier streams.

This change makes the send behavior "fairer" by enqueuing stream which
just have sent data **after** all other pending streams instead of in
front of them. This is simply achieved by switching to a `VecDeque` and
using the the right insert/remove orders.

Stats (obtained via #946), when running

```
./bulk --streams 300 --max_streams 10 --stream_size 10
```

```
Stream metrics:

AVG : Throughput:  172.38 MiB/s, Duration:  395.00ms
P0  : Throughput:    0.83 MiB/s, Duration:   39.00ms
P10 : Throughput:   49.19 MiB/s, Duration:   40.00ms
P50 : Throughput:  232.50 MiB/s, Duration:   42.00ms
P90 : Throughput:  245.87 MiB/s, Duration:  203.00ms
P100: Throughput:  251.25 MiB/s, Duration:    12.08s
```

```
Stream metrics:

AVG : Throughput:   24.20 MiB/s, Duration:  413.00ms
P0  : Throughput:   21.42 MiB/s, Duration:  279.00ms
P10 : Throughput:   23.25 MiB/s, Duration:  403.00ms
P50 : Throughput:   24.34 MiB/s, Duration:  410.00ms
P90 : Throughput:   24.81 MiB/s, Duration:  430.00ms
P100: Throughput:   35.78 MiB/s, Duration:  466.00ms
```

With this change throughput on streams is a lot more consistent than
before.
2020-12-28 13:59:36 +01:00
Benjamin Saunders e151a5236c Fix state leak when a stopped stream is reset 2020-12-27 14:14:00 -08:00
Benjamin Saunders 4e6f946423 Clarify example path behavior 2020-12-22 07:42:34 +01:00
Benjamin Saunders a92e070fab Note address family gotcha 2020-12-22 07:42:34 +01:00
Benjamin Saunders 36de1c2385 Fix errors in example README 2020-12-22 07:42:34 +01:00
Dirkjan Ochtman 120c8157ae Update futures-* to 0.3.8
Prevents security issues in futures older than 0.3.5.

Specifically RUSTSEC-2020-0059 and RUSTSEC-2020-0060.
2020-12-21 14:22:18 -08:00
Dirkjan Ochtman 3b8730d651 Upgrade to directories-next 2 2020-12-21 14:22:18 -08:00
Dirkjan Ochtman 4935f58b25 Update rand to 0.8 2020-12-21 14:22:18 -08:00
Benjamin Saunders cd229d342e Always preserve outer type when converting to io::Error
Ensures that the resulting io::Error's dynamic type is constant and
its Display impl includes the "connection closed: " clarifying
context.
2020-12-20 13:38:23 -08:00
Benjamin Saunders 62fa56feaa Fix intra-doc link 2020-12-19 23:59:06 +01:00
Benjamin Saunders 005de6185f More helpful timeout error documentation 2020-12-19 23:59:06 +01:00
Benjamin Saunders 1c165f2dbc Remove trailing periods 2020-12-19 23:59:06 +01:00
Benjamin Saunders 47232c83d1 Sanity-check remote addresses before trying to connect
Catches some common user errors that would otherwise manifest as
difficult-to-diagnose I/O errors.
2020-12-18 06:54:11 +01:00
Dirkjan Ochtman 5f071729be Remove stray err-derive dependency 2020-12-14 10:34:54 -08:00
Dirkjan Ochtman 4420b61aaa quinn: print socket addresses in example client/server 2020-12-11 16:17:48 -08:00
Luca Barbato fc2016103d Fix a typo 2020-12-04 10:30:40 +01:00
Ximin Luo cfe6570a66 proto: add more high-level API docs to Connection, closes #924 (#926) 2020-12-02 20:30:09 +01:00
Matthias Einwag 6d84453037 Use a newtype to indicate whether a frame needs to be sent
This commit changes all code-path which update `MAX_DATA`,
`MAX_STREAM_DATA` and `STOP_SENDING` to use a new `ShouldTransmit` type
to indicate whether an outgoing frame needs to be enqueued. The type is
labeled with `#[must_use]` - which makes it harder to miss a place which
requires sending a frame.
2020-11-30 09:41:46 +01:00
Wenjie Li 9aa3bde3aa Expose cid generator customization API in endpoint builder (#925) 2020-11-25 09:13:33 +01:00
Dirkjan Ochtman f14c915e1f Apply clippy suggestions for Rust 1.48 2020-11-20 14:24:56 -08:00
Timon 83cff80908 Create example README (#910) 2020-11-15 21:43:28 +01:00
Dirkjan Ochtman efceb503a2 Add link explaining sans-io concept 2020-11-13 17:05:53 -08:00
Benjamin Saunders 51a3cea225 Link the correct draft version 2020-11-12 06:37:11 +01:00
Matthias Einwag 70f32c8eec Send only significant MAX_DATA frames
This change equals #880, but targets the connection window which is
updated via `MAX_DATA` frames instead of the stream windows.

Similar as #880, frames will only be enqueued if the update is
significant enough.

Quinn had already before an optimization, which triggered MAX_DATA
frames not to be sent when the window was set to the maximum at
the start of the connection [1]. However the frame was still set as
`pending` [2], which triggered the connection logic to create a packet
for it [3]. Since the payload was suppressed, this lead the connection
to either send additional ACK-only packets or create empty packets.

This change fixes this behavior, and thereby impacts the amount
of packets and performance even if the maximum connection flow
control window is specified. Therefore the throughput for large streams
increases on windows from 30MB/s to 56MB/s with this change.

[1] https://github.com/quinn-rs/quinn/blob/bd14aa1dc2162e68c3a90027e3ca4e6404aea94d/quinn-proto/src/connection/streams.rs#L485
[2] https://github.com/quinn-rs/quinn/blob/bd14aa1dc2162e68c3a90027e3ca4e6404aea94d/quinn-proto/src/connection/mod.rs#L2789
[3] https://github.com/quinn-rs/quinn/blob/bd14aa1dc2162e68c3a90027e3ca4e6404aea94d/quinn-proto/src/connection/mod.rs#L2789
2020-11-10 20:10:03 +01:00
Timon 5cc62c2416 Fix book ci (#898) 2020-11-10 10:56:49 +01:00
Dirkjan Ochtman 90abbbc33a Clean up trailing whitespace in README 2020-11-09 14:03:21 -08:00
Dirkjan Ochtman bb3e330b84 Fix default branch name in a few places 2020-11-09 14:03:21 -08:00
Dirkjan Ochtman e80fd67597 Fix branch name in book workflow 2020-11-09 14:03:21 -08:00
Timon 05672c67e8 Md Book setup (#868)
Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2020-11-09 20:57:30 +01:00
Benjamin Saunders d5de4708c3 Reduce default payload size limit to match internet MTU
Saves a noticable chunk of memory when using batched I/O.
2020-11-09 08:04:01 +01:00
Benjamin Saunders 917ca3a223 Adjust batch size to match the availability of batched I/O 2020-11-09 08:04:01 +01:00
Benjamin Saunders ddc4da92a2 Remove redundant flag
This was probably left over from earlier logic.
2020-11-09 08:04:01 +01:00
Benjamin Saunders dbbf811767 Deduplicate Incoming stream wakeups 2020-11-09 08:04:01 +01:00
Benjamin Saunders b681c65412 Implement batched recv for Linux-likes 2020-11-09 08:04:01 +01:00
Benjamin Saunders b9f1d2803f Extract Unix recv setup/decode logic into functions 2020-11-09 08:04:01 +01:00
Benjamin Saunders 7efb56a4eb Batch recvs 2020-11-09 08:04:01 +01:00