https://github.com/lun-4/zigdig
naive dns client library in zig
https://github.com/lun-4/zigdig
dns zig zig-package
Last synced: 5 months ago
JSON representation
naive dns client library in zig
- Host: GitHub
- URL: https://github.com/lun-4/zigdig
- Owner: lun-4
- License: mit
- Created: 2019-05-12T05:39:02.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2024-08-07T05:10:10.000Z (9 months ago)
- Last Synced: 2024-12-01T10:54:22.384Z (5 months ago)
- Topics: dns, zig, zig-package
- Language: Zig
- Homepage:
- Size: 595 KB
- Stars: 33
- Watchers: 3
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-zig - lun-4/zigdig
- awesome-zig - zigdig🗒️naive dns client library in zig
README
# zigdig
naive dns client library in zig
help me decide if this api is good: https://github.com/lun-4/zigdig/issues/10
## what does it do
- serialization and deserialization of dns packets as per rfc1035
- supports a subset of rdata (i do not have any plans to support 100% of DNS, but SRV/MX/TXT/A/AAAA
are there, which most likely will be enough for your use cases)
- has helpers for reading `/etc/resolv.conf` (not that much, really)## what does it not do
- no edns0
- support all resolv.conf options
- can deserialize pointer labels, but does not serialize into pointers
- follow CNAME records, this provides only the basic
serialization/deserializtion## how do
- zig 0.12.0: https://ziglang.org
- have a `/etc/resolv.conf`
- tested on linux, should work on bsd i think```
git clone ...
cd zigdigzig build test
zig build install --prefix ~/.local/
```and then
```bash
zigdig google.com a
```or, for the host(1) equivalent
```bash
zigdig-tiny google.com
```## using the library
### getAddressList-style api
```zig
const dns = @import("dns");pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
_ = gpa.deinit();
}
var allocator = gpa.alloator();var addresses = try dns.helpers.getAddressList("ziglang.org", allocator);
defer addresses.deinit();for (addresses.addrs) |address| {
std.debug.print("we live in a society {}\n", .{address});
}
}
```### full api
```zig
const dns = @import("dns");pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
_ = gpa.deinit();
}
var allocator = gpa.alloator();var name_buffer: [128][]const u8 = undefined;
const name = try dns.Name.fromString("ziglang.org", &name_buffer);var questions = [_]dns.Question{
.{
.name = name,
.typ = .A,
.class = .IN,
},
};var packet = dns.Packet{
.header = .{
.id = dns.helpers.randomHeaderId(),
.is_response = false,
.wanted_recursion = true,
.question_length = 1,
},
.questions = &questions,
.answers = &[_]dns.Resource{},
.nameservers = &[_]dns.Resource{},
.additionals = &[_]dns.Resource{},
};// use helper function to connect to a resolver in the systems'
// resolv.confconst conn = try dns.helpers.connectToSystemResolver();
defer conn.close();try conn.sendPacket(packet);
// you can also do this to support any Writer
// const written_bytes = try packet.writeTo(some_fun_writer_goes_here);const reply = try conn.receivePacket(allocator, 4096);
defer reply.deinit();// you can also do this to support any Reader
// const packet = try dns.Packet.readFrom(some_fun_reader, allocator);
// defer packet.deinit();const reply_packet = reply.packet;
logger.info("reply: {}", .{reply_packet});try std.testing.expectEqual(packet.header.id, reply_packet.header.id);
try std.testing.expect(reply_packet.header.is_response);// ASSERTS that there's one A resource in the answer!!! you should verify
// reply_packet.header.opcode to see if there's any errorsconst resource = reply_packet.answers[0];
var resource_data = try dns.ResourceData.fromOpaque(
reply_packet,
resource.typ,
resource.opaque_rdata,
allocator
);
defer resource_data.deinit(allocator);// you now have an std.net.Address to use to your hearts content
const ziglang_address = resource_data.A;
}```
it is recommended to look at zigdig's source on `src/main.zig` to understand
how things tick using the library, but it boils down to three things:
- packet generation and serialization
- sending/receiving (via a small shim on top of std.os.socket)
- packet deserialization