[PATCH v2 15/42] gresolv: Add GError for hostname lookup
Jussi Laakkonen <[email protected]> Wed, 13 Aug 2025 18:01:47 +0300
| Newsgroups | dev.linux.lists.connman |
|---|---|
| Message-ID | <[email protected]> |
Add a GError for the hostname lookup call to indicate the error as the
function should return either 0 in case of error or the source id. This
fixes the wrong returns when error happens and makes it possible to
check the error. The error message is propagated from add_query() and a
generic G_RESOLV_ERROR_ADD_QUERY error is reported as the GError code.
---
gweb/gresolv.c | 40 +++++++++++++++++++++++++++++++++++-----
gweb/gresolv.h | 8 +++++++-
gweb/gweb.c | 2 +-
plugins/vpn.c | 2 +-
src/dnsproxy.c | 4 ++--
src/timeserver.c | 2 +-
src/wpad.c | 4 ++--
tools/resolv-test.c | 2 +-
tools/wpad-test.c | 5 +++--
vpn/vpn-provider.c | 2 +-
10 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index 8101d718..e1d23f8f 100644
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -40,6 +40,9 @@
#include "gresolv.h"
+#define G_RESOLV_ERROR g_resolv_error_quark ()
+G_DEFINE_QUARK (g-resolv-error-quark, g_resolv_error)
+
struct sort_result {
int precedence;
int src_scope;
@@ -116,6 +119,7 @@ struct _GResolv {
GResolvDebugFunc debug_func;
gpointer debug_data;
+ int err;
};
#define debug(resolv, format, arg...) \
@@ -1014,9 +1018,11 @@ static gint add_query(struct resolv_lookup *lookup, const char *hostname, int ty
}
guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
- GResolvResultFunc func, gpointer user_data)
+ GResolvResultFunc func, gpointer user_data,
+ GError **error)
{
struct resolv_lookup *lookup;
+ gint err;
if (!resolv)
return 0;
@@ -1058,14 +1064,23 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
lookup->id = resolv->next_lookup_id++;
if (resolv->result_family != AF_INET6) {
- if (add_query(lookup, hostname, ns_t_a)) {
+ err = add_query(lookup, hostname, ns_t_a);
+ if (err) {
g_free(lookup);
- return -EIO;
+
+ g_set_error(error,
+ G_RESOLV_ERROR,
+ G_RESOLV_ERROR_ADD_QUERY,
+ "Failed to add query: %s",
+ g_strerror(-err));
+
+ return 0;
}
}
if (resolv->result_family != AF_INET) {
- if (add_query(lookup, hostname, ns_t_aaaa)) {
+ err = add_query(lookup, hostname, ns_t_aaaa);
+ if (err) {
if (resolv->result_family != AF_INET6) {
g_queue_remove(resolv->query_queue,
lookup->ipv4_query);
@@ -1073,7 +1088,14 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
}
g_free(lookup);
- return -EIO;
+
+ g_set_error(error,
+ G_RESOLV_ERROR,
+ G_RESOLV_ERROR_ADD_QUERY,
+ "Failed to add query: %s",
+ g_strerror(-err));
+
+ return 0;
}
}
@@ -1119,3 +1141,11 @@ bool g_resolv_set_address_family(GResolv *resolv, int family)
return true;
}
+
+int g_resolv_get_error(GResolv *resolv)
+{
+ if (!resolv)
+ return 0;
+
+ return resolv->err;
+}
diff --git a/gweb/gresolv.h b/gweb/gresolv.h
index 5e82c168..093b9a2d 100644
--- a/gweb/gresolv.h
+++ b/gweb/gresolv.h
@@ -47,6 +47,11 @@ typedef enum {
G_RESOLV_RESULT_STATUS_NO_ANSWER,
} GResolvResultStatus;
+typedef enum {
+ G_RESOLV_ERROR_ADD_QUERY,
+ G_RESOLV_ERROR_NO_ERROR,
+} GResolvError;
+
typedef void (*GResolvResultFunc)(GResolvResultStatus status,
char **results, gpointer user_data);
@@ -65,7 +70,8 @@ bool g_resolv_add_nameserver(GResolv *resolv, const char *address,
void g_resolv_flush_nameservers(GResolv *resolv);
guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
- GResolvResultFunc func, gpointer user_data);
+ GResolvResultFunc func, gpointer user_data,
+ GError **error);
bool g_resolv_cancel_lookup(GResolv *resolv, guint id);
diff --git a/gweb/gweb.c b/gweb/gweb.c
index 4dbbb4c8..4aa4416a 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -2673,7 +2673,7 @@ static guint do_request(GWeb *web, const char *url,
session->address_action = g_idle_add(already_resolved, session);
} else {
session->resolv_action = g_resolv_lookup_hostname(web->resolv,
- host, resolv_result, session);
+ host, resolv_result, session, NULL);
if (session->resolv_action <= 0) {
free_session(session);
/*
diff --git a/plugins/vpn.c b/plugins/vpn.c
index d683c67d..c0739fc1 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -243,7 +243,7 @@ static void resolv_host_addr(struct connection_data *data)
DBG("Trying to resolv %s", data->host);
data->resolv_id = g_resolv_lookup_hostname(data->resolv, data->host,
- resolv_result, data);
+ resolv_result, data, NULL);
}
static void free_config_cb_data(struct config_create_data *cb_data)
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 1dd2f7f5..71a01f6d 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -400,14 +400,14 @@ static void refresh_dns_entry(struct cache_entry *entry, char *name)
if (!entry->ipv4) {
debug("Refreshing A record for %s", name);
g_resolv_lookup_hostname(ipv4_resolve, name,
- dummy_resolve_func, NULL);
+ dummy_resolve_func, NULL, NULL);
age = 4;
}
if (!entry->ipv6) {
debug("Refreshing AAAA record for %s", name);
g_resolv_lookup_hostname(ipv6_resolve, name,
- dummy_resolve_func, NULL);
+ dummy_resolve_func, NULL, NULL);
age = 4;
}
diff --git a/src/timeserver.c b/src/timeserver.c
index d364f728..8f077307 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -204,7 +204,7 @@ static void sync_next(void)
DBG("Resolving timeserver %s", ts_current);
resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
- resolv_result, NULL);
+ resolv_result, NULL, NULL);
return;
}
diff --git a/src/wpad.c b/src/wpad.c
index e1886d2b..f3bc6282 100644
--- a/src/wpad.c
+++ b/src/wpad.c
@@ -111,7 +111,7 @@ static void wpad_result(GResolvResultStatus status,
DBG("hostname %s", wpad->hostname);
g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
- wpad_result, wpad);
+ wpad_result, wpad, NULL);
return;
@@ -176,7 +176,7 @@ int __connman_wpad_start(struct connman_service *service)
wpad->service = connman_service_ref(service);
g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
- wpad_result, wpad);
+ wpad_result, wpad, NULL);
g_hash_table_replace(wpad_list, GINT_TO_POINTER(index), wpad);
diff --git a/tools/resolv-test.c b/tools/resolv-test.c
index 1aad2841..acf4f0bd 100644
--- a/tools/resolv-test.c
+++ b/tools/resolv-test.c
@@ -146,7 +146,7 @@ int main(int argc, char *argv[])
timer = g_timer_new();
if (g_resolv_lookup_hostname(resolv, argv[1],
- resolv_result, NULL) == 0) {
+ resolv_result, NULL, NULL) == 0) {
printf("failed to start lookup\n");
return 1;
}
diff --git a/tools/wpad-test.c b/tools/wpad-test.c
index 2ecbcdae..518d42ea 100644
--- a/tools/wpad-test.c
+++ b/tools/wpad-test.c
@@ -75,7 +75,7 @@ static void resolv_result(GResolvResultStatus status,
str = g_strdup_printf("wpad.%s", ptr + 1);
- g_resolv_lookup_hostname(resolv, str, resolv_result, str);
+ g_resolv_lookup_hostname(resolv, str, resolv_result, str, NULL);
g_free(hostname);
@@ -118,7 +118,8 @@ static void start_wpad(const char *search)
hostname = g_strdup_printf("wpad.%s", domainname);
- g_resolv_lookup_hostname(resolv, hostname, resolv_result, hostname);
+ g_resolv_lookup_hostname(resolv, hostname, resolv_result, hostname,
+ NULL);
return;
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index b21e9e61..b79b7963 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -980,7 +980,7 @@ static void provider_resolv_host_addr(struct vpn_provider *provider)
vpn_provider_ref(provider);
g_resolv_lookup_hostname(provider->resolv, provider->host,
- resolv_result, provider);
+ resolv_result, provider, NULL);
}
void __vpn_provider_append_properties(struct vpn_provider *provider,
--
2.39.5