Skip to content

RFC Verification/Hardening#108

Open
zanbaldwin wants to merge 3 commits into
6.xfrom
z/rfc-hardening
Open

RFC Verification/Hardening#108
zanbaldwin wants to merge 3 commits into
6.xfrom
z/rfc-hardening

Conversation

@zanbaldwin
Copy link
Copy Markdown
Member

No description provided.

@zanbaldwin zanbaldwin self-assigned this Jun 4, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 5, 2026

Greptile Summary

This PR aligns isPublicUse(), isDocumentation(), and isUnicastGlobal() with the current IANA special-purpose address registries, adding missing address blocks and correcting RFC citation references throughout the interface and implementation files.

  • IPv4: Adds 233.252.0.0/24 (MCAST-TEST-NET) to isDocumentation(), carves out 192.88.99.2/32 (6a44 relay anycast) and the 0.0.0.0/8 block from isPublicUse(), and explicitly excludes 255.255.255.255 from isFutureReserved().
  • IPv6: Extends isDocumentation() with 3fff::/20 (RFC 9637), and rewrites isUnicastGlobal() with a full set of exclusions (IPv4-mapped, 6to4/derived, IETF Protocol Assignments 2001::/23 with per-RFC carve-outs, NAT64 local-use, discard-only, dummy prefix, and Segment Routing SID blocks).
  • Docs/tests: Updates PHPDoc RFC citations across the interface, fixes a copy-paste error in the IANA IPv6 registry URL, and adjusts test-data flags to reflect the corrected classifications.

Confidence Score: 4/5

Safe to merge for the classification correctness improvements; the new exclusions are well-sourced from IANA and all hex constants verified correctly. The main gap is that several newly excluded IPv4 and IPv6 blocks have no test entries, and the known-incomplete isDerived() detection is now load-bearing in the public-use check.

The implementation is well-researched and the IANA registry alignment is accurate. The concerns are about test coverage gaps and an acknowledged limitation in isDerived() that is now silently affecting isPublicUse() results for non-canonical 6to4 addresses — previously that gap was inconsequential, but this PR makes it observable to callers.

src/Version/IPv6.php (new isUnicastGlobal() chain, especially the TODO on isDerived()), tests/DataProvider/IPv4.php and tests/DataProvider/IPv6.php (missing test entries for the newly introduced address blocks).

Important Files Changed

Filename Overview
src/Version/IPv6.php Major expansion of isUnicastGlobal() with seven new private helper methods and careful IANA registry alignment; hex constants verified correct, but new blocks (isDiscardOnly, isDummyPrefix, isNat64LocalUse, isSegmentRoutingSid) have no entries in the categorized test provider.
src/Version/IPv4.php Adds MCAST-TEST-NET (233.252.0.0/24) to isDocumentation() and the 6a44 anycast address (192.88.99.2) to isPublicUse() exclusions; neither new case has a test entry in the IPv4 data provider.
tests/DataProvider/IPv6.php Correctly updates flags for mapped, derived, and benchmarking addresses to reflect the new not-globally-reachable classifications; no new test entries added for the seven new exclusion blocks.
src/IpInterface.php PHPDoc RFC citations updated and the IPv6 IANA registry URL corrected (was using the IPv4 path segment).
src/Version/Version4Interface.php Minor doc improvements: added section references to RFC 919 and RFC 1112, and clarified the isFutureReserved() broadcast exclusion.
src/Version/Version6Interface.php Adds a comment clarifying that multicast scope constants are per RFC 7346, and updates isUnicastGlobal() docblock RFC reference.
CHANGELOG.md Changelog entry added for the isPublicUse() and isDocumentation() alignment with IANA registries.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["isPublicUse() IPv6"] --> B["isUnicastGlobal() OR\nmulticast global scope"]
    B --> C{isUnicast?}
    C -- No --> Z["false"]
    C -- Yes --> D{isLoopback / isLinkLocal /\nisUniqueLocal / isUnspecified?}
    D -- Yes --> Z
    D -- No --> E{isMapped\n::ffff:0:0/96}
    E -- Yes --> Z
    E -- No --> F{isDocumentation\n2001:db8::/32\n3fff::/20 NEW}
    F -- Yes --> Z
    F -- No --> G{isBenchmarking\n2001:2::/48}
    G -- Yes --> Z
    G -- No --> H{isIetfProtocolAssignment\n2001::/23 minus carve-outs NEW}
    H -- Yes --> Z
    H -- No --> I{isDerived\n2002::/16 ⚠️ TODO}
    I -- Yes --> Z
    I -- No --> J{isNat64LocalUse\n64:ff9b:1::/48 NEW}
    J -- Yes --> Z
    J -- No --> K{isDiscardOnly\n100::/64 NEW}
    K -- Yes --> Z
    K -- No --> L{isDummyPrefix\n100:0:0:1::/64 NEW}
    L -- Yes --> Z
    L -- No --> M{isSegmentRoutingSid\n5f00::/16 NEW}
    M -- Yes --> Z
    M -- No --> Y["true (globally reachable)"]
Loading

Comments Outside Diff (1)

  1. tests/DataProvider/IPv6.php, line 265-315 (link)

    P2 No test entries for the four new IPv6 exclusion blocks

    isDiscardOnly() (100::/64), isDummyPrefix() (100:0:0:1::/64), isNat64LocalUse() (64:ff9b:1::/48), and isSegmentRoutingSid() (5f00::/16) are all private methods that feed into isUnicastGlobal(), but getCategorizedIpAddresses() has no entries in any of those ranges. Without at least one positive example per block flagged as self::UNICAST_OTHER (not PUBLIC_USE_V6 | UNICAST_GLOBAL), the data-driven tests that drive getUnicastGlobalIpAddresses() and getPublicUseIpAddresses() never exercise the new exclusions.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "docs: 📚 update CHANGELOG" | Re-trigger Greptile

Comment thread src/Version/IPv6.php
Comment on lines +161 to +167
// The IANA special-purpose registry lists the 6to4 (derived) block
// `2002::/16` (RFC 3056) with a globally-reachable value of "N/A"
// rather than "true"; when in doubt, do what the Rust standard
// library does.
// TODO: This is broken until the Derived strategy detects
// non-canonical, "lossy" addresses.
&& !$this->isDerived()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Known-broken isDerived() detection is now load-bearing in isUnicastGlobal()

The TODO acknowledges that isDerived() fails to exclude "non-canonical, lossy" 6to4 addresses. Before this PR, isDerived() was not checked in isUnicastGlobal(), so that deficiency was invisible to callers of isPublicUse(). Now that !$this->isDerived() gates global-reachability, any 6to4 address that isDerived() misclassifies will silently pass through as publicly routable. It would be worth either fixing the detection in isDerived() first, or at least adding a note in the isPublicUse() docblock (and the public isDerived() docblock) warning that the 6to4 exclusion is incomplete.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove TODO comment once #110 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant