frame: fix UDP datagram boundary recovery after parse errors#246
Open
gavrilaf wants to merge 1 commit intobluenviron:mainfrom
Open
frame: fix UDP datagram boundary recovery after parse errors#246gavrilaf wants to merge 1 commit intobluenviron:mainfrom
gavrilaf wants to merge 1 commit intobluenviron:mainfrom
Conversation
On a packet-oriented transport (UDP), a single malformed datagram used to produce dozens of spurious "invalid magic byte" errors because bufio scanned the bad datagram byte-by-byte looking for the next magic byte. Add EndpointUDPClientPacket: identical to EndpointUDPClient but marks the channel as PacketOriented. After any ReadError, DiscardBuffered() drops all bytes still buffered from the current datagram so the next Read() begins on a fresh UDP packet boundary. Key changes: - pkg/frame: Reader.DiscardBuffered() discards remaining buffered bytes - pkg/frame: ReadWriter uses a 65536-byte buffer in PacketOriented mode so a single bufio fill always covers exactly one datagram - pkg/frame/v2_frame: unmarshal header with Peek+Discard instead of peekAndDiscard so an incompatibility-flag error leaves the header bytes in the buffer for DiscardBuffered to clean up - channel: call DiscardBuffered on ReadError when PacketOriented - channel_provider: detect packetOrientedEndpoint and set the flag - endpoint_udp_client_packet: new EndpointUDPClientPacket type
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.
Problem
When using
EndpointUDPClientover a real UDP link (e.g. a radio-link tunnel), a single malformed or out-of-order datagram produces dozens of spuriousparse error invalid magic byteerrors:The root cause:
bufio.Readertreats the UDP connection as a byte stream. After a parse error it continues scanning byte-by-byte inside the same datagram, generating one error per remaining byte. The next datagram then starts mid-buffer, corrupting further frames.This does not affect TCP or serial endpoints because those are true byte streams where byte-by-byte scanning is the correct recovery strategy.
Solution
Add
EndpointUDPClientPacket— identical toEndpointUDPClientbut marks the channel as packet-oriented. After anyReadError,DiscardBuffered()drops all bytes still buffered from the current datagram so the nextRead()begins on a fresh UDP packet boundary.One bad datagram → exactly one
EventParseError→ normal parsing resumes.Changes
pkg/frame: addReader.DiscardBuffered()to flush the bufio bufferpkg/frame:ReadWriterallocates a 65536-byte buffer in packet-oriented mode so one bufio fill always covers exactly one datagrampkg/frame/v2_frame: unmarshal header withPeek+Discardinstead ofpeekAndDiscardso an incompatibility-flag error leaves header bytes in the buffer forDiscardBufferedto clean upchannel: callDiscardBuffered()onReadErrorwhenPacketOrientedchannel_provider: detectpacketOrientedEndpointinterface and set the flagendpoint_udp_client_packet: newEndpointUDPClientPacketendpoint typeTests
TestEndpointUDPClientPacketRecoverAfterMalformedDatagrams: sends 2 junk datagrams followed by a valid one — verifies exactly 2EventParseErrorevents and correct frame received afterTestEndpointUDPClientRecoverAfterMalformedDatagram: existing-style test inendpoint_client_test.goTestReaderRecoverAfterInvalidV2IncompatibilityFlag: unit test for thePeek+Discardheader change