map: increase active timeout to 300
[project/qosify.git] / map.c
diff --git a/map.c b/map.c
index 7f8c20dcb0c215656a19da58c3c1a30296e8b490..afca0f5234d47a24b8bc6ef1741aaffe393af605 100644 (file)
--- a/map.c
+++ b/map.c
@@ -21,7 +21,8 @@ static AVL_TREE(map_data, qosify_map_entry_cmp, false, NULL);
 static LIST_HEAD(map_files);
 static uint32_t next_timeout;
 static uint8_t qosify_dscp_default[2] = { 0xff, 0xff };
-int qosify_map_timeout = 3600;
+int qosify_map_timeout;
+int qosify_active_timeout;
 struct qosify_config config;
 
 struct qosify_map_file {
@@ -67,6 +68,8 @@ static const struct {
        { "AF43", 38 },
        { "EF", 46 },
        { "VA", 44 },
+       { "LE", 1 },
+       { "DF", 0 },
 };
 
 static void qosify_map_timer_cb(struct uloop_timeout *t)
@@ -281,8 +284,14 @@ static void __qosify_map_set_entry(struct qosify_map_data *data)
                e->data.dscp = e->data.file_dscp;
        }
 
-       if (e->data.dscp != prev_dscp && data->id < CL_MAP_DNS)
-               bpf_map_update_elem(fd, &data->addr, &e->data.dscp, BPF_ANY);
+       if (e->data.dscp != prev_dscp && data->id < CL_MAP_DNS) {
+               struct qosify_ip_map_val val = {
+                       .dscp = e->data.dscp,
+                       .seen = 1,
+               };
+
+               bpf_map_update_elem(fd, &data->addr, &val, BPF_ANY);
+       }
 
        if (add) {
                if (qosify_map_timeout == ~0 || file) {
@@ -523,6 +532,7 @@ void qosify_map_reset_config(void)
        qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, 0);
        qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, 0);
        qosify_map_timeout = 3600;
+       qosify_active_timeout = 300;
 
        memset(&config, 0, sizeof(config));
        config.dscp_prio = 0xff;
@@ -552,6 +562,29 @@ static void qosify_map_free_entry(struct qosify_map_entry *e)
        free(e);
 }
 
+static bool
+qosify_map_entry_refresh_timeout(struct qosify_map_entry *e)
+{
+       struct qosify_ip_map_val val;
+       int fd = qosify_map_fds[e->data.id];
+
+       if (e->data.id != CL_MAP_IPV4_ADDR &&
+           e->data.id != CL_MAP_IPV6_ADDR)
+               return false;
+
+       if (bpf_map_lookup_elem(fd, &e->data.addr, &val))
+               return false;
+
+       if (!val.seen)
+               return false;
+
+       e->timeout = qosify_gettime() + qosify_active_timeout;
+       val.seen = 0;
+       bpf_map_update_elem(fd, &e->data.addr, &val, BPF_ANY);
+
+       return true;
+}
+
 void qosify_map_gc(void)
 {
        struct qosify_map_entry *e, *tmp;
@@ -564,6 +597,9 @@ void qosify_map_gc(void)
 
                if (e->data.user && e->timeout != ~0) {
                        cur_timeout = e->timeout - cur_time;
+                       if (cur_timeout <= 0 &&
+                           qosify_map_entry_refresh_timeout(e))
+                               cur_timeout = e->timeout - cur_time;
                        if (cur_timeout <= 0) {
                                e->data.user = false;
                                e->data.dscp = e->data.file_dscp;
@@ -585,6 +621,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;