summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau2021-11-08 20:59:22 +0000
committerFelix Fietkau2021-11-08 21:01:20 +0000
commit737970946bc0198453fa7adb7a5c55bab160dfc6 (patch)
treebe89d14ba507b445070c8c34b8231689b952b17a
parentf5ae89e8d8699a144bbdf16da859185f31d272f6 (diff)
downloadqosify-737970946bc0198453fa7adb7a5c55bab160dfc6.tar.gz
map: default to fnmatch matching for dns patterns. support regex via leading /
Simplifies writing DNS matching rules Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--README4
-rw-r--r--map.c26
-rw-r--r--qosify.h2
3 files changed, 25 insertions, 7 deletions
diff --git a/README b/README
index 98b407f..6a8034f 100644
--- a/README
+++ b/README
@@ -99,7 +99,9 @@ match is one of:
IPv4 address, e.g. 1.1.1.1
- <ipv6addr>
IPv6 address, e.g. ff01::1
-- dns:<regex>
+- dns:<pattern>
+ fnmatch() pattern supporting * and ? as wildcard characters
+- 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.
diff --git a/map.c b/map.c
index afca0f5..52f4337 100644
--- a/map.c
+++ b/map.c
@@ -9,6 +9,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
+#include <fnmatch.h>
#include <libubox/uloop.h>
@@ -225,6 +226,7 @@ __qosify_map_alloc_entry(struct qosify_map_data *data)
{
struct qosify_map_entry *e;
char *pattern;
+ char *c;
if (data->id < CL_MAP_DNS) {
e = calloc(1, sizeof(*e));
@@ -236,8 +238,13 @@ __qosify_map_alloc_entry(struct qosify_map_data *data)
e = calloc_a(sizeof(*e), &pattern, strlen(data->addr.dns.pattern) + 1);
strcpy(pattern, data->addr.dns.pattern);
e->data.addr.dns.pattern = pattern;
- if (regcomp(&e->data.addr.dns.regex, pattern,
- REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
+
+ for (c = pattern; *c; c++)
+ *c = tolower(*c);
+
+ if (pattern[0] == '/' &&
+ regcomp(&e->data.addr.dns.regex, pattern + 1,
+ REG_EXTENDED | REG_NOSUB)) {
free(e);
return NULL;
}
@@ -622,7 +629,7 @@ void qosify_map_gc(void)
}
-int qosify_map_add_dns_host(const char *host, const char *addr, const char *type, int ttl)
+int qosify_map_add_dns_host(char *host, const char *addr, const char *type, int ttl)
{
struct qosify_map_data data = {
.id = CL_MAP_DNS,
@@ -630,6 +637,7 @@ int qosify_map_add_dns_host(const char *host, const char *addr, const char *type
};
struct qosify_map_entry *e;
int prev_timeout = qosify_map_timeout;
+ char *c;
e = avl_find_ge_element(&map_data, &data, e, avl);
if (!e)
@@ -647,14 +655,22 @@ int qosify_map_add_dns_host(const char *host, const char *addr, const char *type
if (qosify_map_fill_ip(&data, addr))
return -1;
+ for (c = host; *c; c++)
+ *c = tolower(*c);
+
avl_for_element_to_last(&map_data, e, e, avl) {
regex_t *regex = &e->data.addr.dns.regex;
if (e->data.id != CL_MAP_DNS)
return 0;
- if (regexec(regex, host, 0, NULL, 0) != 0)
- continue;
+ if (e->data.addr.dns.pattern[0] == '/') {
+ if (regexec(regex, host, 0, NULL, 0) != 0)
+ continue;
+ } else {
+ if (fnmatch(e->data.addr.dns.pattern, host, 0))
+ continue;
+ }
if (ttl)
qosify_map_timeout = ttl;
diff --git a/qosify.h b/qosify.h
index 16d4813..76cf87c 100644
--- a/qosify.h
+++ b/qosify.h
@@ -80,7 +80,7 @@ void qosify_map_dump(struct blob_buf *b);
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);
-int qosify_map_add_dns_host(const char *host, const char *addr, const char *type, int ttl);
+int qosify_map_add_dns_host(char *host, const char *addr, const char *type, int ttl);
int qosify_iface_init(void);
void qosify_iface_config_update(struct blob_attr *ifaces, struct blob_attr *devs);