| ... | ... | @@ -363,17 +363,19 @@ fn lookupDns(io: Io, lookup_canon_name: []const u8, rc: *const ResolvConf, optio |
| 363 | 363 | continue; |
| 364 | 364 | }) |record| switch (record.rr) { |
| 365 | 365 | std.posix.RR.A => { |
| 366 | | if (record.data.len != 4) return error.InvalidDnsARecord; |
| 366 | const data = record.packet[record.data_off..][0..record.data_len]; |
| 367 | if (data.len != 4) return error.InvalidDnsARecord; |
| 367 | 368 | options.addresses_buffer[addresses_len] = .{ .ip4 = .{ |
| 368 | | .bytes = record.data[0..4].*, |
| 369 | .bytes = data[0..4].*, |
| 369 | 370 | .port = options.port, |
| 370 | 371 | } }; |
| 371 | 372 | addresses_len += 1; |
| 372 | 373 | }, |
| 373 | 374 | std.posix.RR.AAAA => { |
| 374 | | if (record.data.len != 16) return error.InvalidDnsAAAARecord; |
| 375 | const data = record.packet[record.data_off..][0..record.data_len]; |
| 376 | if (data.len != 16) return error.InvalidDnsAAAARecord; |
| 375 | 377 | options.addresses_buffer[addresses_len] = .{ .ip6 = .{ |
| 376 | | .bytes = record.data[0..16].*, |
| 378 | .bytes = data[0..16].*, |
| 377 | 379 | .port = options.port, |
| 378 | 380 | } }; |
| 379 | 381 | addresses_len += 1; |
| ... | ... | @@ -575,23 +577,52 @@ pub fn expandDomainName( |
| 575 | 577 | |
| 576 | 578 | pub const DnsResponse = struct { |
| 577 | 579 | bytes: []const u8, |
| 580 | bytes_index: u32, |
| 581 | answers_remaining: u16, |
| 578 | 582 | |
| 579 | 583 | pub const Answer = struct { |
| 580 | 584 | rr: u8, |
| 581 | | data: []const u8, |
| 582 | 585 | packet: []const u8, |
| 586 | data_off: u32, |
| 587 | data_len: u16, |
| 583 | 588 | }; |
| 584 | 589 | |
| 585 | 590 | pub const Error = error{InvalidDnsPacket}; |
| 586 | 591 | |
| 587 | 592 | pub fn init(r: []const u8) Error!DnsResponse { |
| 588 | 593 | if (r.len < 12) return error.InvalidDnsPacket; |
| 589 | | return .{ .bytes = r }; |
| 594 | if ((r[3] & 15) != 0) return .{ .bytes = r, .bytes_index = 3, .answers_remaining = 0 }; |
| 595 | var i: u32 = 12; |
| 596 | var query_count = std.mem.readInt(u16, r[4..6], .big); |
| 597 | while (query_count != 0) : (query_count -= 1) { |
| 598 | while (i < r.len and r[i] -% 1 < 127) i += 1; |
| 599 | if (r.len - i < 6) return error.InvalidDnsPacket; |
| 600 | i = i + 5 + @intFromBool(r[i] != 0); |
| 601 | } |
| 602 | return .{ |
| 603 | .bytes = r, |
| 604 | .bytes_index = i, |
| 605 | .answers_remaining = std.mem.readInt(u16, r[6..8], .big), |
| 606 | }; |
| 590 | 607 | } |
| 591 | 608 | |
| 592 | 609 | pub fn next(dr: *DnsResponse) Error!?Answer { |
| 593 | | _ = dr; |
| 594 | | @panic("TODO"); |
| 610 | if (dr.answers_remaining == 0) return null; |
| 611 | dr.answers_remaining -= 1; |
| 612 | const r = dr.bytes; |
| 613 | var i = dr.bytes_index; |
| 614 | while (i < r.len and r[i] -% 1 < 127) i += 1; |
| 615 | if (r.len - i < 12) return error.InvalidDnsPacket; |
| 616 | i = i + 1 + @intFromBool(r[i] != 0); |
| 617 | const len = std.mem.readInt(u16, r[i + 8 ..][0..2], .big); |
| 618 | if (i + 10 + len > r.len) return error.InvalidDnsPacket; |
| 619 | defer dr.bytes_index = i + 10 + len; |
| 620 | return .{ |
| 621 | .rr = r[i + 1], |
| 622 | .packet = r, |
| 623 | .data_off = i + 10, |
| 624 | .data_len = len, |
| 625 | }; |
| 595 | 626 | } |
| 596 | 627 | }; |
| 597 | 628 | |