Commit 891ca6d
authored
crypto/noise: Improve stability of websockets by fixing AsyncWrite implementation (#518)
The PR fixes a `AsyncWrite::poll_write` implementation of the
crypto/noise sockets that causes panics in rust-yamux and leads to
unnecessary connection closure and instability:
- T0: poll_write is called with buffer of len 512 bytes
- the implementation encrypt data and buffers it
- because the io socket is not ready, poll pending is returned.
- T1: tokio_tungstenite (or other component) decides that a new payload
must be sent (usually a PONG frame) of len 12 bytes
- because the inner buffers contain the previous message, upon flushing
the size of the older message is returned (ie 512)
- rust-yamux uses the 512 bytes to index a buffer of 12 bytes (as
expected by the second poll_write with buffer 12)
- This caused frequent panics on the websocket implementation, which is
currently addressed as abrupt connection termination
This PR fixes the `AsyncWrite` contract violation by effectively
decoupling the encryption from the writing steps.
- the inner buffers are drained as much as possible (until the socket
returns poll pending)
- The provided message is encrypted into the inner buffer if it has
capacity and the number of bytes is returned immediately
- a subsequent poll_write or poll_flush or poll_close will propagate the
encrypted buffered data to the underlying socket
Previous fixes:
- libp2p/rust-yamux#202
- libp2p/rust-yamux#211
The fixes are still needed since the tokio-tungstenite (websocket crate)
was not properly scoped and may exhibit similar behavior.
cc @paritytech/networking
---------
Signed-off-by: Alexandru Vasile <[email protected]>1 parent 0d2d1bd commit 891ca6d
1 file changed
+298
-83
lines changed
0 commit comments