/work/toxcore/group_announce.h
Line | Count | Source |
1 | | /* SPDX-License-Identifier: GPL-3.0-or-later |
2 | | * Copyright © 2016-2020 The TokTok team. |
3 | | * Copyright © 2015 Tox project. |
4 | | */ |
5 | | |
6 | | /** |
7 | | * Similar to ping.h, but designed for group chat purposes |
8 | | */ |
9 | | #ifndef C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H |
10 | | #define C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H |
11 | | |
12 | | #include <stdbool.h> |
13 | | |
14 | | #include "DHT.h" |
15 | | |
16 | | #ifdef __cplusplus |
17 | | extern "C" { |
18 | | #endif |
19 | | |
20 | | /* The maximum number of announces to save for a particular group chat. */ |
21 | 60.5k | #define GCA_MAX_SAVED_ANNOUNCES_PER_GC 16 |
22 | | |
23 | | /* Maximum number of TCP relays that can be in an announce. */ |
24 | 8.47k | #define GCA_MAX_ANNOUNCED_TCP_RELAYS 1 |
25 | | |
26 | | /* Maximum number of announces we can send in an announce response. */ |
27 | 6.82k | #define GCA_MAX_SENT_ANNOUNCES 4 |
28 | | |
29 | | /* Maximum size of an announce. */ |
30 | 7.25k | #define GCA_ANNOUNCE_MAX_SIZE (ENC_PUBLIC_KEY_SIZE + 1 + 1 + (PACKED_NODE_SIZE_IP6 * 2)) |
31 | | |
32 | | /* Maximum size of a public announce. */ |
33 | 276 | #define GCA_PUBLIC_ANNOUNCE_MAX_SIZE (ENC_PUBLIC_KEY_SIZE + GCA_ANNOUNCE_MAX_SIZE) |
34 | | |
35 | | typedef struct GC_Announce GC_Announce; |
36 | | typedef struct GC_Peer_Announce GC_Peer_Announce; |
37 | | typedef struct GC_Announces GC_Announces; |
38 | | typedef struct GC_Announces_List GC_Announces_List; |
39 | | typedef struct GC_Public_Announce GC_Public_Announce; |
40 | | |
41 | | /* Base announce. */ |
42 | | struct GC_Announce { |
43 | | Node_format tcp_relays[GCA_MAX_ANNOUNCED_TCP_RELAYS]; |
44 | | uint8_t tcp_relays_count; |
45 | | bool ip_port_is_set; |
46 | | IP_Port ip_port; |
47 | | uint8_t peer_public_key[ENC_PUBLIC_KEY_SIZE]; |
48 | | }; |
49 | | |
50 | | /* Peer announce for specific group. */ |
51 | | struct GC_Peer_Announce { |
52 | | GC_Announce base_announce; |
53 | | uint64_t timestamp; |
54 | | }; |
55 | | |
56 | | /* Used for announces in public groups. */ |
57 | | struct GC_Public_Announce { |
58 | | GC_Announce base_announce; |
59 | | uint8_t chat_public_key[ENC_PUBLIC_KEY_SIZE]; |
60 | | }; |
61 | | |
62 | | /* A linked list that holds all announces for a particular group. */ |
63 | | struct GC_Announces { |
64 | | uint8_t chat_id[CHAT_ID_SIZE]; |
65 | | uint64_t index; |
66 | | uint64_t last_announce_received_timestamp; |
67 | | |
68 | | GC_Peer_Announce peer_announces[GCA_MAX_SAVED_ANNOUNCES_PER_GC]; |
69 | | |
70 | | GC_Announces *next_announce; |
71 | | GC_Announces *prev_announce; |
72 | | }; |
73 | | |
74 | | /* A list of all announces. */ |
75 | | struct GC_Announces_List { |
76 | | GC_Announces *root_announces; |
77 | | uint64_t last_timeout_check; |
78 | | }; |
79 | | |
80 | | |
81 | | /** @brief Returns a new group announces list. |
82 | | * |
83 | | * The caller is responsible for freeing the memory with `kill_gca`. |
84 | | */ |
85 | | GC_Announces_List *new_gca_list(void); |
86 | | |
87 | | /** @brief Frees all dynamically allocated memory associated with `announces_list`. */ |
88 | | nullable(1) |
89 | | void kill_gca(GC_Announces_List *announces_list); |
90 | | |
91 | | /** @brief Iterates through the announces list and removes announces that are considered stale. |
92 | | * |
93 | | * @param gc_announces_list The list of announces to iterate. |
94 | | * |
95 | | * This function should be called from the main loop, and will iterate the list a |
96 | | * maxmimum of once per second. |
97 | | */ |
98 | | non_null() |
99 | | void do_gca(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list); |
100 | | |
101 | | /** @brief Frees all dynamically allocated memory associated with an announces list entry. |
102 | | * |
103 | | * @param gc_announces_list The announces list we want to search through. |
104 | | * @param chat_id The chat ID that designates the entry we want to remove. |
105 | | */ |
106 | | non_null() |
107 | | void cleanup_gca(GC_Announces_List *gc_announces_list, const uint8_t *chat_id); |
108 | | |
109 | | /** @brief Puts a set of announces from the announces list in supplied list. |
110 | | * |
111 | | * @param gc_announces_list The announces list we want to search for entries in. |
112 | | * @param gc_announces An empty announces list that will be filled with matches. |
113 | | * @param max_nodes The maximum number of matches that we want to add to the list. |
114 | | * @param chat_id The chat ID associated with the announces that we want to add. |
115 | | * @param except_public_key The public key associated with announces that we want to ignore. |
116 | | * |
117 | | * @return the number of added nodes on success. |
118 | | * @retval -1 on failure. |
119 | | */ |
120 | | non_null() |
121 | | int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *gc_announces, uint8_t max_nodes, |
122 | | const uint8_t *chat_id, const uint8_t *except_public_key); |
123 | | |
124 | | /** @brief Adds a public_announce to list of announces. |
125 | | * |
126 | | * @param gc_announces_list The announces list that we want to add an entry to. |
127 | | * @param public_announce The public announce that we want to add. |
128 | | * |
129 | | * @return the peer announce on success. |
130 | | * @retval null on failure. |
131 | | */ |
132 | | non_null() |
133 | | GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list, |
134 | | const GC_Public_Announce *public_announce); |
135 | | |
136 | | /** @brief Packs an announce into a data buffer. |
137 | | * |
138 | | * @param data The data buffer being packed. |
139 | | * @param length The size in bytes of the data buffer. Must be at least GCA_ANNOUNCE_MAX_SIZE. |
140 | | * @param announce The announce being packed into the data buffer. |
141 | | * |
142 | | * @return the size of the packed data on success. |
143 | | * @retval -1 on failure. |
144 | | */ |
145 | | non_null() |
146 | | int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const GC_Announce *announce); |
147 | | |
148 | | /** @brief Returns the number of bytes needed for a buff in which to pack `count` announces. */ |
149 | | uint16_t gca_pack_announces_list_size(uint16_t count); |
150 | | |
151 | | /** @brief Packs a list of announces into a data buffer. |
152 | | * |
153 | | * @param data The data buffer being packed. |
154 | | * @param length The size in bytes of the data buffer. Use gca_pack_announces_list_size to get the |
155 | | * required length. |
156 | | * @param announces The announces to be packed into the data buffer. |
157 | | * @param announces_count The number of announces in the announces list. |
158 | | * @param processed If non-null, will contain the number of bytes packed (only on success). |
159 | | * |
160 | | * @return the number of packed announces on success. |
161 | | * @retval -1 on failure. |
162 | | */ |
163 | | non_null(1, 2, 4) nullable(6) |
164 | | int gca_pack_announces_list(const Logger *log, uint8_t *data, uint16_t length, const GC_Announce *announces, |
165 | | uint8_t announces_count, size_t *processed); |
166 | | |
167 | | /** @brief Unpacks packed announces from a data buffer into a supplied list. |
168 | | * |
169 | | * @param data The data buffer to unpack from. |
170 | | * @param length The size of the data buffer. |
171 | | * @param announces The announces list that the data buffer will be unpacked to. |
172 | | * @param max_count The maximum number of announces to unpack. |
173 | | * |
174 | | * @return the number of unpacked announces on success. |
175 | | * @retval -1 on failure. |
176 | | */ |
177 | | non_null() |
178 | | int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t length, GC_Announce *announces, |
179 | | uint8_t max_count); |
180 | | |
181 | | /** @brief Packs a public announce into a data buffer. |
182 | | * |
183 | | * @param data The data buffer being packed. |
184 | | * @param length The size in bytes of the data buffer. Must be at least GCA_PUBLIC_ANNOUNCE_MAX_SIZE. |
185 | | * @param public_announce The public announce being packed into the data buffer. |
186 | | * |
187 | | * @return the size of the packed data on success. |
188 | | * @retval -1 on failure. |
189 | | */ |
190 | | non_null() |
191 | | int gca_pack_public_announce(const Logger *log, uint8_t *data, uint16_t length, |
192 | | const GC_Public_Announce *public_announce); |
193 | | |
194 | | /** @brief Unpacks a public announce from a data buffer into a supplied public announce. |
195 | | * |
196 | | * @param data The data buffer to unpack from. |
197 | | * @param length The size of the data buffer. |
198 | | * @param public_announce The public announce to unpack the data buffer into. |
199 | | * |
200 | | * @return the size of the unpacked data on success. |
201 | | * @retval -1 on failure. |
202 | | */ |
203 | | non_null() |
204 | | int gca_unpack_public_announce(const Logger *log, const uint8_t *data, uint16_t length, |
205 | | GC_Public_Announce *public_announce); |
206 | | |
207 | | /** @brief Returns true if the announce is valid. |
208 | | * |
209 | | * An announce is considered valid if there is at least one TCP relay, or the ip_port is set. |
210 | | */ |
211 | | non_null() |
212 | | bool gca_is_valid_announce(const GC_Announce *announce); |
213 | | |
214 | | #ifdef __cplusplus |
215 | | } /* extern "C" */ |
216 | | #endif |
217 | | |
218 | | #endif /* C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H */ |