public inbox for gwml@vger.gnuweeb.org
 help / color / mirror / Atom feed
From: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
To: Ammar Faiz <ammarfaizi2@gnuweeb.org>
Cc: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>,
	Ahmad Gani <reyuki@gnuweeb.org>,
	GNU/Weeb Mailing List <gwml@vger.gnuweeb.org>
Subject: [PATCH gwproxy v13 5/8] dns_resolver: Add DNS resolution interface APIs
Date: Tue, 30 Sep 2025 15:54:25 +0700	[thread overview]
Message-ID: <20250930085428.717195-6-alviro.iskandar@gnuweeb.org> (raw)
In-Reply-To: <20250930085428.717195-1-alviro.iskandar@gnuweeb.org>

Provide an interface for DNS resolution to be used by other components
without including the socket handling code. It allows other components
to handle the socket I/O as they see fit, flexibly. For instance, using
epoll vs using io_uring has different ways of handling the socket I/O.

Signed-off-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
---
 src/gwproxy/dns_resolver.c | 125 +++++++++++++++++++++++++++++++++++++
 src/gwproxy/dns_resolver.h |  30 +++++++++
 2 files changed, 155 insertions(+)

diff --git a/src/gwproxy/dns_resolver.c b/src/gwproxy/dns_resolver.c
index 4d6924f..386439e 100644
--- a/src/gwproxy/dns_resolver.c
+++ b/src/gwproxy/dns_resolver.c
@@ -250,3 +250,128 @@ void gwp_dns_res_free(struct gwp_dns_resolver *res)
 	__sys_close(res->udp_fd);
 	memset(res, 0, sizeof(*res));
 }
+
+int gwp_dns_res_prep_query(struct gwp_dns_resolver *res,
+			   struct gwp_dns_packet *gdp)
+{
+	int af, ret;
+	ssize_t tmp;
+
+	assert(gdp->gcp);
+
+	if (!gdp->__in_fallback_attempt) {
+		ret = insert_map(res->sess_map, gdp->gcp, &gdp->txid);
+		if (ret)
+			return ret;
+	} else {
+		assert(gdp->gcp == lookup_map(res->sess_map, gdp->txid));
+	}
+
+	ret = 0;
+	if (gdp->restyp == GWP_DNS_RESTYP_PREFER_IPV6) {
+		af = AF_INET6;
+		gdp->restyp = GWP_DNS_RESTYP_IPV4_ONLY;
+		gdp->__in_fallback_attempt = true;
+	} else if (gdp->restyp == GWP_DNS_RESTYP_PREFER_IPV4) {
+		af = AF_INET;
+		gdp->restyp = GWP_DNS_RESTYP_IPV6_ONLY;
+		gdp->__in_fallback_attempt = true;
+	} else if (gdp->restyp == GWP_DNS_RESTYP_IPV6_ONLY) {
+		ret = 0;
+		af = AF_INET6;
+	} else if (gdp->restyp == GWP_DNS_RESTYP_IPV4_ONLY) {
+		ret = 0;
+		af = AF_INET;
+	} else {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	tmp = gwdns_build_query(gdp->txid, gdp->host, af, gdp->buf, gdp->buf_len);
+	if (tmp < 0) {
+		ret = (int)tmp;
+		goto err;
+	}
+
+	gdp->buf_len = (uint16_t)tmp;
+	return ret;
+
+err:
+	delete_map(res->sess_map, gdp->txid);
+	return ret;
+}
+
+void gwp_dns_res_drop_query(struct gwp_dns_resolver *res,
+			    struct gwp_conn_pair *gcp, uint16_t txid)
+{
+	assert(gcp);
+	assert(gcp == lookup_map(res->sess_map, txid));
+	delete_map(res->sess_map, txid);
+	(void)gcp;
+}
+
+int gwp_dns_res_fetch_gcp_by_payload(struct gwp_dns_resolver *res,
+				     const uint8_t buf[UDP_MSG_LIMIT],
+				     uint16_t len,
+				     struct gwp_conn_pair **gcp_p)
+{
+	uint16_t txid;
+
+	if (len < 38)
+		return -EINVAL;
+
+	memcpy(&txid, buf, 2);
+	if (txid >= res->sess_map->cap)
+		return -EINVAL;
+
+	*gcp_p = lookup_map(res->sess_map, txid);
+	if (!gcp_p)
+		return -ENOENT;
+
+	return 0;
+}
+
+int gwp_dns_res_complete_query(struct gwp_dns_resolver *res,
+				struct gwp_dns_packet *gdp,
+				uint8_t buf[UDP_MSG_LIMIT],
+				uint16_t len,
+				struct gwp_sockaddr *addr)
+{
+	struct gwdns_addrinfo_node *ai = NULL;
+	char port[sizeof("65535")];
+	uint16_t txid;
+	ssize_t r;
+
+	if (len < 38)
+		return -EINVAL;
+
+	memcpy(&txid, buf, 2);
+	if (txid >= res->sess_map->cap)
+		return -EINVAL;
+
+	if (gdp->txid != txid)
+		return -EINVAL;
+
+	if (gdp->gcp != res->sess_map->sess_map[txid])
+		return -EINVAL;
+
+	snprintf(port, sizeof(port), "%hu", gdp->port);
+	r = gwdns_parse_query(txid, port, buf, len, &ai);
+	if (!r) {
+		*addr = ai->ai_addr;
+		gwdns_free_parsed_query(ai);
+		gwp_dns_res_drop_query(res, gdp->gcp, txid);
+		return 0;
+	}
+
+	if (gdp->__in_fallback_attempt) {
+		int tmp = gwp_dns_res_prep_query(res, gdp);
+		if (!tmp)
+			return -EAGAIN;
+
+		r = tmp;
+	}
+
+	gwp_dns_res_drop_query(res, gdp->gcp, txid);
+	return (int)r;
+}
diff --git a/src/gwproxy/dns_resolver.h b/src/gwproxy/dns_resolver.h
index d4545f1..1e46efd 100644
--- a/src/gwproxy/dns_resolver.h
+++ b/src/gwproxy/dns_resolver.h
@@ -1,7 +1,9 @@
 #ifndef GWPROXY__DNS_RESOLVER_H
 #define GWPROXY__DNS_RESOLVER_H
 
+#include <gwproxy/dns_parser.h>
 #include <gwproxy/gwproxy.h>
+#include <gwproxy/dns.h>
 
 struct gwp_ctx;
 struct gwp_dns_resolver_map;
@@ -12,8 +14,36 @@ struct gwp_dns_resolver {
 	struct gwp_dns_resolver_map	*sess_map;
 };
 
+struct gwp_dns_packet {
+	bool			__in_fallback_attempt;
+	uint8_t			restyp;
+	uint16_t		txid;
+	uint16_t		buf_len;
+	uint16_t		port;
+	uint8_t			buf[UDP_MSG_LIMIT];
+	char			*host;
+	struct gwp_conn_pair	*gcp;
+};
+
 int gwp_dns_res_init(struct gwp_ctx *ctx, struct gwp_dns_resolver *gdr,
 		     const char *srv_addr);
 void gwp_dns_res_free(struct gwp_dns_resolver *gdr);
 
+int gwp_dns_res_prep_query(struct gwp_dns_resolver *res,
+			   struct gwp_dns_packet *gdp);
+
+void gwp_dns_res_drop_query(struct gwp_dns_resolver *res,
+			    struct gwp_conn_pair *gcp, uint16_t txid);
+
+int gwp_dns_res_fetch_gcp_by_payload(struct gwp_dns_resolver *res,
+				     const uint8_t buf[UDP_MSG_LIMIT],
+				     uint16_t len,
+				     struct gwp_conn_pair **gcp_p);
+
+int gwp_dns_res_complete_query(struct gwp_dns_resolver *res,
+				struct gwp_dns_packet *gdp,
+				uint8_t buf[UDP_MSG_LIMIT],
+				uint16_t len,
+				struct gwp_sockaddr *addr);
+
 #endif /* #ifndef GWPROXY__DNS_RESOLVER_H */
-- 
Alviro Iskandar Setiawan


  parent reply	other threads:[~2025-09-30  8:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-30  8:54 [PATCH gwproxy v13 0/8] Initial work on integration of DNS parser lib in gwproxy Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 1/8] gwproxy: Remove 'struct gwp_dns_query' declaration Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 2/8] gwproxy: Introduce __unused macro Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 3/8] Add DNS parser code Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 4/8] Add DNS resolver code Alviro Iskandar Setiawan
2025-09-30  8:54 ` Alviro Iskandar Setiawan [this message]
2025-09-30  8:54 ` [PATCH gwproxy v13 6/8] gwproxy: Introduce --dns-server and --raw-dns Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 7/8] epoll: Intregrate the raw DNS feature to epoll Alviro Iskandar Setiawan
2025-09-30  8:54 ` [PATCH gwproxy v13 8/8] Makefile: Introduce --use-new-dns-resolver configure option Alviro Iskandar Setiawan
2025-10-02  7:05 ` [PATCH gwproxy v13 0/8] Initial work on integration of DNS parser lib in gwproxy Ammar Faizi
2025-10-02  7:20   ` Alviro Iskandar Setiawan
2025-10-02  8:07     ` Ammar Faizi
2025-10-02  8:19       ` Alviro Iskandar Setiawan
2025-10-26 21:10         ` Ammar Faizi
2025-10-29 16:33           ` Alviro Iskandar Setiawan

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=20250930085428.717195-6-alviro.iskandar@gnuweeb.org \
    --to=alviro.iskandar@gnuweeb.org \
    --cc=ammarfaizi2@gnuweeb.org \
    --cc=gwml@vger.gnuweeb.org \
    --cc=reyuki@gnuweeb.org \
    /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