diff options
author | 2023-10-13 17:47:05 -0700 | |
---|---|---|
committer | 2023-10-13 17:47:05 -0700 | |
commit | 77d7e47019753bacc76306dd9066df25c67c51a9 (patch) | |
tree | 40f4b058deb09ffe39f35f06f198f94e98605874 | |
parent | 1bad64bc5e6fc2757a99dc7529d11c86835300bb (diff) | |
download | bun-77d7e47019753bacc76306dd9066df25c67c51a9.tar.gz bun-77d7e47019753bacc76306dd9066df25c67c51a9.tar.zst bun-77d7e47019753bacc76306dd9066df25c67c51a9.zip |
Fix dns.lookup returning wrong address for family (#6474)
* Fix #6452
* Fix formatting
-rw-r--r-- | src/bun.js/api/bun/dns_resolver.zig | 7 | ||||
-rw-r--r-- | test/js/bun/dns/resolve-dns.test.ts | 126 |
2 files changed, 90 insertions, 43 deletions
diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig index 873cdcddc..3c20f4df7 100644 --- a/src/bun.js/api/bun/dns_resolver.zig +++ b/src/bun.js/api/bun/dns_resolver.zig @@ -102,11 +102,12 @@ const LibInfo = struct { ) catch unreachable; const promise_value = request.head.promise.value(); + const hints = query.options.toLibC(); const errno = getaddrinfo_async_start_( &request.backend.libinfo.machport, name_z.ptr, null, - null, + if (hints != null) &hints.? else null, GetAddrInfoRequest.getAddrInfoAsyncCallback, request, ); @@ -2475,7 +2476,7 @@ pub const DNSResolver = struct { return dns_lookup.promise.value(); } - // var hints_buf = &[_]c_ares.AddrInfo_hints{query.toCAres()}; + var hints_buf = &[_]c_ares.AddrInfo_hints{query.toCAres()}; var request = GetAddrInfoRequest.init( cache, .{ @@ -2491,7 +2492,7 @@ pub const DNSResolver = struct { channel.getAddrInfo( query.name, query.port, - &.{}, + hints_buf, GetAddrInfoRequest, request, GetAddrInfoRequest.onCaresComplete, diff --git a/test/js/bun/dns/resolve-dns.test.ts b/test/js/bun/dns/resolve-dns.test.ts index 6102b0745..57b3a50c7 100644 --- a/test/js/bun/dns/resolve-dns.test.ts +++ b/test/js/bun/dns/resolve-dns.test.ts @@ -1,50 +1,96 @@ import { dns } from "bun"; import { describe, expect, it, test } from "bun:test"; import { withoutAggressiveGC } from "harness"; +import { isIP, isIPv4, isIPv6 } from "node:net"; -describe("dns.lookup", () => { - const backends = [process.platform === "darwin" ? "system" : undefined, "libc", "c-ares"].filter(x => !!x) as ( - | "system" - | "libc" - | "c-ares" - )[]; - for (let backend of backends) { - it(backend + " parallell x 10", async () => { - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(dns.lookup("localhost", { backend })); - } - const results = (await Promise.all(promises)).flat(); - withoutAggressiveGC(() => { - for (let { family, address } of results) { - if (family === 4) { - expect(address).toBe("127.0.0.1"); - } else if (family === 6) { - expect(address).toBe("::1"); - } else { - throw new Error("Unknown family"); +const backends = ["system", "libc", "c-ares"]; +const validHostnames = ["localhost", "example.com"]; +const invalidHostnames = [`this-should-not-exist-${Math.floor(Math.random() * 99999)}.com`]; +const malformedHostnames = ["", " ", ".", " .", "localhost:80", "this is not a hostname"]; + +describe("dns", () => { + describe.each(backends)("lookup() [backend: %s]", backend => { + describe.each(validHostnames)("%s", hostname => { + test.each([ + { + options: { backend }, + address: isIP, + }, + { + options: { backend, family: 4 }, + address: isIPv4, + family: 4, + }, + { + options: { backend, family: "IPv4" }, + address: isIPv4, + family: 4, + }, + { + options: { backend, family: 6 }, + address: isIPv6, + family: 6, + }, + { + options: { backend, family: "IPv6" }, + address: isIPv6, + family: 6, + }, + { + options: { backend, family: 0 }, + address: isIP, + }, + { + options: { backend, family: "any" }, + address: isIP, + }, + ])("%j", async ({ options, address: expectedAddress, family: expectedFamily }) => { + // @ts-expect-error + const result = await dns.lookup(hostname, options); + expect(result).toBeArray(); + expect(result.length).toBeGreaterThan(0); + withoutAggressiveGC(() => { + for (const { family, address, ttl } of result) { + expect(address).toBeString(); + expect(expectedAddress(address)).toBeTruthy(); + expect(family).toBeInteger(); + if (expectedFamily !== undefined) { + expect(family).toBe(expectedFamily); + } + expect(ttl).toBeInteger(); } - } + }); }); }); - - it(backend + " remote", async () => { - const [first, second] = await dns.lookup("google.com", { backend }); - console.log(first, second); - }); - it(backend + " local", async () => { - const [first, second] = await dns.lookup("localhost", { backend }); - console.log(first, second); + test.each(validHostnames)("%s [parallel x 10]", async hostname => { + const results = await Promise.all( + // @ts-expect-error + Array.from({ length: 10 }, () => dns.lookup(hostname, { backend })), + ); + const answers = results.flat(); + expect(answers).toBeArray(); + expect(answers.length).toBeGreaterThan(10); + withoutAggressiveGC(() => { + for (const { family, address, ttl } of answers) { + expect(address).toBeString(); + expect(isIP(address)).toBeTruthy(); + expect(family).toBeInteger(); + expect(ttl).toBeInteger(); + } + }); }); - - it(backend + " failing domain throws an error without taking a very long time", async () => { - try { - await dns.lookup("yololololololo1234567.com", { backend }); - throw 42; - } catch (e: any) { - expect(typeof e).not.toBe("number"); - expect(e.code).toBe("DNS_ENOTFOUND"); - } + test.each(invalidHostnames)("%s", hostname => { + // @ts-expect-error + expect(dns.lookup(hostname, { backend })).rejects.toMatchObject({ + code: "DNS_ENOTFOUND", + }); }); - } + // TODO: causes segfaults + // test.each(malformedHostnames)("%s", (hostname) => { + // // @ts-expect-error + // expect(dns.lookup(hostname, { backend })).rejects.toMatchObject({ + // code: "DNS_ENOTFOUND", + // }); + // }); + }); }); |