Coverage Report

Created: 2024-01-26 01:52

/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 */