Commit Graph

110 Commits

Author SHA1 Message Date
Eliza Weisman
b8eab381c0 tracing: remove I/O type names from handshake spans (#608)
## Motivation

Currently, the `tracing` spans for the client and server handshakes
contain the name of the I/O type. In some cases, where nested I/O types
are in use, these names can be quite long; for example, in Linkerd, we
see log lines like this:

```
2022-03-07T23:38:15.322506670Z [ 10533.916262s] DEBUG ThreadId(01) inbound:accept{client.addr=192.168.1.9:1227}:server{port=4143}:direct:gateway{dst=server.echo.svc.cluster.local:8080}:server_handshake{io=hyper::common::io::Rewind<linkerd_io::either::EitherIo<linkerd_io::sensor::SensorIo<linkerd_io::prefixed::PrefixedIo<linkerd_io::either::EitherIo<tokio_rustls::server::TlsStream<linkerd_io::either::EitherIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>, linkerd_io::prefixed::PrefixedIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>>>>, linkerd_io::either::EitherIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>, linkerd_io::prefixed::PrefixedIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>>>>>, linkerd_transport_metrics::sensor::Sensor>, linkerd_io::sensor::SensorIo<linkerd_io::either::EitherIo<tokio_rustls::server::TlsStream<linkerd_io::either::EitherIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>, linkerd_io::prefixed::PrefixedIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>>>>, linkerd_io::either::EitherIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>, linkerd_io::prefixed::PrefixedIo<linkerd_io::scoped::ScopedIo<tokio::net::tcp::stream::TcpStream>>>>, linkerd_transport_metrics::sensor::Sensor>>>}:FramedWrite::buffer{frame=Settings { flags: (0x0), initial_window_size: 65535, max_frame_size: 16384 }}: h2::codec::framed_write: send frame=Settings { flags: (0x0), initial_window_size: 65535, max_frame_size: 16384 }
```

which is kinda not great.

## Solution

This branch removes the IO type's type name from the spans for the
server and client handshakes. In practice, these are not particularly
useful, because a given server or client instance is parameterized over
the IO types and will only serve connections of that type.
2022-03-08 15:54:31 -08:00
Sean McArthur
efa113bac6 Add max send buffer per stream option (#580) 2021-12-08 10:03:15 -08:00
Anthony Ramine
87969c1f29 Implement the extended CONNECT protocol from RFC 8441 (#565) 2021-11-24 10:05:10 +01:00
Anthony Ramine
f52d5e6290 Replace HTTP/2.0 by HTTP/2 😅
The protocol is named HTTP/2.
2021-10-20 11:10:25 -07:00
Anthony Ramine
465f0337f8 Refactor errors internals (#556)
h2::Error now knows whether protocol errors happened because the user
sent them, because it was received from the remote peer, or because
the library itself emitted an error because it detected a protocol
violation.

It also keeps track of whether it came from a RST_STREAM or GO_AWAY
frame, and in the case of the latter, it includes the additional
debug data if any.

Fixes #530
2021-09-28 09:04:35 -07:00
Eliza Weisman
c1b411fc14 add Connection::max_concurrent_recv_streams (#516)
This commit adds accessors to `client::Connection` and
`server::Connection` that return the current value of the
`SETTINGS_MAX_CONCURRENT_STREAMS` limit that has been sent by this peer
and acknowledged by the remote.

This is analogous to the `max_concurrent_send_streams` methods added in
PR #513. These accessors may be somewhat less useful than the ones for
the values negotiated by the remote, since users who care about this
limit are probably setting the builder parameter. However, it seems
worth having for completeness sake --- and it might be useful for
determining whether or not a configured concurrency limit has been acked
yet...

Part of #512
2021-02-25 08:58:19 -08:00
Markus Westerlind
30ca832790 Make some functions less-generic to reduce binary bloat (#503)
* refactor: Extract FramedWrite::buffer to a less generic function

Should cut out another 23 KiB (since I see it duplicated)

* refactor: Extract some duplicated code to a function

* refactor: Extract part of flush into a less generic function

* refactor: Extract a less generic part of connection

* refactor: Factor out a less generic part of Connection::poll2

* refactor: Extract a non-generic part of handshake2

* refactor: Don't duplicate Streams code on Peer (-3.5%)

The `P: Peer` parameter is rarely used and there is already a mechanism
for using it dynamically.

* refactor: Make recv_frame less generic (-2.3%)

* Move out part of Connection::poll

* refactor: Extract parts of Connection

* refactor: Extract a non-generic part of reclaim_frame

* comments
2021-02-18 11:17:49 -08:00
nickelc
9049e468c8 Remove the obsolent tracing-future dependency (#517) 2021-02-09 05:50:11 -08:00
Eliza Weisman
978c71270a add Connection::max_concurrent_send_streams (#513)
This PR adds accessors to `client::Connection` and `server::Connection`
that return the send stream concurrency limit on that connection, as
negotiated by the remote peer. This is part of issue #512.

I think we probably ought to expose similar accessors for other
settings, but I thought it was better to add each one in a separate,
focused PR.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-02-05 09:58:10 -08:00
Eliza Weisman
fc7f63f641 start adding tracing spans to internals (#478)
We've adopted `tracing` for diagnostics, but currently, it is just being
used as a drop-in replacement for the `log` crate. Ideally, we would
want to start emitting more structured diagnostics, using `tracing`'s
`Span`s and structured key-value fields.

A lot of the logging in `h2` is already written in a style that imitates
the formatting of structured key-value logs, but as textual log
messages. Migrating the logs to structured `tracing` events therefore is
pretty easy to do. I've also started adding spans, mostly in the read
path.

Finally, I've updated the tests to use `tracing` rather than
`env_logger`. The tracing setup happens in a macro, so that a span for
each test with the test's name can be generated and entered. This will
make the test output easier to read if multiple tests are run
concurrently with `--nocapture`.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2020-08-17 17:29:22 -07:00
David Barsky
d3b9f1e36a feat(lib): switch from log to tracing (#475) 2020-07-07 15:55:24 -07:00
Sean McArthur
ec751f3696 Remove Unpin requirement for the send Buf 2019-12-06 11:40:08 -08:00
Sean McArthur
881832cde9 Rename unstable-stream feature to stream (#433) 2019-12-03 10:38:50 -08:00
Sean McArthur
4398e169e8 Update to Tokio 0.2 (#428) 2019-11-27 14:53:57 -08:00
Sean McArthur
86e53054a6 Change ReserveCapacity to expanded FlowControl type (#423)
- Adds `FlowControl::available_capacity` method.
- Adds `FlowControl::used_capacity` method.
2019-10-08 11:28:15 -07:00
Sean McArthur
3cfcab016e Remove public Error constructor from io::Error (#420) 2019-10-07 15:29:38 -07:00
Sean McArthur
4c1d797712 Add ability to adjust INITIAL_WINDOW_SIZE setting on an existing connection (#421) 2019-10-07 15:29:23 -07:00
Sean McArthur
0527f5b72a Rename 'stream' feature to 'unstable-stream' 2019-09-12 12:44:44 -07:00
Sean McArthur
2d90efee17 Prune futures-* dependencies 2019-08-30 14:53:49 -07:00
Sean McArthur
678c90eb0a Update futures and tokio alphas 2019-08-29 15:44:26 -07:00
Gurwinder Singh
85b1f669c0 chore: async_await is stable on nightly 2019-08-21 11:10:03 -07:00
Sean McArthur
a1db5428db Make Stream impls part of optional 'stream' cargo feature (#397) 2019-08-20 16:01:03 -07:00
Gurwinder Singh
f46840f3fa chore: cargo fmt, clippy 2019-08-16 22:27:39 -07:00
Gurwinder Singh
b039ef25bc Make handshake an async fn; other cleanup 2019-08-16 18:47:47 -07:00
Gurwinder Singh
c8fefd49f1 Update lib to std-future 2019-08-16 18:47:47 -07:00
Jakub Beránek
db6b841e67 Update crate to Rust 2018 (#383) 2019-07-23 10:18:43 -07:00
Sean McArthur
19936721b8 Adjust client::Handshake's PhantomData since it doesn't own a buffer 2019-06-27 09:41:43 -07:00
Sean McArthur
e3a73f726e Add user PING support (#346)
- Add `share::PingPong`, which can send `Ping`s, and poll for the `Pong`
  from the peer.
2019-02-18 15:59:11 -08:00
Sean McArthur
8a0b7ff64f Loosen bounds on Handshake struct (#343) 2019-02-07 13:03:53 -08:00
Michael Beaumont
6b23542a55 Add client support for server push (#314)
This patch exposes push promises to the client API.

Closes #252
2018-10-16 12:51:08 -07:00
Eliza Weisman
00ca534c4a Update examples to use new Tokio (#316)
The old `tokio-core` crate is deprecated in favour of the `tokio` crate,
which also provides the new multithreaded Tokio runtime. Although `h2`
is generic over the runtime, the examples do depend on `tokio`. 

This branch update the example code to use the new `tokio` library
rather than `tokio-core`. It also updates the examples in `RustDoc`.

For the most part, this was pretty trivial --- simply replacing
`handle.spawn(...)` with `tokio::spawn(...)` and `core.run(...)` with
`tokio::run(...)`. There were a couple of cases where error and item
types from spawned futures had to be mapped to `(), ()`. Alternatively,
this could have been avoided by using the single-threaded runtime and
calling `block_on` instead to await the value of those futures, but I
thought it was better to reduce the amount of tokio-specific code in the
examples.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2018-09-25 14:33:49 -07:00
Sean McArthur
b0db515bdd fix some autolinks that weren't resolving in docs (#305) 2018-08-10 14:27:45 -07:00
Eliza Weisman
f3806d5144 Add stream_id accessors to public API types (#292)
Problem:

Applications may want to access the underlying h2 stream ID for
diagnostics, etc. Stream IDs were not previously exposed in public APIs.

Solution:

Added a new public `share::StreamId` type, which has a more restricted 
API than the internal `frame::StreamId` type. The public API types 
`SendStream`, `RecvStream`, `ReleaseCapacity`, 
`client::ResponseFuture`, and `server::SendResponse` now all have 
`stream_id` methods which return the stream ID of the corresponding 
stream.

Closes #289.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2018-07-12 21:01:57 -07:00
Geoffry Song
23234fa14f Promote SendRequest::pending to an OpaqueStreamRef. (#281)
Because `self.pending` doesn't necessarily get cleaned up in a timely fashion -
rather, only when the user calls `poll_ready()` - it was possible for it to
refer to a stream that has already been closed. This would lead to a panic the
next time that `poll_ready()` was called.

Instead, use an `OpaqueStreamRef`, bumping the refcount.

A change to an existing test is included which demonstrates the issue.
2018-06-06 10:16:22 -07:00
Oliver Gould
01d81b46c2 Add initial_connection_window_size to Builders (#249)
There is currently no way to configure the initial target window size
for connections. The `Builder::initial_connection_window_size` utilities
make this configurable so that all new connections have this target
window size set.
2018-03-28 14:46:56 -07:00
Darren Tsung
4595b54cfa Add initial_max_send_streams() as builder option (#242) 2018-03-16 11:58:06 -07:00
Carl Lerche
5d4c89b1a9 Fix client doc test (#241)
The test is not supposed to actually run, but the `select` is not fast
enough on Travis.
2018-03-13 14:53:35 -07:00
Darren Tsung
0c59957d88 When Streams are dropped, close Connection (#221) (#222)
When all Streams are dropped / finished, the Connection was held
open until the peer hangs up. Instead, the Connection should hang up
once it knows that nothing more will be sent.

To fix this, we notify the Connection when a stream is no longer
referenced. On the Connection poll(), we check that there are no
active, held, reset streams or any references to the Streams
and transition to sending a GOAWAY if that is case.

The specific behavior depends on if running as a client or server.
2018-02-15 13:14:18 -08:00
walfie
73b4c03b55 Fix typos (#223) 2018-02-13 21:00:09 -08:00
Steven Fackler
ef99f99ae1 Fix documentation for end_of_stream (#219)
The END_STREAM flag is set when the stream is ending, so it needs to be
false if we're sending data.
2018-01-25 11:58:41 -08:00
Carl Lerche
78455a4496 Add docs for shared types (#216)
Add documentation for types shared between the client and server.
2018-01-11 15:00:16 -08:00
Carl Lerche
5604372a8b Client documentation (#212)
Add documentation for client APIs.
2018-01-11 13:55:51 -08:00
Carl Lerche
1db3f34de8 Implement SendRequest::ready. (#215)
This provides a functional future API for waiting for SendRequest
readiness.
2018-01-11 10:21:23 -08:00
Sean McArthur
aa23a9735d SETTINGS_MAX_HEADER_LIST_SIZE (#206)
This, uh, grew into something far bigger than expected, but it turns out, all of it was needed to eventually support this correctly.

- Adds configuration to client and server to set [SETTINGS_MAX_HEADER_LIST_SIZE](http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE)
- If not set, a "sane default" of 16 MB is used (taken from golang's http2)
- Decoding header blocks now happens as they are received, instead of buffering up possibly forever until the last continuation frame is parsed.
- As each field is decoded, it's undecoded size is added to the total. Whenever a header block goes over the maximum size, the `frame` will be marked as such.
- Whenever a header block is deemed over max limit, decoding will still continue, but new fields will not be appended to `HeaderMap`. This is also can save wasted hashing.
- To protect against enormous string literals, such that they span multiple continuation frames, a check is made that the combined encoded bytes is less than the max allowed size. While technically not exactly what the spec suggests (counting decoded size instead), this should hopefully only happen when someone is indeed malicious. If found, a `GOAWAY` of `COMPRESSION_ERROR` is sent, and the connection shut down.
- After an oversize header block frame is finished decoding, the streams state machine will notice it is oversize, and handle that.
  - If the local peer is a server, a 431 response is sent, as suggested by the spec.
  - A `REFUSED_STREAM` reset is sent, since we cannot actually give the stream to the user.
- In order to be able to send both the 431 headers frame, and a reset frame afterwards, the scheduled `Canceled` machinery was made more general to a `Scheduled(Reason)` state instead.

Closes #18 
Closes #191
2018-01-05 09:23:48 -08:00
Carl Lerche
d0b5b6246a Misc renames (#202)
This patch renames a number of types and functions making
the API more consistent.

* `Server` -> `Connection`
* `Client` -> `SendRequest`
* `Respond` -> `SendResponse`.

It also moves the handshake fns off of `Connection` and make
them free fns in the module. And `Connection::builder` is removed
in favor of `Builder::new`.
2018-01-02 17:02:17 -08:00
Kenjiro Nakayama
ecf2e425b4 Add protocol version to response for client (#205) 2018-01-02 12:45:11 -08:00
Carl Lerche
1a0b1eec2b Start writing API docs (#187)
This focuses mostly on the server module.
2017-12-18 14:27:30 -08:00
Sean McArthur
1ea9a8fc7e ignore received frames on a stream locally reset for some time (#174)
- Adds config duration for how long to ignore frames on a reset stream
- Adds config for how many reset streams can be held at a time
2017-12-18 11:09:38 -08:00
Carl Lerche
a437d46bee Remove most struct level bounds on handshake types (#182) 2017-12-13 22:49:07 -06:00
Carl Lerche
9378846da8 Client should validate request URI. (#181)
This patch adds checks for the request URI and rejects invalid URIs. In
the case of forwarding an HTTP 1.1 request with a path, an "http" pseudo
header is added to satisfy the HTTP/2.0 spec.

Closes #179
2017-12-11 13:42:00 -06:00