Skip to content

Commit 196f49e

Browse files
committed
link to registry; reword the spec
1 parent 3060cd0 commit 196f49e

File tree

3 files changed

+68
-77
lines changed

3 files changed

+68
-77
lines changed

connections/README.md

+18-17
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,23 @@ and spec status.
2222
## Table of Contents
2323

2424
- [Connection Establishment in libp2p](#connection-establishment-in-libp2p)
25-
- [Table of Contents](#table-of-contents)
26-
- [Overview](#overview)
27-
- [Definitions](#definitions)
28-
- [Protocol Negotiation](#protocol-negotiation)
29-
- [multistream-select](#multistream-select)
30-
- [Upgrading Connections](#upgrading-connections)
31-
- [Opening New Streams Over a Connection](#opening-new-streams-over-a-connection)
32-
- [Practical Considerations](#practical-considerations)
33-
- [Interoperability](#interoperability)
34-
- [State Management](#state-management)
35-
- [Peer Metadata Storage](#peer-metadata-storage)
36-
- [Connection Limits](#connection-limits)
37-
- [Supported protocols](#supported-protocols)
38-
- [Connection Lifecycle Events](#connection-lifecycle-events)
39-
- [Hole punching](#hole-punching)
40-
- [Future Work](#future-work)
25+
- [Table of Contents](#table-of-contents)
26+
- [Overview](#overview)
27+
- [Definitions](#definitions)
28+
- [Protocol Negotiation](#protocol-negotiation)
29+
- [multistream-select](#multistream-select)
30+
- [Upgrading Connections](#upgrading-connections)
31+
- [Inlining Muxer Negotiation](#inlining-muxer-negotiation)
32+
- [Opening New Streams Over a Connection](#opening-new-streams-over-a-connection)
33+
- [Practical Considerations](#practical-considerations)
34+
- [Interoperability](#interoperability)
35+
- [State Management](#state-management)
36+
- [Peer Metadata Storage](#peer-metadata-storage)
37+
- [Connection Limits](#connection-limits)
38+
- [Supported protocols](#supported-protocols)
39+
- [Connection Lifecycle Events](#connection-lifecycle-events)
40+
- [Hole punching](#hole-punching)
41+
- [Future Work](#future-work)
4142

4243
## Overview
4344

@@ -181,7 +182,7 @@ If the peers agree on a protocol, multistream-select's job is done, and future
181182
traffic over the channel will adhere to the rules of the agreed-upon protocol.
182183

183184
If a peer receives a `"na"` response to a proposed protocol id, they can either
184-
try again with a different protocol id or close the channel.
185+
try again with a different protocol id or close the channel with error code `PROTOCOL_NEGOTIATION_FAILED` as defined in [libp2p error codes](./../error-codes/README.md) spec
185186

186187

187188
## Upgrading Connections

error-codes/README.md

+32-40
Original file line numberDiff line numberDiff line change
@@ -17,80 +17,69 @@ When closing a connection or resetting a stream, it's useful to provide the peer
1717
with a code that explains the reason for the closure. This enables the peer to
1818
better respond to the abrupt closures. For instance, it can implement a backoff
1919
strategy to retry _only_ when it receives a `RATE_LIMITED` error code. An error
20-
code doesn't always indicate an error condition. For example, a connection may
21-
be closed because a connection to the same peer over a better transport is
22-
available.
20+
code doesn't always indicate an error condition. For example, a node can terminate an idle connection, or close a connection because a connection to the same peer over a better transport is available. In both these cases, it can signal an appropriate error code to the other end.
2321

2422
## Semantics
2523
Error codes are unsigned 32-bit integers. The range 0 to 10000 is reserved for
2624
libp2p errors. Application specific errors can be defined by protocols from
27-
integers outside of this range. Implementations supporting error codes MUST
28-
provide the error code provided by the other end to the application.
29-
30-
Error codes provide a best effort guarantee that the error will be propagated to
31-
the application layer. This provides backwards compatibility with older nodes,
32-
allows smaller implementations, and using transports that don't provide a
33-
mechanism to provide an error code. For example, Yamux has no equivalent of
34-
QUIC's [STOP_SENDING](https://www.rfc-editor.org/rfc/rfc9000.html#section-3.5-4)
35-
frame that would tell the peer that the node has stopped reading. So there's no
36-
way of signaling an error while closing the read end of the stream on a yamux
37-
connection.
25+
integers outside of this range. Error Codes can be signaled on Closing a connection or on resetting a Stream.
26+
27+
From an application perspective, error codes provide a best effort guarantee. On resetting a libp2p stream or closing a connection with an error code, the error code may or may not be delivered to the application on the remote end. The specifics depend on the transport used. For example, WebTransport doesn't support error codes at all, while WebRTC doesn't support Connection Close error codes, but supports Stream Reset error codes.
3828

3929
### Connection Close and Stream Reset Error Codes
40-
Error codes are defined separately for Connection Close and Stream Reset. Stream
41-
Reset errors are from the range 0 to 5000 and Connection Close errors are from
42-
the range 5001 to 10000. Having separate errors for Connection Close and stream
43-
reset requires some overlap between the error code definitions but provides more
44-
information to the receiver. Receiving a `Bad Request: Connection Closed` error
45-
on reading from a stream also tells the receiver that no more streams can be
46-
started on the same connection. Implementations MUST provide the Connection
47-
Close error code on streams that are reset as a result of remote closing the
48-
connection.
49-
50-
For stream resets, when the underlying transport supports it, implementations
51-
SHOULD allow sending an error code on both closing the read side of the stream,
52-
and resetting the write side of the stream.
53-
54-
## Libp2p Reserved Error Codes
30+
Error codes are defined separately for Connection Close and Stream Reset. The namespace doesn't overlap as it is clear from the context whether the stream was reset by the other end, or it was reset as a result of a connection close.
31+
Implementations MUST provide the Connection Close error code on streams that are reset as a result of remote closing the connection.
32+
33+
Libp2p streams are reset unilaterally, calling `Reset` on a stream resets both the read and write end of a stream. For transports, like QUIC, which support cancelling the read and write ends of the stream separately, implementations MAY provide the ability to signal error codes separately on resetting either end.
34+
35+
## Error Codes Registry
36+
Libp2p connections are shared by multiple applications. The same connection used in the dht may be used for gossip sub, or for any other application. Any of these applications can close the underlying connection on an error, resetting streams used by the other applications. To correctly distinguish which application closed the connection, Connection Close error codes are allocated to applications from a central registry.
37+
38+
For simplicity, we manage both Connection Close and Stream Reset error codes from a central registry. The libp2p error codes registry is at: https://github.com/libp2p/error-codes/
39+
40+
### Libp2p Reserved Error Codes
41+
Error code 0 signals that no error code was provided. Implementations MUST handle closing a connection with error code 0 as they handle closing a connection with no error code, and resetting a stream with error code 0 as they handle resetting a stream with no error.
42+
43+
Error codes from 1 to 100 are reserved for transport errors. These are used by the transports to terminate connections on transport errors.
44+
45+
Error codes from 100 - 10000 are reserved for libp2p. This includes multistream error codes, as it is necessary for libp2p connection establishment over TCP, but not kad-dht or gossip-sub error codes.
46+
5547
see [Libp2p error codes](./libp2p-error-codes.md) for the libp2p reserved error
5648
codes.
5749

58-
## Wire Encoding
59-
Different transports will encode the 32-bit error code differently.
60-
50+
## Transport Specification and Wire Encoding
51+
Different transports will encode the 32-bit error code differently on the wire. They also provide different semantics: Webtransport doesn't define error codes, WebRTC doesn't support Connection Close error codes, Yamux error codes on Connection Close cannot be reliably sent over the wire.
52+
6153
### QUIC
6254
QUIC provides the ability to send an error on closing the read end of the
6355
stream, resetting the write end of the stream and on closing the connection.
6456

65-
For stream resets, the error code MUST be sent on the `RESET_STREAM` or the
66-
`STOP_SENDING` frame using the `Application Protocol Error Code` field as per
57+
For stream resets, the error code MUST be sent on `RESET_STREAM` and `STOP_SENDING` frames using the `Application Protocol Error Code` field as per
6758
the frame definitions in the
6859
[RFC](https://www.rfc-editor.org/rfc/rfc9000.html#name-reset_stream-frames).
6960

70-
For Connection Close, the error code MUST be sent on the CONNECTION_CLOSE frame
61+
For Connection Close, the error code MUST be sent on `CONNECTION_CLOSE` frame
7162
using the Error Code field as defined in the
7263
[RFC](https://www.rfc-editor.org/rfc/rfc9000.html#section-19.19-6.2.1).
7364

7465
### Yamux
75-
Yamux has no `STOP_SENDING` frame, so there's no way to signal an error on
76-
closing the read side of the stream.
66+
Yamux streams are reset unilaterally. Receiving a stream frame with `RST` flag set resets both the read and write end of the stream. So, there's no way to separately signal error code on closing the read end of the stream, or resetting the write end of the stream.
7767

7868
For Connection Close, the 32-bit Length field is interpreted as the error code.
7969

8070
For Stream Resets, the error code is sent in the `Window Update` frame, with the
8171
32-bit Length field interpreted as the error code. See [yamux spec
8272
extension](https://github.com/libp2p/specs/pull/622).
8373

84-
Note: On TCP connections with `SO_LINGER` set to 0, the Connection Close error
85-
code may not be delivered.
74+
Connection Close error code delivery to the other end depends on the OS TCP implementation and the TCP options used for the socket. In particular, when `SO_LINGER` TCP option is set to 0 and the implementation closes the connection immediately after writing the error code containing frame, the error code may not be delivered.
8675

8776
### WebRTC
8877
There is no way to provide any information on closing a peer connection in
8978
WebRTC. Providing error codes on Connection Close will be taken up in the
9079
future.
9180

9281
For Stream Resets, the error code can be sent in the `errorCode` field of the
93-
WebRTC message with `flag` set to `RESET_STREAM` .
82+
WebRTC message with `flag` set to `RESET_STREAM`.
9483

9584
### WebTransport
9685
Error codes for WebTransport will be introduced when browsers upgrade to draft-9
@@ -102,3 +91,6 @@ as the latest WebTransport draft,
10291
[draft-9](https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-02.html#section-4.3-2)
10392
allows for a 4-byte error code to be sent on stream resets, we will introduce
10493
error codes over WebTransport later.
94+
95+
### Multistream Select
96+
Multistream-Select is used to negotiate Security protocol for TCP connections before a stream muxer has been selected. There's only one error code defined for such cases, `PROTOCOL_NEGOTIATION_FAILED`. To encode this error, send the string `101` prefixed with the length and close the TCP connection.

error-codes/libp2p-error-codes.md

+18-20
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
# Libp2p error codes
22

3-
## TODO!
4-
make this a CSV
5-
63
## Connection Error Codes
7-
84
| Name | Code | Description |
95
| --- | --- | --- |
106
| NO_ERROR | 0 | No reason provided for disconnection. This is equivalent to closing a connection or resetting a stream without any error code. |
11-
| Reserved For Transport | 0x1 - 0x1000 | Reserved for transport level error codes. |
12-
| GATED | 0x1001 | The connection was gated. Most likely the IP / node is blacklisted. |
13-
| RESOURCE_LIMIT_EXCEEDED | 0x1002 | Rejected because we ran into a resource limit. Implementations MAY retry with a backoff |
14-
| RATE_LIMITED | 0x1003 | Rejected because the connection was rate limited. Implementations MAY retry with a backoff |
15-
| PROTOCOL_VIOLATION | 0x1004 | Peer violated the protocol |
16-
| SUPPLANTED | 0x1005 | Connection closed because a connection over a better tranpsort was available |
17-
| GARBAGE_COLLECTED | 0x1006 | Connection was garbage collected |
18-
| SHUTDOWN | 0x1007 | The node is going down |
19-
| PROTOCOL_NEGOTIATION_FAILED | 0x1008 | Rejected because we couldn't negotiate a protocol |
7+
| Reserved For Transport | 1 - 100 | Reserved for transport level error codes. |
8+
| PROTOCOL_NEGOTIATION_FAILED | 101 | Rejected because we couldn't negotiate a protocol. Used by multistream select for security negotiation |
9+
| RESOURCE_LIMIT_EXCEEDED | 102 | Rejected because we ran into a resource limit. Implementations MAY retry with a backoff |
10+
| RATE_LIMITED | 103 | Rejected because the connection was rate limited. Implementations MAY retry with a backoff |
11+
| PROTOCOL_VIOLATION | 104 | Peer violated the protocol |
12+
| SUPPLANTED | 105 | Connection closed because a connection over a better tranpsort was available |
13+
| GARBAGE_COLLECTED | 106 | Connection was garbage collected |
14+
| SHUTDOWN | 107 | The node is shutting down |
15+
| GATED | 108 | The connection was gated. Most likely the IP / node is blacklisted. |
2016

2117

2218
## Stream Error Codes
23-
2419
| Name | Code | Description |
2520
| --- | --- | --- |
2621
| NO_ERROR | 0 | No reason provided for disconnection. This is equivalent to resetting a stream without any error code. |
27-
| Reserved For Transport | 0x1 - 0x1000 | Reserved for transport level error codes. |
28-
| PROTOCOL_NEGOTIATION_FAILED | 0x1001 | Rejected because we couldn't negotiate a protocol |
29-
| RESOURCE_LIMIT_EXCEEDED | 0x1002 | Connection rejected because we ran into a resource limit. Implementations MAY retry with a backoff |
30-
| RATE_LIMITED | 0x1003 | Rejected because the connection was rate limited. Implementations MAY retry with a backoff |
31-
| BAD_REQUEST | 0x1004 | Rejected because the request was invalid |
32-
| PROTOCOL_VIOLATION | 0x1005 | Rejected because the stream protocol was violated. MAY be used interchangably with `BAD_REQUEST` |
22+
| Reserved For Transport | 1 - 100 | Reserved for transport level error codes. |
23+
| PROTOCOL_NEGOTIATION_FAILED | 101 | Rejected because we couldn't negotiate a protocol. Used by multistream select|
24+
| RESOURCE_LIMIT_EXCEEDED | 102 | Connection rejected because we ran into a resource limit. Implementations MAY retry with a backoff |
25+
| RATE_LIMITED | 103 | Rejected because the connection was rate limited. Implementations MAY retry with a backoff |
26+
| PROTOCOL_VIOLATION | 104 | Rejected because the stream protocol was violated. MAY be used interchangably with `BAD_REQUEST` |
27+
| SUPPLANTED | 105 | Resetted because a better transport is available for the stream |
28+
| GARBAGE_COLLECTED | 106 | Connection was garbage collected |
29+
| SHUTDOWN | 107 | The node is shutting down |
30+
| GATED | 108 | The stream was gated. Most likely the IP / node is blacklisted. |

0 commit comments

Comments
 (0)