Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up some DNS code #10718

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
169 changes: 84 additions & 85 deletions src/bun.js/api/bun/dns_resolver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Async = bun.Async;
const GetAddrInfoAsyncCallback = fn (i32, ?*std.c.addrinfo, ?*anyopaque) callconv(.C) void;
const INET6_ADDRSTRLEN = if (bun.Environment.isWindows) 65 else 46;
const IANA_DNS_PORT = 53;

const String = bun.String;
const LibInfo = struct {
// static int32_t (*getaddrinfo_async_start)(mach_port_t*,
// const char*,
Expand Down Expand Up @@ -259,39 +259,38 @@ const LibUVBackend = struct {
};

pub fn addressToString(
allocator: std.mem.Allocator,
address: std.net.Address,
) JSC.ZigString {
const str: []const u8 = brk: {
switch (address.any.family) {
std.os.AF.INET => {
var self = address.in;
const bytes = @as(*const [4]u8, @ptrCast(&self.sa.addr));
break :brk std.fmt.allocPrint(allocator, "{}.{}.{}.{}", .{
bytes[0],
bytes[1],
bytes[2],
bytes[3],
}) catch unreachable;
},
std.os.AF.INET6 => {
var out = std.fmt.allocPrint(allocator, "{any}", .{address}) catch unreachable;
// TODO: this is a hack, fix it
// This removes [.*]:port
// ^ ^^^^^^
break :brk out[1 .. out.len - 1 - std.fmt.count("{d}", .{address.in6.getPort()}) - 1];
},
std.os.AF.UNIX => {
if (comptime std.net.has_unix_sockets) {
break :brk std.mem.sliceTo(&address.un.path, 0);
}
break :brk "";
},
else => break :brk "",
}
};
address: *const std.net.Address,
) !bun.String {
switch (address.any.family) {
std.os.AF.INET => {
var self = address.in;
const bytes = @as(*const [4]u8, @ptrCast(&self.sa.addr));
return String.createFormat("{}.{}.{}.{}", .{
bytes[0],
bytes[1],
bytes[2],
bytes[3],
});
},
std.os.AF.INET6 => {
var stack = std.heap.stackFallback(512, default_allocator);
const allocator = stack.get();
var out = try std.fmt.allocPrint(allocator, "{any}", .{address.*});
defer allocator.free(out);
// TODO: this is a hack, fix it
// This removes [.*]:port
// ^ ^^^^^^
return String.createLatin1(out[1 .. out.len - 1 - std.fmt.count("{d}", .{address.in6.getPort()}) - 1]);
},
std.os.AF.UNIX => {
if (comptime std.net.has_unix_sockets) {
return String.createLatin1(&address.un.path);
}

return JSC.ZigString.init(str);
return String.empty;
},
else => return String.empty,
}
}

pub fn normalizeDNSName(name: []const u8, backend: *GetAddrInfo.Backend) []const u8 {
Expand All @@ -312,11 +311,15 @@ pub fn normalizeDNSName(name: []const u8, backend: *GetAddrInfo.Backend) []const
}

pub fn addressToJS(
allocator: std.mem.Allocator,
address: std.net.Address,
address: *const std.net.Address,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return addressToString(allocator, address).toValueGC(globalThis);
const str = addressToString(address) catch {
globalThis.throwOutOfMemory();
return .zero;
};
defer str.deref();
return str.toJS(globalThis);
}

fn addrInfoCount(addrinfo: *std.c.addrinfo) u32 {
Expand All @@ -329,21 +332,15 @@ fn addrInfoCount(addrinfo: *std.c.addrinfo) u32 {
}

pub fn addrInfoToJSArray(
parent_allocator: std.mem.Allocator,
addr_info: *std.c.addrinfo,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
var stack = std.heap.stackFallback(2048, parent_allocator);
var arena = bun.ArenaAllocator.init(stack.get());
const array = JSC.JSValue.createEmptyArray(
globalThis,
addrInfoCount(addr_info),
);

{
defer arena.deinit();

const allocator = arena.allocator();
var j: u32 = 0;
var current: ?*std.c.addrinfo = addr_info;
while (current) |this_node| : (current = current.?.next) {
Expand All @@ -353,7 +350,6 @@ pub fn addrInfoToJSArray(
bun.JSC.DNS.GetAddrInfo.Result.toJS(
&(bun.JSC.DNS.GetAddrInfo.Result.fromAddrInfo(this_node) orelse continue),
globalThis,
allocator,
),
);
j += 1;
Expand Down Expand Up @@ -487,11 +483,13 @@ pub const GetAddrInfo = struct {
}

if (value.isString()) {
const str = value.toBunString(globalObject);
if (str.isEmpty())
return .unspecified;
return map.fromJS(globalObject, value) orelse {
if (value.toString(globalObject).length() == 0) {
return .unspecified;
}

return str.inMap(map) orelse return error.InvalidFamily;
return error.InvalidFamily;
};
}

return error.InvalidFamily;
Expand Down Expand Up @@ -541,11 +539,12 @@ pub const GetAddrInfo = struct {
}

if (value.isString()) {
const str = value.getZigString(globalObject);
if (str.len == 0)
return .unspecified;
return map.fromJS(globalObject, value) orelse {
if (value.toString(globalObject).length() == 0)
return .unspecified;

return map.getWithEql(str, JSC.ZigString.eqlComptime) orelse return error.InvalidSocketType;
return error.InvalidSocketType;
};
}

return error.InvalidSocketType;
Expand Down Expand Up @@ -576,11 +575,13 @@ pub const GetAddrInfo = struct {
}

if (value.isString()) {
const str = value.getZigString(globalObject);
if (str.len == 0)
return .unspecified;
return map.fromJS(globalObject, value) orelse {
const str = value.toString(globalObject);
if (str.length() == 0)
return .unspecified;

return map.getWithEql(str, JSC.ZigString.eqlComptime) orelse return error.InvalidProtocol;
return error.InvalidProtocol;
};
}

return error.InvalidProtocol;
Expand Down Expand Up @@ -620,11 +621,13 @@ pub const GetAddrInfo = struct {
return default;

if (value.isString()) {
const str = value.getZigString(globalObject);
if (str.len == 0)
return default;
return label.fromJS(globalObject, value) orelse {
if (value.toString(globalObject).length() == 0) {
return default;
}

return label.getWithEql(str, JSC.ZigString.eqlComptime) orelse return error.InvalidBackend;
return error.InvalidBackend;
};
}

return error.InvalidBackend;
Expand All @@ -641,34 +644,32 @@ pub const GetAddrInfo = struct {
addrinfo: ?*std.c.addrinfo,
list: List,

pub fn toJS(this: Any, globalThis: *JSC.JSGlobalObject) ?JSC.JSValue {
return switch (this) {
.addrinfo => |addrinfo| addrInfoToJSArray(globalThis.allocator(), addrinfo orelse return null, globalThis),
pub fn toJS(this: *const Any, globalThis: *JSC.JSGlobalObject) ?JSC.JSValue {
return switch (this.*) {
.addrinfo => |addrinfo| addrInfoToJSArray(addrinfo orelse return null, globalThis),
.list => |list| brk: {
var stack = std.heap.stackFallback(2048, globalThis.allocator());
var arena = bun.ArenaAllocator.init(stack.get());
const array = JSC.JSValue.createEmptyArray(globalThis, @as(u32, @truncate(list.items.len)));
var i: u32 = 0;
const items: []const Result = list.items;
for (items) |item| {
array.putIndex(globalThis, i, item.toJS(globalThis, arena.allocator()));
array.putIndex(globalThis, i, item.toJS(globalThis));
i += 1;
}
break :brk array;
},
};
}

pub fn deinit(this: Any) void {
switch (this) {
pub fn deinit(this: *const Any) void {
switch (this.*) {
.addrinfo => |addrinfo| {
if (addrinfo) |a| {
std.c.freeaddrinfo(a);
}
},
.list => |list| {
var list_ = list;
list_.deinit();
.list => |list_| {
var list = list_;
list.clearAndFree();
},
}
}
Expand All @@ -693,9 +694,9 @@ pub const GetAddrInfo = struct {
};
}

pub fn toJS(this: *const Result, globalThis: *JSC.JSGlobalObject, allocator: std.mem.Allocator) JSValue {
pub fn toJS(this: *const Result, globalThis: *JSC.JSGlobalObject) JSValue {
const obj = JSC.JSValue.createEmptyObject(globalThis, 3);
obj.put(globalThis, JSC.ZigString.static("address"), addressToJS(allocator, this.address, globalThis));
obj.put(globalThis, JSC.ZigString.static("address"), addressToJS(&this.address, globalThis));
obj.put(globalThis, JSC.ZigString.static("family"), switch (this.address.any.family) {
std.os.AF.INET => JSValue.jsNumber(4),
std.os.AF.INET6 => JSValue.jsNumber(6),
Expand Down Expand Up @@ -1153,7 +1154,7 @@ pub const GetAddrInfoRequest = struct {

if (this.resolver_for_caching) |resolver| {
if (this.cache.pending_cache) {
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, status, .{ .addrinfo = addr_info });
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, status, &.{ .addrinfo = addr_info });
return;
}
}
Expand Down Expand Up @@ -1256,13 +1257,13 @@ pub const GetAddrInfoRequest = struct {
// }

if (this.cache.pending_cache) {
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, 0, any);
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, 0, &any);
return;
}
}
var head = this.head;
bun.default_allocator.destroy(this);
head.onCompleteNative(any);
head.onCompleteNative(&any);
},
.err => |err| {
getAddrInfoAsyncCallback(err, null, this);
Expand Down Expand Up @@ -1299,19 +1300,17 @@ pub const GetAddrInfoRequest = struct {
log("onLibUVComplete: status={d}", .{uv_info.retcode.int()});
const this: *GetAddrInfoRequest = @alignCast(@ptrCast(uv_info.data));
bun.assert(uv_info == &this.backend.libc.uv);
if (this.backend == .libinfo) {
if (this.backend.libinfo.file_poll) |poll| poll.deinit();
}

if (this.resolver_for_caching) |resolver| {
if (this.cache.pending_cache) {
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, uv_info.retcode.int(), .{ .addrinfo = uv_info.addrinfo });
resolver.drainPendingHostNative(this.cache.pos_in_pending, this.head.globalThis, uv_info.retcode.int(), &.{ .addrinfo = uv_info.addrinfo });
return;
}
}

var head = this.head;
head.processGetAddrInfoNative(uv_info.retcode.int(), uv_info.addrinfo);
uv_info.deinit();
head.globalThis.allocator().destroy(this);
}
};
Expand Down Expand Up @@ -1491,7 +1490,7 @@ pub const DNSLookup = struct {
return this;
}

pub fn onCompleteNative(this: *DNSLookup, result: GetAddrInfo.Result.Any) void {
pub fn onCompleteNative(this: *DNSLookup, result: *const GetAddrInfo.Result.Any) void {
log("onCompleteNative", .{});
const array = result.toJS(this.globalThis).?;
this.onCompleteWithArray(array);
Expand Down Expand Up @@ -1520,7 +1519,7 @@ pub const DNSLookup = struct {
promise.rejectTask(globalThis, error_value);
return;
}
onCompleteNative(this, .{ .addrinfo = result });
onCompleteNative(this, &.{ .addrinfo = result });
}

pub fn processGetAddrInfo(this: *DNSLookup, err_: ?c_ares.Error, _: i32, result: ?*c_ares.AddrInfo) void {
Expand Down Expand Up @@ -1559,7 +1558,7 @@ pub const DNSLookup = struct {
pub fn onComplete(this: *DNSLookup, result: *c_ares.AddrInfo) void {
log("onComplete", .{});

const array = result.toJSArray(this.globalThis.allocator(), this.globalThis);
const array = result.toJSArray(this.globalThis);
this.onCompleteWithArray(array);
}

Expand Down Expand Up @@ -1726,7 +1725,7 @@ pub const DNSResolver = struct {

var pending: ?*DNSLookup = key.lookup.head.next;
var prev_global = key.lookup.head.globalThis;
var array = addr.toJSArray(this.vm.allocator, prev_global);
var array = addr.toJSArray(prev_global);
defer addr.deinit();
array.ensureStillAlive();
key.lookup.head.onCompleteWithArray(array);
Expand All @@ -1738,7 +1737,7 @@ pub const DNSResolver = struct {
while (pending) |value| {
const new_global = value.globalThis;
if (prev_global != new_global) {
array = addr.toJSArray(this.vm.allocator, new_global);
array = addr.toJSArray(new_global);
prev_global = new_global;
}
pending = value.next;
Expand All @@ -1751,7 +1750,7 @@ pub const DNSResolver = struct {
}
}

pub fn drainPendingHostNative(this: *DNSResolver, index: u8, globalObject: *JSC.JSGlobalObject, err: i32, result: GetAddrInfo.Result.Any) void {
pub fn drainPendingHostNative(this: *DNSResolver, index: u8, globalObject: *JSC.JSGlobalObject, err: i32, result: *const GetAddrInfo.Result.Any) void {
log("drainPendingHostNative", .{});
const key = this.getKey(index, "pending_host_cache_native", GetAddrInfoRequest);

Expand Down
7 changes: 0 additions & 7 deletions src/deps/c_ares.zig
Original file line number Diff line number Diff line change
Expand Up @@ -369,21 +369,15 @@ pub const AddrInfo = extern struct {

pub fn toJSArray(
addr_info: *AddrInfo,
parent_allocator: std.mem.Allocator,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
var stack = std.heap.stackFallback(2048, parent_allocator);
var arena = bun.ArenaAllocator.init(stack.get());
var node = addr_info.node.?;
const array = JSC.JSValue.createEmptyArray(
globalThis,
node.count(),
);

{
defer arena.deinit();

const allocator = arena.allocator();
var j: u32 = 0;
var current: ?*AddrInfo_node = addr_info.node;
while (current) |this_node| : (current = this_node.next) {
Expand All @@ -400,7 +394,6 @@ pub const AddrInfo = extern struct {
.ttl = this_node.ttl,
},
globalThis,
allocator,
),
);
j += 1;
Expand Down
4 changes: 4 additions & 0 deletions src/deps/libuv.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,10 @@ pub const struct_uv_getaddrinfo_s = extern struct {
addrinfow: ?*anyopaque,
addrinfo: ?*addrinfo,
retcode: ReturnCode,

pub fn deinit(this: *uv_getaddrinfo_t) void {
uv_freeaddrinfo(this);
}
};
const struct_unnamed_439 = extern struct {
overlapped: OVERLAPPED,
Expand Down