Fix TCP IPv4 tx checksum length for padded RX frames#1332
Fix TCP IPv4 tx checksum length for padded RX frames#1332marcusb wants to merge 1 commit intoFreeRTOS:mainfrom
Conversation
AniruddhaKanhere
left a comment
There was a problem hiding this comment.
Thanks for the contribution, @marcusb. Good catch — confirmed the bug by comparing the IPv4 and IPv6 paths. The checksum was indeed being computed over the stale incoming xDataLength rather than the outgoing packet length.
The fix correctly mirrors prvTCPReturnPacket_IPV6() and the unit test is solid.
Tagging @htibosch for review.
LGTM — approving.
70312bd to
79f4693
Compare
79f4693 to
402c35a
Compare
|
It looks correct to me, but I want to make sure that things went really wrong with the existing release. One moment please. |
|
I found that the patch doesn't make much a difference: the protocol checksum doesn't change if you add more zeros to the packet. Why not move the following 2 lines to above: Or if you prefer, here in a patch: |
|
PS my patch applies to your branch |
prvTCPReturnPacket_IPV4() passed pxNetworkBuffer->xDataLength to usGenerateProtocolChecksum(), but at that point xDataLength still holds the length of the incoming frame (e.g. 60 bytes for a SYN padded to the Ethernet minimum) rather than the outgoing reply (typically 66 bytes for a SYNACK with options). The checksum was computed over the wrong byte range, yielding a bogus value. Add a unit test that installs a content-dependent stub for usGenerateProtocolChecksum and asserts the written checksum matches the sum over the outgoing packet length. Verified the test fails against the unfixed source and passes after the fix.
402c35a to
ecd52d1
Compare
|
@htibosch I applied your patch. The issue is that the received packet is still in the buffer under some circumstances, so it's not only zeros. This caused connections to fail in my project. |
As you may have seen, the driver sometimes allocates a new large buffer ( for sending data ), and it uses a static small buffer for simple messages like an ACK. Were you also able to test the change? |
|
@archigup @AniruddhaKanhere Can you please check this PR #1332? |
Summary
prvTCPReturnPacket_IPV4()calledusGenerateProtocolChecksum()withpxNetworkBuffer->xDataLengthas the buffer length. At that pointxDataLengthstill holds the length of the incoming frame — for example, 60 bytes for a SYN that was padded up to the Ethernet minimum. The reply (e.g. a SYNACK with TCP options) is typically longer, so the checksum ended up being computed over the wrong byte range.xDataLengthis only updated to the outgoing length a few lines later, atpxNetworkBuffer->xDataLength = ( size_t ) ulLen; pxNetworkBuffer->xDataLength += ipSIZE_OF_ETH_HEADER;.The IPv6 path (
prvTCPReturnPacket_IPV6()) was already correct — it usesulLen + ipSIZE_OF_ETH_HEADERdirectly. This change mirrors that in the IPv4 path.