mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.Io.net.HostName: implement DNS name expansion
This commit is contained in:
parent
f1a590c876
commit
85a6fea3be
@ -51,6 +51,7 @@ pub const LookupError = error{
|
|||||||
ResolvConfParseFailed,
|
ResolvConfParseFailed,
|
||||||
InvalidDnsARecord,
|
InvalidDnsARecord,
|
||||||
InvalidDnsAAAARecord,
|
InvalidDnsAAAARecord,
|
||||||
|
InvalidDnsCnameRecord,
|
||||||
NameServerFailure,
|
NameServerFailure,
|
||||||
} || Io.Timestamp.Error || IpAddress.BindError || Io.File.OpenError || Io.File.Reader.Error || Io.Cancelable;
|
} || Io.Timestamp.Error || IpAddress.BindError || Io.File.OpenError || Io.File.Reader.Error || Io.Cancelable;
|
||||||
|
|
||||||
@ -381,16 +382,8 @@ fn lookupDns(io: Io, lookup_canon_name: []const u8, rc: *const ResolvConf, optio
|
|||||||
addresses_len += 1;
|
addresses_len += 1;
|
||||||
},
|
},
|
||||||
std.posix.RR.CNAME => {
|
std.posix.RR.CNAME => {
|
||||||
_ = &canonical_name;
|
_, canonical_name = expand(record.packet, record.data_off, options.canonical_name_buffer) catch
|
||||||
@panic("TODO");
|
return error.InvalidDnsCnameRecord;
|
||||||
//var tmp: [256]u8 = undefined;
|
|
||||||
//// Returns len of compressed name. strlen to get canon name.
|
|
||||||
//_ = try posix.dn_expand(packet, record.data, &tmp);
|
|
||||||
//const canon_name = mem.sliceTo(&tmp, 0);
|
|
||||||
//if (isValidHostName(canon_name)) {
|
|
||||||
// ctx.canon.items.len = 0;
|
|
||||||
// try ctx.canon.appendSlice(gpa, canon_name);
|
|
||||||
//}
|
|
||||||
},
|
},
|
||||||
else => continue,
|
else => continue,
|
||||||
};
|
};
|
||||||
@ -525,51 +518,50 @@ fn writeResolutionQuery(q: *[280]u8, op: u4, dname: []const u8, class: u8, ty: u
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ExpandDomainNameError = error{InvalidDnsPacket};
|
pub const ExpandError = error{InvalidDnsPacket} || InitError;
|
||||||
|
|
||||||
pub fn expandDomainName(
|
/// Decompresses a DNS name.
|
||||||
msg: []const u8,
|
///
|
||||||
comp_dn: []const u8,
|
/// Returns number of bytes consumed from `packet` starting at `i`,
|
||||||
exp_dn: []u8,
|
/// along with the expanded `HostName`.
|
||||||
) ExpandDomainNameError!usize {
|
///
|
||||||
// This implementation is ported from musl libc.
|
/// Asserts `buffer` is has length at least `max_len`.
|
||||||
// A more idiomatic "ziggy" implementation would be welcome.
|
pub fn expand(noalias packet: []const u8, start_i: usize, noalias dest_buffer: []u8) ExpandError!struct { usize, HostName } {
|
||||||
var p = comp_dn.ptr;
|
const dest = dest_buffer[0..max_len];
|
||||||
var len: usize = std.math.maxInt(usize);
|
|
||||||
const end = msg.ptr + msg.len;
|
var i = start_i;
|
||||||
if (p == end or exp_dn.len == 0) return error.InvalidDnsPacket;
|
var dest_i: usize = 0;
|
||||||
var dest = exp_dn.ptr;
|
var len: ?usize = null;
|
||||||
const dend = dest + @min(exp_dn.len, 254);
|
|
||||||
// detect reference loop using an iteration counter
|
// Detect reference loop using an iteration counter.
|
||||||
var i: usize = 0;
|
for (0..packet.len / 2) |_| {
|
||||||
while (i < msg.len) : (i += 2) {
|
if (i >= packet.len) return error.InvalidDnsPacket;
|
||||||
// loop invariants: p<end, dest<dend
|
|
||||||
if ((p[0] & 0xc0) != 0) {
|
const c = packet[i];
|
||||||
if (p + 1 == end) return error.InvalidDnsPacket;
|
if ((c & 0xc0) != 0) {
|
||||||
const j = @as(usize, p[0] & 0x3f) << 8 | p[1];
|
if (i + 1 >= packet.len) return error.InvalidDnsPacket;
|
||||||
if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 2 - @intFromPtr(comp_dn.ptr);
|
const j: usize = (@as(usize, c & 0x3F) << 8) | packet[i + 1];
|
||||||
if (j >= msg.len) return error.InvalidDnsPacket;
|
if (j >= packet.len) return error.InvalidDnsPacket;
|
||||||
p = msg.ptr + j;
|
if (len == null) len = (i + 2) - start_i;
|
||||||
} else if (p[0] != 0) {
|
i = j;
|
||||||
if (dest != exp_dn.ptr) {
|
} else if (c != 0) {
|
||||||
dest[0] = '.';
|
if (dest_i != 0) {
|
||||||
dest += 1;
|
dest[dest_i] = '.';
|
||||||
}
|
dest_i += 1;
|
||||||
var j = p[0];
|
|
||||||
p += 1;
|
|
||||||
if (j >= @intFromPtr(end) - @intFromPtr(p) or j >= @intFromPtr(dend) - @intFromPtr(dest)) {
|
|
||||||
return error.InvalidDnsPacket;
|
|
||||||
}
|
|
||||||
while (j != 0) {
|
|
||||||
j -= 1;
|
|
||||||
dest[0] = p[0];
|
|
||||||
dest += 1;
|
|
||||||
p += 1;
|
|
||||||
}
|
}
|
||||||
|
const label_len: usize = c;
|
||||||
|
if (i + 1 + label_len > packet.len) return error.InvalidDnsPacket;
|
||||||
|
if (dest_i + label_len + 1 > dest.len) return error.InvalidDnsPacket;
|
||||||
|
@memcpy(dest[dest_i..][0..label_len], packet[i + 1 ..][0..label_len]);
|
||||||
|
dest_i += label_len;
|
||||||
|
i += 1 + label_len;
|
||||||
} else {
|
} else {
|
||||||
dest[0] = 0;
|
dest[dest_i] = 0;
|
||||||
if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 1 - @intFromPtr(comp_dn.ptr);
|
dest_i += 1;
|
||||||
return len;
|
return .{
|
||||||
|
len orelse i - start_i + 1,
|
||||||
|
try .init(dest[0..dest_i]),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error.InvalidDnsPacket;
|
return error.InvalidDnsPacket;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user