Repository navigation
Conversation
…ssRestricted A hostname made ipaddr.process() throw on every request (~7 us for the stack trace), and an IPv4 address threw once per IPv6 range in the policy. Return early for hosts that cannot be an IP literal, and remember verdicts per host string on networkOptions.restrictedVerdicts (bounded at 1,000 entries). Verdicts are unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project check has failed because the head coverage (34.15%) is below the target coverage (35.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## develop #1571 +/- ##
===========================================
+ Coverage 77.61% 77.67% +0.05%
===========================================
Files 51 51
Lines 4361 4371 +10
Branches 1234 1238 +4
===========================================
+ Hits 3385 3395 +10
Misses 732 732
Partials 244 244
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Kart03
marked this pull request as ready for review
October 23, 2026 07:18
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.
Context
AUTO-1063: per-VU throughput of our cloud performance runs dropped after the restricted-address policy was turned on (#1548 added CIDR support; the performance library started passing a 19-entry policy). On a 100 ms endpoint at 25,000 VUs it costs about 6.4% per-VU throughput, and 7.4% on a 50 ms endpoint. A slow endpoint (1,000 ms) shows no difference.
isAddressRestrictedruns on every request for the URL's hostname (requester.js:434), and again on each newly resolved address inside the DNS lookup override (core.js:309,core.js:322). I measured each call separately on our load workers: switching off only the hostname check recovers 6.0 of the 6.4 points; switching off only the resolved-address check changes nothing measurable (it runs once per new connection, and connections are kept alive).The cost is
ipaddr.jsthrowing:ipaddr.process()throws "neither IPv6 nor IPv4 format", and the catch at the bottom of the function turns that intofalse. Building the error (stack trace) is about 7 µs, on every request.addr.match()throws on each IPv6 range in the policy ("cannot match ipv4 address with non-ipv4 one"). With 3 IPv6 ranges a public IPv4 throws 3 times, about 9.4 µs per call.Summary of the change
All inside
isAddressRestrictedinlib/requester/core.js. The policy, the call sites, the DNS-time check and the redirect check are unchanged.:and a character outside[0-9a-fx.]returnsfalsewithout parsing. Every IPv4 formipaddr.js2.x accepts (dotted decimal, octal,0xhex, short and single-number forms) uses only those characters, and every IPv6 literal contains:, so such a host can never match a CIDR entry; the parse would only throw. It stays after the exact-match block so listed names likelocalhostare still blocked. Anything IP-shaped (0x7f.0.0.1,2130706433,fe80::1%eth0) still takes the full path, which matters because Node never calls the lookup hook for numeric hosts, so the hostname check is the only guard there.networkOptions.restrictedVerdicts(aMap, cleared when it reaches 1,000 entries). This relies on the same assumption the function already makes forrestrictedCidrs:restrictedAddressesdoes not change after the first call. The cache is keyed by the exact string checked, never by where a name resolves to, so when DNS starts returning a different address for a name, the resolved-address check sees the new address string and checks it on its own (there is a test for this).Breaking changes
None for callers. Verdicts are identical for every input in the new and existing tests.
networkOptionsgains arestrictedVerdictsproperty, written lazily likerestrictedCidrs. An embedder that buildsnetworkOptionsfrom untrusted input should not let that input setrestrictedVerdicts(the same applies torestrictedCidrstoday); the performance library strips both, and I'll make that explicit in its own PR.Dependencies
None.
Test plan
New unit tests in
test/unit/requester-core.test.js(hostname pre-check and verdict cache):localhost).ipaddr.process(spy). IP-shaped strings always do.networkOptionsdoes not parse again.Suites:
node npm/test-unit.js582 passing, 10 pending, 0 failing.node npm/test-integration.js1,915 passing, 33 pending, 0 failing (includestest/integration/sanity/restricted-addresses.test.js). ESLint clean on both files.Microbenchmark (one call, 19-entry policy, Node 24, same verdict before and after):
Load test (our load workers, a performance library build that vendors this branch):
Per-VU requests/second, 100 ms and 50 ms endpoints, fixed profile, 5 min, one worker image with only this change versus the same image without it. 0% errors in every run.
Graviton (c6g), 25,000 VUs. Workers peak at 92-94% CPU:
AMD (c8a). Workers peak at 74-78% CPU, so there is less to win:
On c6g the fix lands within 0.6% of running with the policy switched off. At 100,000 VUs I compare total requests, because the reported requests/second uses a measurement window that varied between 284 s and 301 s.
Additional notes
develop.Generated with Claude Code