1.26 src/dnsproxy.c fails to process (probably CNAME) answers from
certain types of external DNS servers, and thus it cannot resolve
host-only queries such as "www" at all or at least correctly depending
on the answer content and format. If the default domain list has
"company.com," it is expected to be resolved as if it were a
"www.company.com" query, but dnsproxy cannot perform this with certain
types of external DNS servers.
This may be related to the following threads:
https://lists.connman.net/pipermail/connman/2014-July/017338.html
https://lists.connman.net/pipermail/connman/2014-July/017340.html
https://lists.connman.net/pipermail/connman/2014-July/017346.html
I found answer messages from two versions of BIND fail in different modes:
BIND 9.3.2's answer is misjudged as a "Corrupted packet" probably
because strip_domain() unexpectedly encounters a compressed label (i.e.
0xc000+offset) (in an NS record?).
BIND 9.7.3's answer is ignored and discarded because it contains a
dns_type of ns_t_ns, which uncompress() ignores and discards.
Both of the Linux BIND servers above have been in production use for
several years with no unhappy resolvers (except connmand) as far as I know.
I found a corporate Windows DNS server is compatible with connman-1.26
and partial domains are resolved expectedly.
Furthermore, ns_resolv() appends search domains and submits additional
queries only if the original query is for a single-label partial domain
such as "www." This seems to disagree with glibc getaddrinfo(3) with
resolv.conf having a domain/search directive, which always submits
queries for the original and domain-appended domains to the external DNS
server(s) regardless of the original query (multi- or single-label).
This appears more reasonable for resolving multi-label partial domains
such as "host.zone" with a default domain of "company.com." I notice
that getaddrinfo(3) even submits "www.company.com" and
"www.company.com.company.com" queries if the original query is for
"www.company.com" (i.e. FQDN) and resolv.conf's domain/search directive
has "company.com" in its list.
The attached Quick-n-Dirty(TM) patch, when proxy failures mentioned
above are detected, makes connmand fall back to nodnsproxy mode and
rewrites resolv.conf so that resolvers will later query directly to
external DNS servers (proxy mode is preferred and the default, if
possible, for its internal cache).
hiro
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 5ddb813..51a44ee 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -1865,6 +1865,9 @@ static char *uncompress(int16_t field_count, char *start, char *end,
*/
len_ptr[0] = total_len << 8;
len_ptr[1] = total_len & 0xff;
+ } else {
+ restart_noproxy();
+ goto out;
}
*uncompressed_ptr = uptr;
@@ -1915,6 +1918,8 @@ static int strip_domains(char *name, char *answers, int maxlen)
return end - start;
}
+extern void restart_noproxy(void);
+
static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
struct server_data *data)
{
@@ -2080,6 +2085,7 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
uptr - answers);
if (new_len < 0) {
DBG("Corrupted packet");
+ restart_noproxy();
return -EINVAL;
}
diff --git a/src/resolver.c b/src/resolver.c
index 01e7c0e..c0c1076 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -91,6 +91,12 @@ static int resolvfile_export(void)
content = g_string_new("# Generated by Connection Manager\n");
+ if (dnsproxy_enabled) {/* Bypass all the crappy stuff. */
+ g_string_append_printf(content,
+ "nameserver 127.0.0.1\nnameserver ::1\n");
+ goto put;
+ }
+
/*
* Domains and nameservers are added in reverse so that the most
* recently appended entry is the primary one. No more than
@@ -127,7 +133,7 @@ static int resolvfile_export(void)
entry->server);
count++;
}
-
+put:
old_umask = umask(022);
fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
@@ -157,6 +163,19 @@ done:
return err;
}
+void restart_noproxy(void)
+{
+ int index = connman_inet_ifindex("lo");
+
+ if (!dnsproxy_enabled)
+ return;
+
+ __connman_resolvfile_remove(index, NULL, "::1");
+ __connman_resolvfile_remove(index, NULL, "127.0.0.1");
+ dnsproxy_enabled = false;
+ resolvfile_export();
+}
+
int __connman_resolvfile_append(int index, const char *domain,
const char *server)
{
@@ -229,7 +248,7 @@ static void append_fallback_nameservers(void)
if (dnsproxy_enabled) {
__connman_dnsproxy_append(entry->index, entry->domain,
entry->server);
- } else {
+ } /*else*/ {
__connman_resolvfile_append(entry->index,
entry->domain, entry->server);
}
@@ -251,7 +270,7 @@ static void remove_fallback_nameservers(void)
if (dnsproxy_enabled) {
__connman_dnsproxy_remove(entry->index, entry->domain,
entry->server);
- } else {
+ } /*else*/ {
__connman_resolvfile_remove(entry->index,
entry->domain, entry->server);
}
@@ -270,7 +289,7 @@ static void remove_entries(GSList *entries)
if (dnsproxy_enabled) {
__connman_dnsproxy_remove(entry->index, entry->domain,
entry->server);
- } else {
+ } /*else*/ {
__connman_resolvfile_remove(entry->index, entry->domain,
entry->server);
}
@@ -397,7 +416,7 @@ static int append_resolver(int index, const char *domain,
if (dnsproxy_enabled)
__connman_dnsproxy_append(entry->index, domain, server);
- else
+ /*else*/
__connman_resolvfile_append(entry->index, domain, server);
return 0;
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman