godotengine / godotengine/godot
StreamPeerTLS randomly disconnects when pulling 0 bytes in get_partial_data
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
4.3
### System information
Windows 10 - Godot 4.3 Stable (Same behavior on Linux, same behavior when changing wifi)
### Issue description
I am really not sure if what I encountered is the expected behavior or if I'm mis-using TLS, but here's something I noticed:
When invoking get_partial_data(available_bytes) on a StreamPeerTLS with a backing TCP stream and there's really no data available, my peer would suddenly disconnect.
If I pulled only when get_available_bytes() returns a byte count larger than 0, this disconnect does not happen and the connection is stable.
The connection is also stable if I only use StreamPeerTCP without tls.
### Steps to reproduce
Create a StreamPeerTLS with a backing StreamPeerTCP and connect both to a TLS server
Continue to pull data
If no data is available, proceed to call get_partial_data(bytes) anyway. (In my case with the number of available bytes, which was 0)
further interactions with your StreamPeerTLS will suddenly return error code 27 (ERR_CONNECTION_ERROR). I can't tell if this happens immediately or only after some time has passed, though.
### Minimal reproduction project (MRP)
N/A really. But I noticed this behavior while devving on my client library so here's what i can share:
Heres' the old (tls randomly disconnects) version: https://github.com/arnemileswinter/rabbitgd/blob/1255ccb34db3cb961383324e7974ba2873f5149e/addons/rabbit-gd/RMQClient.gd#L124
And here it is with my latest fix which yields a stable connection now: https://github.com/arnemileswinter/rabbitgd/blob/0edc9ccbe2dbb38530d96cb58afa2f1a0faf4da5/addons/rabbit-gd/RMQClient.gd#L124
Here's the relevant diff of what i've done to circumvent the behavior: https://github.com/arnemileswinter/rabbitgd/commit/70b84af48b0e45a7108e564edc2b993e7a66166c#diff-57d035684cfdc886e3620113ac0513315c66fc3e70c501bfb9b0bd291bc254bfR124
Contributor guide
Research direction
Start with the StreamPeerTLS.get_partial_data() and get_available_bytes() behavior described here, using the linked RMQClient.gd versions to reproduce the zero-byte read case. Trace the backing StreamPeerTCP/TLS interaction and error code 27, then check whether a focused regression test can demonstrate the disconnect; done means zero-byte reads no longer unexpectedly terminate a valid TLS connection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100