diff options
| author | Felix Fietkau | 2021-11-08 20:59:22 +0000 |
|---|---|---|
| committer | Felix Fietkau | 2021-11-08 21:01:20 +0000 |
| commit | 737970946bc0198453fa7adb7a5c55bab160dfc6 (patch) | |
| tree | be89d14ba507b445070c8c34b8231689b952b17a | |
| parent | f5ae89e8d8699a144bbdf16da859185f31d272f6 (diff) | |
| download | qosify-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-- | README | 4 | ||||
| -rw-r--r-- | map.c | 26 | ||||
| -rw-r--r-- | qosify.h | 2 |
3 files changed, 25 insertions, 7 deletions
@@ -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. @@ -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; @@ -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); |