Coverage Report

Created: 2025-10-08 19:34

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