Repository navigation
fix(protocols): rebuilding a frame cut at the extension-chain bound warns once (#1619) - #1630
Merged
Merged
Conversation
…arns once (#1619) - Each layer from_data rebuilds parses its own octets again, and a layer constructed rather than parsed started at _exthdr_depth 0, so each rebuilt extension header counted its chain afresh: its parse went up to 32 headers past the cut, and warned again on reaching EXTENSION_HEADER_LIMIT. A cut frame rebuilt with 2 warnings over IPv6 and up to 33 over IPv4, not 1. - Internet._make_payload now hands the payload its place in the chain, one past this layer's, as #1620 hands it its place in the frame; a constructed IPv6_Ext takes it up, so the rebuild stops where the parse did. - _next_layer_class does not warn of the bound inside a payload being rebuilt, as _parse_next_layer does not of FRAME_LAYER_LIMIT: the layer being rebuilt warns once, from its own parse.
Owner
Author
|
Verdict: GOOD TO GO at Sonnet cross-review. It confirmed the cause: each rebuilt extension header restarted the chain count. It reproduced the fail-before (the new file fails with the fix reverted), and measured the IPv4 1,000-header rebuild at 155 ms → 76 ms, with 1,121 → 594 Non-blocking notes:
Not checked: ESP with a configured SA decrypting a chain of 33 or more headers, and the Sphinx build. I re-ran the new test file at this head: 5 passed, 119 subtests. |
Contributor
|
Coverage: 89.69% (unit tier, Python 3.14,
Per-file detail: the |
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.
Please follow the guide below
You will be asked some questions, please read them carefully and answer honestly
Put an
xinto all the boxes [ ] relevant to your pull request (like that [x])Use Preview tab to see how your pull request will actually look like
Searched for similar pull requests
Followed the coding style (
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeAdded a changelog entry under
docs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
Tick the commit type your subject line carries.
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseDescription of your pull request and other information
Closes #1619
from_datarebuilds parses its own octets again. A constructedInternetlayer started at_exthdr_depth = 0, so each rebuilt extension header counted its chain from itself, and each parse that reached the 32-header bound warned. A trace shows every nestedHOPOPTwarning with_rebuildingset.Internet._make_payload(internet.py:336) hands the payload its place in the chain, one past this layer's, through_exthdr_rebuilt(:64). This mirrors how fix(protocols): bound a frame's dissection at 64 layers (#1610) #1620 carries_frame_depth. A constructedIPv6_Exttakes that place (:261,:315)._next_layer_classskips the warning while_rebuildingis set (:409), as_parse_next_layeralready does for the frame bound.Ethernet.from_data(info.to_dict()). The cells are rebuild warnings, before → after; the parse gives 0 at 32 headers and 1 past that, both before and after:In the mixed case the 33rd header is also the 65th layer: 31 IPv4 tunnels under Ethernet, or 30 in a PCAP frame. Its rebuild warnings drop from 33 to 1 for both carriers. On the IPv4 frame with 1,000 headers, the rebuild ran +123 Python frames deeper than the parse, built 1,121
Internetlayers and took 155 ms. It now runs +2 deeper, builds 594 and takes 79 ms. Bytes and protocol chain are identical in every case.tests/protocols/internet/test_ext_chain_limit_rebuild_1619_unit.pyhas 48 subtest failures with the fix reverted, under both pytest and unittest, and passes with it. All 202 files undertests/protocols/, plus the fix(protocols): a chain of ~80+ IPv6 extension headers exhausts recursion and leaves the payload undissected #1604 engine and toolkit tests and the docstring and isort checks, pass one file at a time on 3.14. The chain-bound and frame-bound files also pass on 3.11.