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