Skip to content

Commit fdea545

Browse files
committed
fix: allow guarded fetch IPv6 fallback
1 parent 198e3b3 commit fdea545

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

src/infra/net/ssrf.pinning.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe("ssrf pinning", () => {
5151
);
5252
});
5353

54-
it("keeps automatic pinned lookups on IPv4 when both address families are available", async () => {
54+
it("keeps single-address lookups on IPv4 while exposing both families to Happy Eyeballs", async () => {
5555
const lookup = createPinnedLookup({
5656
hostname: "api.anthropic.com",
5757
addresses: ["160.79.104.10", "2607:6bc0::10"],
@@ -89,7 +89,10 @@ describe("ssrf pinning", () => {
8989
}
9090
});
9191
});
92-
expect(all).toEqual([{ address: "160.79.104.10", family: 4 }]);
92+
expect(all).toEqual([
93+
{ address: "160.79.104.10", family: 4 },
94+
{ address: "2607:6bc0::10", family: 6 },
95+
]);
9396

9497
await expect(lookupWithOptions({ family: 6 })).resolves.toEqual({
9598
address: "2607:6bc0::10",

src/infra/net/ssrf.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,14 @@ export function createPinnedLookup(params: {
524524
: {};
525525
const requestedFamily =
526526
typeof options === "number" ? options : typeof opts.family === "number" ? opts.family : 0;
527+
// Single-address lookups stay IPv4-only when possible, while Happy Eyeballs
528+
// receives every validated family so it can fall back when IPv4 is unreachable.
527529
const candidates =
528530
requestedFamily === 4 || requestedFamily === 6
529531
? records.filter((entry) => entry.family === requestedFamily)
530-
: automaticRecords;
532+
: opts.all
533+
? records
534+
: automaticRecords;
531535
const usable = candidates.length > 0 ? candidates : automaticRecords;
532536
if (opts.all) {
533537
cb(null, usable as LookupAddress[]);

0 commit comments

Comments
 (0)