libp2p / libp2p/specs

Proposal: provide error codes when closing connections and resetting streams

Open
#479 2 comments 7 reactions 1 assignee View on GitHub

@sukunrt is already working on this.

Since Jul 24, 2024.

  • #623 by @sukunrt — open
difficulty:moderate P1 - High
Dominant language
No language data
Stars
1.8k
Forks
320
Avg merge
11d 15h
Merged PRs (30d)
1

Description

### Related PRs
- [ ] #623 
- [ ] #622 

It would be really helpful to know why a peer closed a connection or reset a stream. Unfortunately, we currently don’t have access to that information.

Here’s a proposal how to convey that piece of information.

Connection Termination

Current situation:

  • QUIC: uses a CONNECTION_CLOSE frame, which carries a 62 bit error code and a human-readable message (a string limited by the MTU).
  • WebTransport: uses a CLOSE_WEBTRANSPORT_SESSION capsule, which carries a 32 bit error code and a human-readable message (up to 8k)
  • yamux: has a GOAWAY frame that abuses the length field (32 bit) to carry an error code. Currently the spec only defines 3 distinct error codes
  • mplex: don’t care

It seems straightforward to use a 32 bit error code space for libp2p. If we decide that transmitting an error message is important, we might be able to find a backwards-compatible yamux hack, similar to the one described in the next section.

We could have different error codes for: connections that are closed because they were dial-raced with other connections, disallowed by a connection gater, closed due to resource limitations, closed to make room for more valuable connections, closed for different kinds of protocol violations, etc.

Caveat: With TCP linger set to 0, the TCP connection is reset instead of properly closed. This also means that the error code might not be transmitted reliably.

Stream Termination

Current situation:

  • QUIC: the RESET_STREAM frames contains a 62 bit error code field (there are no human-readable messages for stream resets)
  • WebTransport: limits stream reset error codes to 8 bits
  • yamux: doesn’t allow transmitting any error code
  • mplex: still don’t care

It seems like we’re therefore limit to 256 error codes. We’d need to reserve a subset of these for libp2p itself (for example, we need to convey that multistream negotiation failed, or that we didn’t even start multistream negotiation because of resource limits, etc.). The rest of the error codes would be defined by the application.

yamux hack

Depending on how current implementations handle this, we could either:

  • if implementations ignore data sent on frames that have the RESET flag set: attach the error code to that frame
  • if implementations ignore stream data received on a stream that was set (I think go does): send the error code in a stream frame

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.