From: ReYuki <reyuki@gnuweeb.org>
To: GNU/Weeb Mailing List <gwml@vger.gnuweeb.org>
Cc: ReYuki <me@reyuki.site>
Subject: [PATCH gwproxy v1 2/2] add support for AAAA record type
Date: Mon, 28 Jul 2025 12:14:35 +0700 [thread overview]
Message-ID: <20250728051438.48089-3-reyuki@gnuweeb.org> (raw)
In-Reply-To: <20250728051438.48089-1-reyuki@gnuweeb.org>
From: ReYuki <me@reyuki.site>
https://datatracker.ietf.org/doc/html/rfc3596
2.1 AAAA record type
The AAAA resource record type is a record specific to the Internet
class that stores a single IPv6 address.
The IANA assigned value of the type is 28 (decimal).
the following is a sample from dig command (strace -x -s 512 dig A google.com):
// dns request query packet
// header section
\xfd\x11 // id
\x01\x20 // flags
\x00\x01 // qdcount
\x00\x00 // ancount
\x00\x00 // nscount
\x00\x01 // arcount
// question section
// name
\x06\x67\x6f\x6f\x67\x6c\x65
\x03\x63\x6f\x6d
\x00\x00 // type
\x1c\x00 // class
// additional resource section
\x01\x00\x00\x29\x04\xd0\x00\x00\x00\x00\x00\x0c\x00\x0a\x00\x08\x21\x06\x68\xe2\x80\xc2\xe8\xb8
// dns response answer packet
// header section
\xfd\x11 // id
\x81\x80 // flags
\x00\x01 // qdcount
\x00\x04 // ancount
\x00\x00 // nscount
\x00\x01 // arcount
// question section
\x06\x67\x6f\x6f\x67\x6c\x65
\x03\x63\x6f\x6d
\x00
\x00\x1c // type
\x00\x01 // class
// (1) answer section
\xc0\x0c // name
\x00\x1c // type
\x00\x01 // class
\x00\x00\x06\xd1 // ttl
\x00\x10 // rdlength
\x24\x04\x68\x00\x40\x03\x0c\x0f\x00\x00\x00\x00\x00\x00\x00\x8a // rdata
// (2) answer section
\xc0\x0c
\x00\x1c
\x00\x01
\x00\x00\x06\xd1
\x00\x10
\x24\x04\x68\x00\x40\x03\x0c\x0f\x00\x00\x00\x00\x00\x00\x00\x65
// (3) answer section
\xc0\x0c
\x00\x1c
\x00\x01
\x00\x00\x06\xd1
\x00\x10
\x24\x04\x68\x00\x40\x03\x0c\x0f\x00\x00\x00\x00\x00\x00\x00\x66
// (4) answer section
\xc0\x0c
\x00\x1c
\x00\x01
\x00\x00\x06\xd1
\x00\x10
\x24\x04\x68\x00\x40\x03\x0c\x0f\x00\x00\x00\x00\x00\x00\x00\x64
// additional resource section
\x00\x00\x29\x10\x00\x00\x00\x00\x00\x00\x00
---
dnsclient.c | 7 +++++--
gwdnsparserlib.c | 14 +++++++++++++-
gwdnsparserlib.h | 4 +++-
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/dnsclient.c b/dnsclient.c
index 4d96b18..6f2e66c 100644
--- a/dnsclient.c
+++ b/dnsclient.c
@@ -83,6 +83,7 @@ static int send_query(struct io_uring *ring, int sockfd, char *domain, gwdns_que
q.domain = domain;
q.dst_buffer = buff->question;
q.dst_len = UDP_MSG_LIMIT;
+ q.type = TYPE_AAAA;
payload_len = construct_question(&q);
if (payload_len < 0)
return -1;
@@ -161,13 +162,15 @@ static int resolv_addr(char **domains, gwdns_resolv_hint *hint, gwdns_resolv_ctx
ctx->sqe_nr--;
printf("cqe->res=%d cqe->user_data=%llx\n", cqe->res, CLEAR_ID(cqe->user_data));
if (EXTRACT_ID(cqe->user_data) == ID) {
- char ipstr[INET_ADDRSTRLEN];
+ char ipstr[INET6_ADDRSTRLEN];
gwdns_answ_data d;
cqe->user_data = CLEAR_ID(cqe->user_data);
ret = serialize_answ((uint16_t)cqe->user_data, (uint8_t *)buff[idx].answr, cqe->res, &d);
for (size_t i = 0; i < d.hdr.ancount; i++) {
- inet_ntop(AF_INET, d.rr_answ[i]->rdata, ipstr, sizeof(ipstr));
+ gwdns_serialized_answ *p = d.rr_answ[i];
+ int sa_family = p->rr_type == TYPE_AAAA ? AF_INET6 : AF_INET;
+ inet_ntop(sa_family, p->rdata, ipstr, sizeof(ipstr));
printf("%s\n", ipstr);
}
diff --git a/gwdnsparserlib.c b/gwdnsparserlib.c
index aa883d9..022ccc2 100644
--- a/gwdnsparserlib.c
+++ b/gwdnsparserlib.c
@@ -1,3 +1,5 @@
+#define _DEFAULT_SOURCE
+#include <endian.h>
#include "gwdnsparserlib.h"
static ssize_t construct_qname(uint8_t *dst, size_t dst_len, const char *qname)
@@ -126,14 +128,21 @@ int serialize_answ(uint16_t txid, uint8_t *in, size_t in_len, gwdns_answ_data *o
in += 2; // NAME
memcpy(&item->rr_type, in, 2);
+ item->rr_type = ntohs(item->rr_type);
in += 2; // TYPE
memcpy(&item->rr_class, in, 2);
+ item->rr_class = ntohs(item->rr_class);
in += 2; // CLASS
memcpy(&item->ttl, in, 4);
+ item->ttl = be32toh(item->ttl);
in += 4; // TTL
memcpy(&rdlength, in, sizeof(rdlength));
rdlength = ntohs(rdlength);
+ if (item->rr_type == TYPE_AAAA && rdlength != sizeof(struct in6_addr))
+ return -EINVAL;
+ if (item->rr_type == TYPE_A && rdlength != sizeof(struct in_addr))
+ return -EINVAL;
item->rdlength = rdlength;
in += 2;
@@ -153,6 +162,9 @@ ssize_t construct_question(gwdns_question_part *question)
size_t required_len;
ssize_t bw;
+ if (question->type != TYPE_AAAA && question->type != TYPE_A)
+ return -EINVAL;
+
hdr = &pkt.hdr;
/*
* the memset implicitly set opcode to query
@@ -177,7 +189,7 @@ ssize_t construct_question(gwdns_question_part *question)
return bw;
pkt.body[bw++] = 0x0;
- qtype = htons(TYPE_A);
+ qtype = htons(question->type);
qclass = htons(CLASS_IN);
memcpy(&pkt.body[bw], &qtype, 2);
bw += 2;
diff --git a/gwdnsparserlib.h b/gwdnsparserlib.h
index d24e414..c5948d0 100644
--- a/gwdnsparserlib.h
+++ b/gwdnsparserlib.h
@@ -91,6 +91,7 @@ typedef enum {
TYPE_MINFO = 14, // mailbox or mail list information
TYPE_MX = 15, // mail exchange
TYPE_TXT = 16, // text strings
+ TYPE_AAAA = 28, // text strings
QTYPE_AXFR = 252, // A request for a transfer of an entire zone
QTYPE_MAILB = 253, // A request for mailbox-related records (MB, MG or MR)
QTYPE_ALL = 255 // A request for all records
@@ -119,6 +120,7 @@ typedef struct {
typedef struct {
uint8_t *dst_buffer;
+ uint16_t type;
size_t dst_len;
char *domain;
} gwdns_question_part;
@@ -190,7 +192,7 @@ typedef struct {
* possible error are:
* - ENAMETOOLONG domain name in question.name is too long.
* - ENOBUFS length in question.dst_len is not sufficient.
-* - EINVAL malformed question.name
+* - EINVAL malformed or unsupported value in question data
*/
ssize_t construct_question(gwdns_question_part *question);
--
ReYuki
next prev parent reply other threads:[~2025-07-28 5:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-28 5:14 [PATCH gwproxy v1 0/2] Introduce IPv6 support for dns parser program ReYuki
2025-07-28 5:14 ` [PATCH gwproxy v1 1/2] add unit test ReYuki
2025-07-28 5:14 ` ReYuki [this message]
2025-07-28 5:19 ` [PATCH gwproxy v1 0/2] Introduce IPv6 support for dns parser program reyuki
[not found] ` <CAADvAgoHZujWqiFWqjKXWHMtcJxvCBHZhdEp9Ysryy-8H6tkgg@mail.gmail.com>
2025-07-28 5:22 ` reyuki
[not found] ` <CAADvAgpRnL_GtvaHrM7JY4T_-qm9EZ0Lcg_dwSPQ+w60_esnmQ@mail.gmail.com>
2025-07-28 5:26 ` Re Yuki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250728051438.48089-3-reyuki@gnuweeb.org \
--to=reyuki@gnuweeb.org \
--cc=gwml@vger.gnuweeb.org \
--cc=me@reyuki.site \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox