Repository navigation
Conversation
With protocol v5 framing, _process_segment_buffer() returned without rewinding the io buffer when fewer than 6 bytes (one segment header plus its CRC24) had arrived. process_io_buffer() then called reset_io_buffer(), which keeps only the bytes after the current position, and the position was at the end, so those 1-5 header bytes were dropped. The next read was parsed from the wrong offset and the connection was defuncted with "CRC mismatch on header". Rewind in that branch too, like the "header but incomplete payload" branch already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With protocol v5, a read that ends 1-5 bytes into a segment header loses those bytes, and the connection is then defuncted with
CRC mismatch on header.Connection._process_segment_buffer()has three cases:seek(0)and wait for more.process_io_buffer()then callsreset_io_buffer(), which keeps only the bytes after the current position. In case 3 the position is at the end, so the partial header is discarded. The next read is parsed from the wrong offset and its header fails the CRC24 check:This PR adds the missing
seek(0)to case 3.It needs a socket read to end inside a header, so it's rare. It's more likely with the asyncio reactor, which processes the buffer after every 4 KB read. We hit it in CI against Cassandra 5.0 with asyncio, during a large schema refresh, while running the integration tests of the ScyllaDB fork of this driver, which has the same code (scylladb#1141).
Test: the new unit test
test_v5_segment_header_split_across_readsfeeds two segments split at every offset from 0 to 7 bytes into the second header. On trunk, offsets 1-5 fail. With the fix, all pass, andtests/unit/test_connection.pyandtests/unit/test_segment.pypass.🤖 Generated with Claude Code