Initial Release
[project/omcproxy.git] / src / groups.h
1 /*
2 * Author: Steven Barth <steven at midlink.org>
3 *
4 * Copyright 2015 Deutsche Telekom AG
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #pragma once
21
22 #include <libubox/list.h>
23 #include <libubox/avl.h>
24 #include <libubox/uloop.h>
25 #include <arpa/inet.h>
26 #include "omcproxy.h"
27
28 struct group {
29 struct avl_node node;
30 struct in6_addr addr;
31 struct list_head sources;
32 size_t source_count;
33 omgp_time_t exclude_until;
34 omgp_time_t compat_v2_until;
35 omgp_time_t compat_v1_until;
36 omgp_time_t next_generic_transmit;
37 omgp_time_t next_source_transmit;
38 int retransmit;
39 };
40
41 struct group_source {
42 struct list_head head;
43 struct in6_addr addr;
44 omgp_time_t include_until;
45 int retransmit;
46 };
47
48 struct groups_config {
49 omgp_time_t query_response_interval;
50 omgp_time_t query_interval;
51 omgp_time_t last_listener_query_interval;
52 int robustness;
53 int last_listener_query_count;
54 };
55
56 struct groups {
57 struct groups_config cfg_v4;
58 struct groups_config cfg_v6;
59 struct avl_tree groups;
60 struct uloop_timeout timer;
61 size_t source_limit;
62 size_t group_limit;
63 void (*cb_query)(struct groups *g, const struct in6_addr *addr,
64 const struct list_head *sources, bool suppress);
65 void (*cb_update)(struct groups *g, struct group *group, omgp_time_t now);
66 };
67
68
69 void groups_init(struct groups *groups);
70 void groups_deinit(struct groups *groups);
71
72
73 enum groups_update {
74 UPDATE_UNSPEC,
75 UPDATE_IS_INCLUDE = 1,
76 UPDATE_IS_EXCLUDE = 2,
77 UPDATE_TO_IN = 3,
78 UPDATE_TO_EX = 4,
79 UPDATE_ALLOW = 5,
80 UPDATE_BLOCK = 6,
81 UPDATE_REPORT = 7,
82 UPDATE_REPORT_V1 = 8,
83 UPDATE_DONE = 9,
84 UPDATE_SET_IN = 0x11,
85 UPDATE_SET_EX = 0x12,
86 };
87
88 void groups_update_config(struct groups *groups, bool v6,
89 omgp_time_t query_response_interval, omgp_time_t query_interval, int robustness);
90
91 void groups_update_timers(struct groups *groups,
92 const struct in6_addr *groupaddr,
93 const struct in6_addr *addrs, size_t len);
94
95 void groups_update_state(struct groups *groups,
96 const struct in6_addr *groupaddr,
97 const struct in6_addr *addrs, size_t len,
98 enum groups_update update);
99
100 void groups_synthesize_events(struct groups *groups);
101
102 // Groups user query API
103
104 static inline bool group_is_included(const struct group *group, omgp_time_t time)
105 {
106 return group->exclude_until <= time;
107 }
108
109 static inline bool source_is_included(const struct group_source *source, omgp_time_t time)
110 {
111 return source->include_until > time;
112 }
113
114 #define groups_for_each_group(group, groupsp) \
115 avl_for_each_element(&(groupsp)->groups, group, node)
116
117 #define group_for_each_source(source, group) \
118 list_for_each_entry(source, &(group)->sources, head)
119
120 #define group_for_each_active_source(source, group, time) \
121 list_for_each_entry(source, &group->sources, head) \
122 if (source_is_included(source, time) == group_is_included(group, time))
123
124 const struct group* groups_get(struct groups *groups, const struct in6_addr *addr);
125 bool groups_includes_group(struct groups *groups, const struct in6_addr *addr,
126 const struct in6_addr *src, omgp_time_t time);