hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 4bf2bb19ccf91f3405ea408e84266a3a313717e5
parent 636c6dc3faa5bb93b0f31b2821870ef152af9a7b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 21 Jun 2021 10:40:09 -0400

net::dns: add porcelain decoder API

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mnet/dns/encoding.ha | 44+++++++++++++++++++++++++++++++++++++++++---
Mnet/dns/types.ha | 22+++++++++++++++++++++-
2 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/net/dns/encoding.ha b/net/dns/encoding.ha @@ -16,9 +16,47 @@ export type decoder = struct { // Decodes a DNS message, heap allocating the resources necessary to represent // it in Hare's type system. The caller must use [[message_free]] to free the // return value. To decode without use of the heap, see [[decoder_init]]. -export fn decode(buf: []u8) *message = { - abort(); // TODO - return alloc(message { ... }); +export fn decode(buf: []u8) (*message | format) = { + let msg = message { ... }; + let dec = decoder_init(buf); + decode_header(&dec, &msg.header)?; + + for (let i = 0z; i < msg.header.qdcount; i += 1) { + let q = question { ... }; + let names = decode_question(&dec, &q)?; + + for (let i = 0; len(names) != 0; i += 1) { + let ns = decode_name(&dec, names)!; + names = ns.0; + append(q.qname, ns.1); + }; + + append(msg.questions, q); + }; + + decode_rrecords(&dec, msg.header.ancount, &msg.answers)?; + decode_rrecords(&dec, msg.header.nscount, &msg.authority)?; + decode_rrecords(&dec, msg.header.arcount, &msg.additional)?; + return alloc(msg); +}; + +fn decode_rrecords( + dec: *decoder, + count: u16, + out: *[]rrecord, +) (void | format) = { + for (let i = 0z; i < count; i += 1) { + let r = rrecord { ... }; + let names = decode_rrecord(dec, &r)?; + + for (let i = 0; len(names) != 0; i += 1) { + let ns = decode_name(dec, names)!; + names = ns.0; + append(r.name, ns.1); + }; + + append(*out, r); + }; }; // Initializes a DNS message decoder. All storaged used by the decoder is either diff --git a/net/dns/types.ha b/net/dns/types.ha @@ -131,5 +131,25 @@ export type message = struct { // Frees a [[message]] and the resources associated with it. export fn message_free(msg: *message) void = { - abort(); // TODO + for (let i = 0z; i < len(msg.questions); i += 1) { + free(msg.questions[i].qname); + }; + free(msg.questions); + + for (let i = 0z; i < len(msg.questions); i += 1) { + free(msg.answers[i].name); + }; + free(msg.answers); + + for (let i = 0z; i < len(msg.questions); i += 1) { + free(msg.answers[i].name); + }; + free(msg.authority); + + for (let i = 0z; i < len(msg.questions); i += 1) { + free(msg.answers[i].name); + }; + free(msg.additional); + + free(msg); };