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 v12 5/8] dns_resolver: Add DNS resolution interface APIs
Date: Fri, 19 Sep 2025 01:47:27 +0700 [thread overview]
Message-ID: <20250918184730.598305-6-alviro.iskandar@gnuweeb.org> (raw)
In-Reply-To: <20250918184730.598305-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..22fac18 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);
+ delete_map(res->sess_map, txid);
+ return 0;
+ }
+
+ if (gdp->__in_fallback_attempt) {
+ int tmp = gwp_dns_res_prep_query(res, gdp);
+ if (!tmp)
+ return -EAGAIN;
+
+ r = tmp;
+ }
+
+ delete_map(res->sess_map, 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
next prev parent reply other threads:[~2025-09-18 18:47 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-18 18:47 [PATCH gwproxy v12 0/8] Initial work on integration of DNS parser lib in gwproxy Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 1/8] gwproxy: Remove 'struct gwp_dns_query' declaration Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 2/8] gwproxy: Introduce __unused macro Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 3/8] Add DNS parser code Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 4/8] Add DNS resolver code Alviro Iskandar Setiawan
2025-09-18 18:47 ` Alviro Iskandar Setiawan [this message]
2025-09-18 23:16 ` [PATCH gwproxy v12 5/8] dns_resolver: Add DNS resolution interface APIs Ammar Faizi
2025-09-18 18:47 ` [PATCH gwproxy v12 6/8] gwproxy: Introduce --dns-server and --raw-dns Alviro Iskandar Setiawan
2025-09-18 22:54 ` Ammar Faizi
2025-09-18 23:07 ` Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 7/8] epoll: Intregrate the raw DNS feature to epoll Alviro Iskandar Setiawan
2025-09-18 18:47 ` [PATCH gwproxy v12 8/8] Makefile: Introduce --use-new-dns-resolver configure option Alviro Iskandar Setiawan
2025-09-18 18:55 ` [PATCH gwproxy v12 0/8] Initial work on integration of DNS parser lib in gwproxy 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=20250918184730.598305-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