networking · advanced · ~25 min
Length-prefixed wire-format parsing.
Decode a DNS-wire domain name — a sequence of length-prefixed labels — into a dotted string. Getting the bounds right is what keeps real resolvers from looping forever.
Implement int decode_dns_labels(const unsigned char *in, int in_len, char *out, int cap).
A DNS name on the wire is each label prefixed by its 1-byte length, ending with a 0-length terminator:
[3]'w' 'w' 'w' [7]'e' 'x' 'a' 'm' 'p' 'l' 'e' [3]'c' 'o' 'm' [0]
Decode this into "www.example.com" (labels joined by .), NUL-terminated. This exercise IGNORES pointer compression: any length byte with its top 2 bits set is rejected.
in: the DNS-wire bytes.in_len: number of bytes available in in.out: buffer for the decoded name.cap: capacity of out in bytes.Return the number of input bytes consumed (through and including the 0 terminator) on success, or -1 on any parse failure.
{3,'w','w','w', 7,'e','x','a','m','p','l','e', 3,'c','o','m', 0} -> 17, out = "www.example.com"
{0} -> 1, out = "" (root label)
{3,'w','w'} -> -1 (truncated: missing bytes)
{0xC0, 0x0C} -> -1 (compression pointer, refused)
0 byte) decodes to the empty string.-1.out; return -1 rather than truncate.DNS wire format uses length-prefixed labels. A parser that does pointer-compression wrong can loop forever — a classic CVE primitive in resolvers.
in, the DNS-wire bytes; in_len, bytes available; out buffer; cap, its size.
Input bytes consumed on success (out filled, NUL-terminated); -1 on any parse failure.
Refuse labels >63 bytes and compression pointers (top 2 bits set). Bound every read against in_len and every write against cap.
#include <stddef.h>
int decode_dns_labels(const unsigned char *in, int in_len, char *out, int cap) { /* TODO */ (void)in; (void)in_len; (void)out; (void)cap; return -1; }
Forgetting that each label is <= 63 bytes (top 2 bits clear).
Root label (just 00) → empty output. Truncated input.
O(in_len).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.