dns: allow limiting dns entry matching to cname name
authorFelix Fietkau <nbd@nbd.name>
Sun, 6 Mar 2022 21:49:59 +0000 (22:49 +0100)
committerFelix Fietkau <nbd@nbd.name>
Sun, 6 Mar 2022 21:57:04 +0000 (22:57 +0100)
Allows more precise control on how to match CNAME redirected subdomains

Signed-off-by: Felix Fietkau <nbd@nbd.name>
README
dns.c
map.c
qosify.h

diff --git a/README b/README
index 485d030290080157161d875a14f38b5279b34e1d..10d0c55b8a4d067b3d65ae9974e599c26aead763 100644 (file)
--- a/README
+++ b/README
@@ -104,9 +104,13 @@ match is one of:
 - dns:/<regex>
        POSIX.2 extended regular expression for matching hostnames
        Only works, if dns lookups are passed to qosify via the add_dns_host ubus call.
+- dns_c:...
+       Like dns:... but only matches cname entries
 
 dscp can be a raw value, or a codepoint like CS0
 Adding a + in front of the value tells qosify to only override the DSCP value if it is zero
+DNS entries are compared in the order in which they are specified in the config, using the
+first matching entry.
 
 
 Planned features:
diff --git a/dns.c b/dns.c
index 5d10c6ddf10ed19d13af28e8be2c15c57395a5cd..b943ef5030fbddd4e5142bcbb86f285425892bf3 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -169,7 +169,7 @@ dns_parse_question(struct packet *pkt, const void *hdr, uint8_t *dscp, uint32_t
                return -1;
 
        cname_cache_get(qname, dscp, seq);
-       qosify_map_lookup_dns_entry(qname, dscp, seq);
+       qosify_map_lookup_dns_entry(qname, false, dscp, seq);
 
        return 0;
 }
@@ -202,7 +202,7 @@ dns_parse_answer(struct packet *pkt, void *hdr, uint8_t *dscp, uint32_t *seq)
                              cname, sizeof(cname)) < 0)
                        return -1;
 
-               qosify_map_lookup_dns_entry(cname, dscp, seq);
+               qosify_map_lookup_dns_entry(cname, true, dscp, seq);
                cname_cache_set(cname, *dscp, *seq);
 
                return 0;
diff --git a/map.c b/map.c
index e4130204b584d9bc260463aad53a0e71d1279aff..83e119bfb89356f462136d7d31040f6cdcab5d02 100644 (file)
--- a/map.c
+++ b/map.c
@@ -406,6 +406,8 @@ int qosify_map_set_entry(enum qosify_map_id id, bool file, const char *str,
        switch (id) {
        case CL_MAP_DNS:
                data.addr.dns.pattern = str;
+               if (str[-2] == 'c')
+                       data.addr.dns.only_cname = 1;
                break;
        case CL_MAP_TCP_PORTS:
        case CL_MAP_UDP_PORTS:
@@ -525,6 +527,8 @@ qosify_map_parse_line(char *str)
 
        if (!strncmp(key, "dns:", 4))
                qosify_map_set_entry(CL_MAP_DNS, true, key + 4, dscp);
+       if (!strncmp(key, "dns_q:", 6) || !strncmp(key, "dns_c:", 6))
+               qosify_map_set_entry(CL_MAP_DNS, true, key + 6, dscp);
        if (!strncmp(key, "tcp:", 4))
                qosify_map_set_entry(CL_MAP_TCP_PORTS, true, key + 4, dscp);
        else if (!strncmp(key, "udp:", 4))
@@ -715,7 +719,7 @@ void qosify_map_gc(void)
        uloop_timeout_set(&qosify_map_timer, timeout * 1000);
 }
 
-int qosify_map_lookup_dns_entry(char *host, uint8_t *dscp, uint32_t *seq)
+int qosify_map_lookup_dns_entry(char *host, bool cname, uint8_t *dscp, uint32_t *seq)
 {
        struct qosify_map_data data = {
                .id = CL_MAP_DNS,
@@ -738,6 +742,9 @@ int qosify_map_lookup_dns_entry(char *host, uint8_t *dscp, uint32_t *seq)
                if (e->data.id != CL_MAP_DNS)
                        break;
 
+               if (!cname && e->data.addr.dns.only_cname)
+                       continue;
+
                if (e->data.addr.dns.pattern[0] == '/') {
                        if (regexec(regex, host, 0, NULL, 0) != 0)
                                continue;
@@ -763,7 +770,7 @@ int qosify_map_add_dns_host(char *host, const char *addr, const char *type, int
        int prev_timeout = qosify_map_timeout;
        uint32_t lookup_seq = 0;
 
-       if (qosify_map_lookup_dns_entry(host, &data.dscp, &lookup_seq))
+       if (qosify_map_lookup_dns_entry(host, false, &data.dscp, &lookup_seq))
                return 0;
 
        data.user = true;
index 7a598e3bebfc8edc1f48c9aa605f3afc699f61a2..bd0887999ba269939e8327f57950f6ea0f20c69b 100644 (file)
--- a/qosify.h
+++ b/qosify.h
@@ -51,7 +51,8 @@ struct qosify_map_data {
                struct in_addr ip;
                struct in6_addr ip6;
                struct {
-                       uint32_t seq;
+                       uint32_t seq : 30;
+                       uint32_t only_cname : 1;
                        const char *pattern;
                        regex_t regex;
                } dns;
@@ -90,7 +91,7 @@ void qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val);
 void qosify_map_reset_config(void);
 void qosify_map_update_config(void);
 void qosify_map_set_classes(struct blob_attr *val);
-int qosify_map_lookup_dns_entry(char *host, uint8_t *dscp, uint32_t *seq);
+int qosify_map_lookup_dns_entry(char *host, bool cname, uint8_t *dscp, uint32_t *seq);
 int qosify_map_add_dns_host(char *host, const char *addr, const char *type, int ttl);
 int map_parse_flow_config(struct qosify_flow_config *cfg, struct blob_attr *attr,
                          bool reset);