Make mdns responder case-insensitive.
authorAvi <[email protected]>
Tue, 11 Mar 2025 02:18:19 +0000 (22:18 -0400)
committerFelix Fietkau <[email protected]>
Wed, 28 May 2025 22:28:57 +0000 (00:28 +0200)
From [the RFC](https://github.com/openwrt/mdnsd/blob/master/rfc6762.txt#L2532-L2550):

>  The simple rules for case-insensitivity in Unicast DNS [RFC1034]
   [RFC1035] also apply in Multicast DNS; that is to say, in name
   comparisons, the lowercase letters "a" to "z" (0x61 to 0x7A) match
   their uppercase equivalents "A" to "Z" (0x41 to 0x5A).  Hence, if a
   querier issues a query for an address record with the name
   "myprinter.local.", then a responder having an address record with
   the name "MyPrinter.local." should issue a response.  No other
   automatic equivalences should be assumed.

Fixes #15.

Signed-off-by: Felix Fietkau <[email protected]>
dns.c

diff --git a/dns.c b/dns.c
index 18210f177a11ef517952ee298eef1111dbe4f1a5..a20fb3ee17c22b724f6bbf5a710f42d14b23ec34 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -11,6 +11,7 @@
  * GNU General Public License for more details.
  */
 
+#define _GNU_SOURCE
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -458,7 +459,7 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc
 
        switch (q->type) {
        case TYPE_ANY:
-               if (!strcmp(name, mdns_hostname_local)) {
+               if (!strcasecmp(name, mdns_hostname_local)) {
                        dns_reply_a(iface, to, announce_ttl, NULL);
                        dns_reply_a_additional(iface, to, announce_ttl);
                        service_reply(iface, to, NULL, NULL, announce_ttl, is_unicast);
@@ -466,7 +467,7 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc
                break;
 
        case TYPE_PTR:
-               if (!strcmp(name, C_DNS_SD)) {
+               if (!strcasecmp(name, C_DNS_SD)) {
                        service_announce_services(iface, to, announce_ttl);
                } else {
                        if (name[0] == '_') {
@@ -486,16 +487,16 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc
 
        case TYPE_AAAA:
        case TYPE_A:
-               host = strstr(name, ".local");
+               host = strcasestr(name, ".local");
                if (host)
                        *host = '\0';
-               if (!strcmp(umdns_host_label, name)) {
+               if (!strcasecmp(umdns_host_label, name)) {
                        dns_reply_a(iface, to, announce_ttl, NULL);
                } else {
                        if (host)
                                *host = '.';
                        vlist_for_each_element(&hostnames, h, node)
-                               if (!strcmp(h->hostname, name))
+                               if (!strcasecmp(h->hostname, name))
                                        dns_reply_a(iface, to, announce_ttl, h->hostname);
                }
                break;