From: Felix Fietkau Date: Mon, 8 Nov 2021 20:59:22 +0000 (+0100) Subject: map: default to fnmatch matching for dns patterns. support regex via leading / X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=737970946bc0198453fa7adb7a5c55bab160dfc6;p=project%2Fqosify.git map: default to fnmatch matching for dns patterns. support regex via leading / Simplifies writing DNS matching rules Signed-off-by: Felix Fietkau --- 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 - IPv6 address, e.g. ff01::1 -- dns: +- dns: + fnmatch() pattern supporting * and ? as wildcard characters +- dns:/ 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 #include #include +#include #include @@ -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);