| ... | @@ -13481,10 +13481,14 @@ fn netLookupFallible( | ... | @@ -13481,10 +13481,14 @@ fn netLookupFallible( |
| 13481 | if (is_windows) { | 13481 | if (is_windows) { |
| 13482 | if (options.family == null) { | 13482 | if (options.family == null) { |
| 13483 | if (IpAddress.parseIp4(name, options.port)) |addr| { | 13483 | if (IpAddress.parseIp4(name, options.port)) |addr| { |
| 13484 | try resolved.putAll(t_io, &.{ | 13484 | if (copyCanon(options.canonical_name_buffer, name)) |canon| { |
| 13485 | .{ .address = addr }, | 13485 | try resolved.putAll(t_io, &.{ |
| 13486 | .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) }, | 13486 | .{ .address = addr }, |
| 13487 | }); | 13487 | .{ .canonical_name = canon }, |
| | 13488 | }); |
| | 13489 | } else { |
| | 13490 | try resolved.putOne(t_io, .{ .address = addr }); |
| | 13491 | } |
| 13488 | return; | 13492 | return; |
| 13489 | } else |_| {} | 13493 | } else |_| {} |
| 13490 | } | 13494 | } |
| ... | @@ -13608,20 +13612,28 @@ fn netLookupFallible( | ... | @@ -13608,20 +13612,28 @@ fn netLookupFallible( |
| 13608 | if (native_os == .linux) { | 13612 | if (native_os == .linux) { |
| 13609 | if (options.family != .ip4) { | 13613 | if (options.family != .ip4) { |
| 13610 | if (IpAddress.parseIp6(name, options.port)) |addr| { | 13614 | if (IpAddress.parseIp6(name, options.port)) |addr| { |
| 13611 | try resolved.putAll(t_io, &.{ | 13615 | if (copyCanon(options.canonical_name_buffer, name)) |canon| { |
| 13612 | .{ .address = addr }, | 13616 | try resolved.putAll(t_io, &.{ |
| 13613 | .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) }, | 13617 | .{ .address = addr }, |
| 13614 | }); | 13618 | .{ .canonical_name = canon }, |
| | 13619 | }); |
| | 13620 | } else { |
| | 13621 | try resolved.putOne(t_io, .{ .address = addr }); |
| | 13622 | } |
| 13615 | return; | 13623 | return; |
| 13616 | } else |_| {} | 13624 | } else |_| {} |
| 13617 | } | 13625 | } |
| 13618 | | 13626 | |
| 13619 | if (options.family != .ip6) { | 13627 | if (options.family != .ip6) { |
| 13620 | if (IpAddress.parseIp4(name, options.port)) |addr| { | 13628 | if (IpAddress.parseIp4(name, options.port)) |addr| { |
| 13621 | try resolved.putAll(t_io, &.{ | 13629 | if (copyCanon(options.canonical_name_buffer, name)) |canon| { |
| 13622 | .{ .address = addr }, | 13630 | try resolved.putAll(t_io, &.{ |
| 13623 | .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) }, | 13631 | .{ .address = addr }, |
| 13624 | }); | 13632 | .{ .canonical_name = canon }, |
| | 13633 | }); |
| | 13634 | } else { |
| | 13635 | try resolved.putOne(t_io, .{ .address = addr }); |
| | 13636 | } |
| 13625 | return; | 13637 | return; |
| 13626 | } else |_| {} | 13638 | } else |_| {} |
| 13627 | } | 13639 | } |
| ... | @@ -13652,11 +13664,13 @@ fn netLookupFallible( | ... | @@ -13652,11 +13664,13 @@ fn netLookupFallible( |
| 13652 | results_buffer[results_index] = .{ .address = .{ .ip4 = .loopback(options.port) } }; | 13664 | results_buffer[results_index] = .{ .address = .{ .ip4 = .loopback(options.port) } }; |
| 13653 | results_index += 1; | 13665 | results_index += 1; |
| 13654 | } | 13666 | } |
| 13655 | const canon_name = "localhost"; | 13667 | if (options.canonical_name_buffer) |buf| { |
| 13656 | const canon_name_dest = options.canonical_name_buffer[0..canon_name.len]; | 13668 | const canon_name = "localhost"; |
| 13657 | canon_name_dest.* = canon_name.*; | 13669 | const canon_name_dest = buf[0..canon_name.len]; |
| 13658 | results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } }; | 13670 | canon_name_dest.* = canon_name.*; |
| 13659 | results_index += 1; | 13671 | results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } }; |
| | 13672 | results_index += 1; |
| | 13673 | } |
| 13660 | try resolved.putAll(t_io, results_buffer[0..results_index]); | 13674 | try resolved.putAll(t_io, results_buffer[0..results_index]); |
| 13661 | return; | 13675 | return; |
| 13662 | } | 13676 | } |
| ... | @@ -13688,7 +13702,7 @@ fn netLookupFallible( | ... | @@ -13688,7 +13702,7 @@ fn netLookupFallible( |
| 13688 | const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable; | 13702 | const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable; |
| 13689 | | 13703 | |
| 13690 | const hints: posix.addrinfo = .{ | 13704 | const hints: posix.addrinfo = .{ |
| 13691 | .flags = .{ .CANONNAME = options.request_canonical_name, .NUMERICSERV = true }, | 13705 | .flags = .{ .CANONNAME = options.canonical_name_buffer != null, .NUMERICSERV = true }, |
| 13692 | .family = posix.AF.UNSPEC, | 13706 | .family = posix.AF.UNSPEC, |
| 13693 | .socktype = posix.SOCK.STREAM, | 13707 | .socktype = posix.SOCK.STREAM, |
| 13694 | .protocol = posix.IPPROTO.TCP, | 13708 | .protocol = posix.IPPROTO.TCP, |
| ... | @@ -13745,9 +13759,9 @@ fn netLookupFallible( | ... | @@ -13745,9 +13759,9 @@ fn netLookupFallible( |
| 13745 | } | 13759 | } |
| 13746 | } | 13760 | } |
| 13747 | if (canon_name) |n| { | 13761 | if (canon_name) |n| { |
| 13748 | try resolved.putOne(t_io, .{ | 13762 | if (copyCanon(options.canonical_name_buffer, std.mem.sliceTo(n, 0))) |canon| { |
| 13749 | .canonical_name = copyCanon(options.canonical_name_buffer, std.mem.sliceTo(n, 0)), | 13763 | try resolved.putOne(t_io, .{ .canonical_name = canon }); |
| 13750 | }); | 13764 | } |
| 13751 | } | 13765 | } |
| 13752 | return; | 13766 | return; |
| 13753 | } | 13767 | } |
| ... | @@ -14268,12 +14282,14 @@ fn lookupDnsSearch( | ... | @@ -14268,12 +14282,14 @@ fn lookupDnsSearch( |
| 14268 | // both provides the desired default canonical name (if the requested | 14282 | // both provides the desired default canonical name (if the requested |
| 14269 | // name is not a CNAME record) and serves as a buffer for passing the | 14283 | // name is not a CNAME record) and serves as a buffer for passing the |
| 14270 | // full requested name to `lookupDns`. | 14284 | // full requested name to `lookupDns`. |
| 14271 | @memcpy(options.canonical_name_buffer[0..canon_name.len], canon_name); | 14285 | var local_buf: [HostName.max_len]u8 = undefined; |
| 14272 | options.canonical_name_buffer[canon_name.len] = '.'; | 14286 | const canon_buf = options.canonical_name_buffer orelse &local_buf; |
| | 14287 | @memcpy(canon_buf[0..canon_name.len], canon_name); |
| | 14288 | canon_buf[canon_name.len] = '.'; |
| 14273 | var it = std.mem.tokenizeAny(u8, search, " \t"); | 14289 | var it = std.mem.tokenizeAny(u8, search, " \t"); |
| 14274 | while (it.next()) |token| { | 14290 | while (it.next()) |token| { |
| 14275 | @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token); | 14291 | @memcpy(canon_buf[canon_name.len + 1 ..][0..token.len], token); |
| 14276 | const lookup_canon_name = options.canonical_name_buffer[0 .. canon_name.len + 1 + token.len]; | 14292 | const lookup_canon_name = canon_buf[0 .. canon_name.len + 1 + token.len]; |
| 14277 | if (t.lookupDns(lookup_canon_name, &rc, resolved, options)) |result| { | 14293 | if (t.lookupDns(lookup_canon_name, &rc, resolved, options)) |result| { |
| 14278 | return result; | 14294 | return result; |
| 14279 | } else |err| switch (err) { | 14295 | } else |err| switch (err) { |
| ... | @@ -14282,7 +14298,7 @@ fn lookupDnsSearch( | ... | @@ -14282,7 +14298,7 @@ fn lookupDnsSearch( |
| 14282 | } | 14298 | } |
| 14283 | } | 14299 | } |
| 14284 | | 14300 | |
| 14285 | const lookup_canon_name = options.canonical_name_buffer[0..canon_name.len]; | 14301 | const lookup_canon_name = canon_buf[0..canon_name.len]; |
| 14286 | return t.lookupDns(lookup_canon_name, &rc, resolved, options); | 14302 | return t.lookupDns(lookup_canon_name, &rc, resolved, options); |
| 14287 | } | 14303 | } |
| 14288 | | 14304 | |
| ... | @@ -14464,14 +14480,23 @@ fn lookupDns( | ... | @@ -14464,14 +14480,23 @@ fn lookupDns( |
| 14464 | addresses_len += 1; | 14480 | addresses_len += 1; |
| 14465 | }, | 14481 | }, |
| 14466 | .CNAME => { | 14482 | .CNAME => { |
| 14467 | _, canonical_name = HostName.expand(record.packet, record.data_off, options.canonical_name_buffer) catch | 14483 | if (options.canonical_name_buffer) |buf| { |
| 14468 | return error.InvalidDnsCnameRecord; | 14484 | _, canonical_name = HostName.expand( |
| | 14485 | record.packet, |
| | 14486 | record.data_off, |
| | 14487 | buf, |
| | 14488 | ) catch return error.InvalidDnsCnameRecord; |
| | 14489 | } |
| 14469 | }, | 14490 | }, |
| 14470 | _ => continue, | 14491 | _ => continue, |
| 14471 | }; | 14492 | }; |
| 14472 | } | 14493 | } |
| 14473 | | 14494 | |
| 14474 | try resolved.putOne(t_io, .{ .canonical_name = canonical_name orelse .{ .bytes = lookup_canon_name } }); | 14495 | if (options.canonical_name_buffer != null) { |
| | 14496 | try resolved.putOne(t_io, .{ |
| | 14497 | .canonical_name = canonical_name orelse .{ .bytes = lookup_canon_name }, |
| | 14498 | }); |
| | 14499 | } |
| 14475 | if (addresses_len == 0) return error.NoAddressReturned; | 14500 | if (addresses_len == 0) return error.NoAddressReturned; |
| 14476 | } | 14501 | } |
| 14477 | | 14502 | |
| ... | @@ -14552,13 +14577,15 @@ fn lookupHostsReader( | ... | @@ -14552,13 +14577,15 @@ fn lookupHostsReader( |
| 14552 | } else continue; | 14577 | } else continue; |
| 14553 | | 14578 | |
| 14554 | if (canonical_name == null) { | 14579 | if (canonical_name == null) { |
| 14555 | if (HostName.init(first_name_text.?)) |name_text| { | 14580 | if (options.canonical_name_buffer) |buf| { |
| 14556 | if (name_text.bytes.len <= options.canonical_name_buffer.len) { | 14581 | if (HostName.init(first_name_text.?)) |name_text| { |
| 14557 | const canonical_name_dest = options.canonical_name_buffer[0..name_text.bytes.len]; | 14582 | if (name_text.bytes.len <= buf.len) { |
| 14558 | @memcpy(canonical_name_dest, name_text.bytes); | 14583 | const canonical_name_dest = buf[0..name_text.bytes.len]; |
| 14559 | canonical_name = .{ .bytes = canonical_name_dest }; | 14584 | @memcpy(canonical_name_dest, name_text.bytes); |
| 14560 | } | 14585 | canonical_name = .{ .bytes = canonical_name_dest }; |
| 14561 | } else |_| {} | 14586 | } |
| | 14587 | } else |_| {} |
| | 14588 | } |
| 14562 | } | 14589 | } |
| 14563 | | 14590 | |
| 14564 | if (options.family != .ip6) { | 14591 | if (options.family != .ip6) { |
| ... | @@ -14652,17 +14679,23 @@ const LookupDnsWindows = struct { | ... | @@ -14652,17 +14679,23 @@ const LookupDnsWindows = struct { |
| 14652 | }); | 14679 | }); |
| 14653 | }, | 14680 | }, |
| 14654 | }; | 14681 | }; |
| 14655 | if (lookup_dns.results.pQueryRecords) |record| try lookup_dns.resolved.putOne(t_io, .{ | 14682 | if (lookup_dns.results.pQueryRecords) |record| { |
| 14656 | .canonical_name = .{ .bytes = lookup_dns.options.canonical_name_buffer[0..std.unicode.wtf16LeToWtf8( | 14683 | if (lookup_dns.options.canonical_name_buffer) |buf| { |
| 14657 | lookup_dns.options.canonical_name_buffer, | 14684 | const name_wtf16 = std.mem.span( |
| 14658 | std.mem.span(@as([*:0]const windows.WCHAR, @ptrCast(@alignCast(record.pName)))), | 14685 | @as([*:0]const windows.WCHAR, @ptrCast(@alignCast(record.pName))), |
| 14659 | )] }, | 14686 | ); |
| 14660 | }); | 14687 | const len = std.unicode.wtf16LeToWtf8(buf, name_wtf16); |
| | 14688 | try lookup_dns.resolved.putOne(t_io, .{ |
| | 14689 | .canonical_name = .{ .bytes = buf[0..len] }, |
| | 14690 | }); |
| | 14691 | } |
| | 14692 | } |
| 14661 | } | 14693 | } |
| 14662 | }; | 14694 | }; |
| 14663 | | 14695 | |
| 14664 | fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) HostName { | 14696 | fn copyCanon(canonical_name_buffer: ?*[HostName.max_len]u8, name: []const u8) ?HostName { |
| 14665 | const dest = canonical_name_buffer[0..name.len]; | 14697 | const buf = canonical_name_buffer orelse return null; |
| | 14698 | const dest = buf[0..name.len]; |
| 14666 | @memcpy(dest, name); | 14699 | @memcpy(dest, name); |
| 14667 | return .{ .bytes = dest }; | 14700 | return .{ .bytes = dest }; |
| 14668 | } | 14701 | } |