From a0740172eda65ea608a1c52bc4eef215241d44b4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 3 Nov 2021 15:24:58 +0100 Subject: [PATCH] ubus: add api for providing dns lookup results for dns regex rules Signed-off-by: Felix Fietkau --- map.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ qosify.h | 1 + ubus.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/map.c b/map.c index 7f8c20d..41db52d 100644 --- a/map.c +++ b/map.c @@ -585,6 +585,52 @@ void qosify_map_gc(void) uloop_timeout_set(&qosify_map_timer, timeout * 1000); } + +int qosify_map_add_dns_host(const char *host, const char *addr, const char *type, int ttl) +{ + struct qosify_map_data data = { + .id = CL_MAP_DNS, + .addr.dns.pattern = "", + }; + struct qosify_map_entry *e; + int prev_timeout = qosify_map_timeout; + + e = avl_find_ge_element(&map_data, &data, e, avl); + if (!e) + return 0; + + memset(&data, 0, sizeof(data)); + data.user = true; + if (!strcmp(type, "A")) + data.id = CL_MAP_IPV4_ADDR; + else if (!strcmp(type, "AAAA")) + data.id = CL_MAP_IPV6_ADDR; + else + return 0; + + if (qosify_map_fill_ip(&data, addr)) + return -1; + + 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 (ttl) + qosify_map_timeout = ttl; + data.dscp = e->data.dscp; + __qosify_map_set_entry(&data); + qosify_map_timeout = prev_timeout; + } + + return 0; +} + + void qosify_map_dump(struct blob_buf *b) { struct qosify_map_entry *e; diff --git a/qosify.h b/qosify.h index 285543a..f9d8026 100644 --- a/qosify.h +++ b/qosify.h @@ -79,6 +79,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_iface_init(void); void qosify_iface_config_update(struct blob_attr *ifaces, struct blob_attr *devs); diff --git a/ubus.c b/ubus.c index 66200c1..79ad957 100644 --- a/ubus.c +++ b/ubus.c @@ -268,6 +268,48 @@ qosify_ubus_check_devices(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +enum { + CL_DNS_HOST_NAME, + CL_DNS_HOST_TYPE, + CL_DNS_HOST_ADDR, + CL_DNS_HOST_TTL, + __CL_DNS_HOST_MAX +}; + +static const struct blobmsg_policy qosify_dns_policy[__CL_DNS_HOST_MAX] = { + [CL_DNS_HOST_NAME] = { "name", BLOBMSG_TYPE_STRING }, + [CL_DNS_HOST_TYPE] = { "type", BLOBMSG_TYPE_STRING }, + [CL_DNS_HOST_ADDR] = { "address", BLOBMSG_TYPE_STRING }, + [CL_DNS_HOST_TTL] = { "ttl", BLOBMSG_TYPE_INT32 }, +}; + +static int +qosify_ubus_add_dns_host(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__CL_DNS_HOST_MAX]; + struct blob_attr *cur; + uint32_t ttl = 0; + + blobmsg_parse(qosify_dns_policy, __CL_DNS_HOST_MAX, tb, + blobmsg_data(msg), blobmsg_len(msg)); + + if (!tb[CL_DNS_HOST_NAME] || !tb[CL_DNS_HOST_TYPE] || + !tb[CL_DNS_HOST_ADDR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if ((cur = tb[CL_DNS_HOST_TTL]) != NULL) + ttl = blobmsg_get_u32(cur); + + if (qosify_map_add_dns_host(blobmsg_get_string(tb[CL_DNS_HOST_NAME]), + blobmsg_get_string(tb[CL_DNS_HOST_ADDR]), + blobmsg_get_string(tb[CL_DNS_HOST_TYPE]), + ttl)) + return UBUS_STATUS_INVALID_ARGUMENT; + + return 0; +} static const struct ubus_method qosify_methods[] = { UBUS_METHOD_NOARG("reload", qosify_ubus_reload), @@ -277,6 +319,7 @@ static const struct ubus_method qosify_methods[] = { UBUS_METHOD("config", qosify_ubus_config, qosify_config_policy), UBUS_METHOD_NOARG("dump", qosify_ubus_dump), UBUS_METHOD_NOARG("status", qosify_ubus_status), + UBUS_METHOD("add_dns_host", qosify_ubus_add_dns_host, qosify_dns_policy), UBUS_METHOD_NOARG("check_devices", qosify_ubus_check_devices), }; -- 2.30.2