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

Adding classless IN-ADDR.ARPA (IPv4) and IP6.ARPA (IPv6) delegations (reverse lookups) #12

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

BitlyTwiser
Copy link

Good day!

I have been aware of your marvelous works for some time! I followed the thread for this package when it was moving its way towards the Zig stdlib 👏 I am excited to see the package progress and move towards stdlib merging.

I am a fan of these works and found them most intriguing, thus, when I had an opportunity to use this package I dived right in! 😄

I was working on another project of mine when I realized I needed reverse DNS lookups to ascertain host records from IP addresses in Zig and your work seemed like the perfect place to attempt to add such things! I hope you do not mind the PR to extend the API functionality of zigdig just a smidge! 🙃

I also apologize if this is a long PR message for little reason, I am an excitable fellow and enjoy this stuff immensely 🙏

Notes on the PR:
The primary innards of the zigdig package were mostly left untouched. I added reverse.zig and address.zig (as you can obviously see) to facilitate the needs of the lookup and the IP Address work needed to get IP's into ARPA formation for PTR DNS queries.

All tests pass and look good. I did need to extend max_label_size: usize = 35 from 32->35 else it would cause an overflow for the more robust label sizes needed for Ipv6 parsing which seemed acceptable enough.

For testing (outside of the actual code) I also used Wireshark and dig to capture packets to ensure everything looked good (aside from getting a valid return, which one does, I wanted to ensure packet structure looked perfect as well).

Dig commands for testing:

dig -x <ip_address> +noadditional +nostats +nocomments +answer +noedns +noadflag

Running the code and capturing traffic on Lo interface the packets are identical and the reverse lookup succeeds with the proper addresses/records returned:
(left packet is the dig command, Right packet is the packet captured from program runtime)
Request:
Screenshot from 2024-09-20 07-37-15

Response (same order as above respectively):
Screenshot from 2024-09-20 07-42-18

Now with all that said, I am super open to feedback, criticism, and the like 😄

If this is entirely unwanted I can keep the works in my work and work from there, if you think this is nifty/sensible and could enhance the package that is marvelous! Whatever feedback on the code you have I am all 👂 and 👀

Thanks for your time! 😃

@BitlyTwiser
Copy link
Author

Good day @lun-4,

I was curious if you yet had an opportunity to review the above PR in any fashion 🙏

Hopefully it does not take too much of your time and I always appreciate feedback 😃

@lun-4
Copy link
Owner

lun-4 commented Oct 13, 2024

oops, thanks for the reminder, should've said something once the PR was open but these past weeks have been keeping me busy. I plan to review this once I'm able to get around to it.

regarding stdlib upstreaming, given the API is living outside of the main address resolution API, I'd be fine with merging it (after review) and just not upstreaming that specific part (given I think stdlib does not need reverse DNS lookups itself given that functionality wasn't there)

@BitlyTwiser
Copy link
Author

Oh certainly understandable there! The hectic days can certainly keep us busy, take all the time you need 😄 I just appreciate the time and review! 🙇

Most certainly understandable on the passing of the reverse code upstream to stdlib. During curation, I mostly assumed all of this would remain behind within the base code of zigdig since its primary purpose is a bit outside of stdlibs needs 🤣

Mostly selfishly making the alterations since I needed them myself for other projects and I was already aware of/a fan of the zigdig code itself 👍

Let me know of any changes you wish to see when you get around to the review and I shall be happy for any and all feedback!

### Reverse lookups examples
```
// Ipv4
const name = "dns.google.";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name is not being used in this example, why is that?

};
}

/// Creates an IpAddress from a []const u8 address
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddressMeta.fromString doesn't return IpAddress


const Errors = error{InvalidIP};

pub const AddressMeta = union(enum) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why isn't std.net.Address used directly?

};

// RFC reference for ARPA address formation: https://www.ietf.org/rfc/rfc2317.txt
pub const IpAddress = struct {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably should be renamed to ArpaDomain rather than IpAddress

arpa_suffix: []const u8 = ".in-addr.arpa",
arpa_suffix_ipv6: []const u8 = "ip6.arpa",

allocator: std.mem.Allocator,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the design of zigdig allows for library users to interact with it without memory allocation, is there a way to do such here?

);

//fromOpaque read the data, so if we utilize any standard reader/writer we have access to the []const u8 opaque data value. So we just allocprint here
const dns_name = try std.fmt.allocPrint(self.allocator, "{s}", .{resource_data});
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should verify that the returned resource_data is of type PTR instead of relying on the dynamic format within dns.ResourceData. a malformed response would return malformed results to library clients instead of an error or empty slice.

test "reverse lookup of Ipv4 address" {
const name = "dns.google.";
const test_address = "8.8.4.4";
var reverse = try ReverseLookup.init(std.heap.page_allocator, test_address, 123);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use std.testing.allocator for memory leak checking (applies to all tests here as well)

var reverse = try ReverseLookup.init(std.heap.page_allocator, test_address, 123);
const names = try reverse.lookupIpv4();

assert(names.len > 0);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use std.testing.expect to fail the test with an error instead of panic'ing the entire executable

const names = try reverse.lookupIpv4();

assert(names.len > 0);
assert(std.mem.eql(u8, names[0], name));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use std.testing.expectEqualStrings for the same reason, plus gives nice diff output when it fails

@@ -295,3 +296,41 @@ test "rdata serialization" {
const encoded_result = encodeBase64(&encode_buffer, serialized_result);
try std.testing.expectEqualStrings(PACKET_WITH_RDATA, encoded_result);
}

// Recreation of tests from reverse.zig to show basic API usage for reverse lookups
test "reverse address lookup Ipv4" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these tests are copy-pasted from src/reverse.zig and it seems on purpose, I would strongly suggest against copy-pasting them to decrease maintenance burden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants