Coverage Report

Created: 2026-10-24 08:16

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