authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-29 14:03:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-29 14:03:39-04:00
log9ade31faaf74f5fc4291df17749ade508e53f734
tree6f472736749cf12bc4622768584a51c14fbc0fe1
parent67058b9b7089446e16eee3c03ab3f8f9a5d13529
signaturelock-open Commit is signed but in an unrecognized format.

implement CNAME expansion


3 files changed, 63 insertions(+), 5 deletions(-)

lib/std/c.zig+8
......@@ -191,3 +191,11 @@ pub extern "c" fn getnameinfo(
191191pub extern "c" fn gai_strerror(errcode: c_int) [*]const u8;
192192
193193pub extern "c" fn poll(fds: [*]pollfd, nfds: nfds_t, timeout: c_int) c_int;
194
195pub extern "c" fn dn_expand(
196 msg: [*]const u8,
197 eomorig: [*]const u8,
198 comp_dn: [*]const u8,
199 exp_dn: [*]u8,
200 length: c_int,
201) c_int;
lib/std/net.zig+7-5
......@@ -1017,7 +1017,6 @@ fn dnsParse(
10171017}
10181018
10191019fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) !void {
1020 var tmp: [256]u8 = undefined;
10211020 switch (rr) {
10221021 os.RR_A => {
10231022 if (data.len != 4) return error.InvalidDnsARecord;
......@@ -1038,10 +1037,13 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
10381037 mem.copy(u8, &new_addr.addr, data);
10391038 },
10401039 os.RR_CNAME => {
1041 @panic("TODO dn_expand");
1042 //if (__dn_expand(packet, (const unsigned char *)packet + 512,
1043 // data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
1044 // strcpy(ctx->canon, tmp);
1040 var tmp: [256]u8 = undefined;
1041 // Returns len of compressed name. strlen to get canon name.
1042 _ = try os.dn_expand(packet, data, &tmp);
1043 const canon_name = mem.toSliceConst(u8, &tmp);
1044 if (isValidHostName(canon_name)) {
1045 try ctx.canon.replaceContents(canon_name);
1046 }
10451047 },
10461048 else => return,
10471049 }
lib/std/os.zig+48
......@@ -3076,3 +3076,51 @@ pub fn recvfrom(
30763076 }
30773077 }
30783078}
3079
3080pub const DnExpandError = error{InvalidDnsPacket};
3081
3082pub fn dn_expand(
3083 msg: []const u8,
3084 comp_dn: []const u8,
3085 exp_dn: []u8,
3086) DnExpandError!usize {
3087 var p = comp_dn.ptr;
3088 var len: usize = std.math.maxInt(usize);
3089 const end = msg.ptr + msg.len;
3090 if (p == end or exp_dn.len == 0) return error.InvalidDnsPacket;
3091 var dest = exp_dn.ptr;
3092 const dend = dest + std.math.min(exp_dn.len, 254);
3093 // detect reference loop using an iteration counter
3094 var i: usize = 0;
3095 while (i < msg.len) : (i += 2) {
3096 // loop invariants: p<end, dest<dend
3097 if ((p[0] & 0xc0) != 0) {
3098 if (p + 1 == end) return error.InvalidDnsPacket;
3099 var j = ((p[0] & usize(0x3f)) << 8) | p[1];
3100 if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 2 - @ptrToInt(comp_dn.ptr);
3101 if (j >= msg.len) return error.InvalidDnsPacket;
3102 p = msg.ptr + j;
3103 } else if (p[0] != 0) {
3104 if (dest != exp_dn.ptr) {
3105 dest.* = '.';
3106 dest += 1;
3107 }
3108 var j = p[0];
3109 p += 1;
3110 if (j >= @ptrToInt(end) - @ptrToInt(p) or j >= @ptrToInt(dend) - @ptrToInt(dest)) {
3111 return error.InvalidDnsPacket;
3112 }
3113 while (j != 0) {
3114 j -= 1;
3115 dest.* = p[0];
3116 dest += 1;
3117 p += 1;
3118 }
3119 } else {
3120 dest.* = 0;
3121 if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 1 - @ptrToInt(comp_dn.ptr);
3122 return len;
3123 }
3124 }
3125 return error.InvalidDnsPacket;
3126}