/work/toxcore/group_connection.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 | | * An implementation of massive text only group chats. |
8 | | */ |
9 | | |
10 | | #ifndef C_TOXCORE_TOXCORE_GROUP_CONNECTION_H |
11 | | #define C_TOXCORE_TOXCORE_GROUP_CONNECTION_H |
12 | | |
13 | | #include "group_common.h" |
14 | | |
15 | | /* Max number of TCP relays we share with a peer on handshake */ |
16 | 174 | #define GCC_MAX_TCP_SHARED_RELAYS 3 |
17 | | |
18 | | /** Marks a peer for deletion. If gconn is null or already marked for deletion this function has no effect. */ |
19 | | non_null(1, 2) nullable(4) |
20 | | void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Group_Exit_Type type, |
21 | | const uint8_t *part_message, uint16_t length); |
22 | | |
23 | | /** @brief Decides if message need to be put in recv_array or immediately handled. |
24 | | * |
25 | | * Return 3 if message is in correct sequence and is a fragment packet. |
26 | | * Return 2 if message is in correct sequence and may be handled immediately. |
27 | | * Return 1 if packet is out of sequence and added to recv_array. |
28 | | * Return 0 if message is a duplicate. |
29 | | * Return -1 on failure |
30 | | */ |
31 | | non_null(1, 2, 3) nullable(4) |
32 | | int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, |
33 | | const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id, |
34 | | bool direct_conn); |
35 | | |
36 | | /** @brief Handles a packet fragment. |
37 | | * |
38 | | * If the fragment is incomplete, it gets stored in the recv |
39 | | * array. Otherwise the segment is re-assembled into a complete |
40 | | * payload and processed. |
41 | | * |
42 | | * Return 1 if fragment is successfully handled and is not the end of the sequence. |
43 | | * Return 0 if fragment is the end of a sequence and successfully handled. |
44 | | * Return -1 on failure. |
45 | | */ |
46 | | non_null(1, 2, 4) nullable(5, 9) |
47 | | int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, GC_Connection *gconn, |
48 | | const uint8_t *chunk, uint16_t length, uint8_t packet_type, uint64_t message_id, |
49 | | void *userdata); |
50 | | |
51 | | /** @brief Return array index for message_id */ |
52 | | uint16_t gcc_get_array_index(uint64_t message_id); |
53 | | |
54 | | /** @brief Removes send_array item with message_id. |
55 | | * |
56 | | * Return true on success. |
57 | | */ |
58 | | non_null() |
59 | | bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id); |
60 | | |
61 | | /** @brief Sets the send_message_id and send_array_start for `gconn` to `id`. |
62 | | * |
63 | | * This should only be used to initialize a new lossless connection. |
64 | | */ |
65 | | non_null() |
66 | | void gcc_set_send_message_id(GC_Connection *gconn, uint64_t id); |
67 | | |
68 | | /** @brief Sets the received_message_id for `gconn` to `id`. */ |
69 | | non_null() |
70 | | void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id); |
71 | | |
72 | | /** |
73 | | * @brief Returns true if the ip_port is set for gconn. |
74 | | */ |
75 | | non_null() |
76 | | bool gcc_ip_port_is_set(const GC_Connection *gconn); |
77 | | |
78 | | /** |
79 | | * @brief Sets the ip_port for gconn to ipp. |
80 | | * |
81 | | * If ipp is not set this function has no effect. |
82 | | */ |
83 | | non_null(1) nullable(2) |
84 | | void gcc_set_ip_port(GC_Connection *gconn, const IP_Port *ipp); |
85 | | |
86 | | /** @brief Copies a random TCP relay node from gconn to tcp_node. |
87 | | * |
88 | | * Return true on success. |
89 | | */ |
90 | | non_null() |
91 | | bool gcc_copy_tcp_relay(const Random *rng, Node_format *tcp_node, const GC_Connection *gconn); |
92 | | |
93 | | /** @brief Saves tcp_node to gconn's list of connected tcp relays. |
94 | | * |
95 | | * If relays list is full a random node is overwritten with the new node. |
96 | | * |
97 | | * Return 0 on success. |
98 | | * Return -1 on failure. |
99 | | * Return -2 if node is already in list. |
100 | | */ |
101 | | non_null() |
102 | | int gcc_save_tcp_relay(const Random *rng, GC_Connection *gconn, const Node_format *tcp_node); |
103 | | |
104 | | /** @brief Checks for and handles messages that are in proper sequence in gconn's recv_array. |
105 | | * This should always be called after a new packet is successfully handled. |
106 | | */ |
107 | | non_null(1, 2, 3) nullable(5) |
108 | | void gcc_check_recv_array(const GC_Session *c, GC_Chat *chat, GC_Connection *gconn, uint32_t peer_number, |
109 | | void *userdata); |
110 | | |
111 | | /** @brief Attempts to re-send lossless packets that have not yet received an ack. */ |
112 | | non_null() |
113 | | void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn); |
114 | | |
115 | | /** |
116 | | * Uses public encryption key `sender_pk` and the shared secret key associated with `gconn` |
117 | | * to generate a shared 32-byte encryption key that can be used by the owners of both keys for symmetric |
118 | | * encryption and decryption. |
119 | | * |
120 | | * Puts the result in the shared session key buffer for `gconn`, which must have room for |
121 | | * CRYPTO_SHARED_KEY_SIZE bytes. This resulting shared key should be treated as a secret key. |
122 | | */ |
123 | | non_null() |
124 | | void gcc_make_session_shared_key(GC_Connection *gconn, const uint8_t *sender_pk); |
125 | | |
126 | | /** @brief Return true if we have a direct connection with `gconn`. */ |
127 | | non_null() |
128 | | bool gcc_conn_is_direct(const Mono_Time *mono_time, const GC_Connection *gconn); |
129 | | |
130 | | /** @brief Return true if a direct UDP connection is possible with `gconn`. */ |
131 | | non_null() |
132 | | bool gcc_direct_conn_is_possible(const GC_Chat *chat, const GC_Connection *gconn); |
133 | | |
134 | | /** @brief Sends a packet to the peer associated with gconn. |
135 | | * |
136 | | * This is a lower level function that does not encrypt or wrap the packet. |
137 | | * |
138 | | * Return true on success. |
139 | | */ |
140 | | non_null() |
141 | | bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *packet, uint16_t length); |
142 | | |
143 | | /** @brief Sends a lossless packet to `gconn` comprised of `data` of size `length`. |
144 | | * |
145 | | * This function will add the packet to the lossless send array, encrypt/wrap it using the |
146 | | * shared key associated with `gconn`, and try to send it over the wire. |
147 | | * |
148 | | * Return 0 if the packet was successfully encrypted and added to the send array. |
149 | | * Return -1 if the packet couldn't be added to the send array. |
150 | | * Return -2 if the packet failed to be wrapped or encrypted. |
151 | | */ |
152 | | non_null(1, 2) nullable(3) |
153 | | int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length, |
154 | | uint8_t packet_type); |
155 | | |
156 | | /** @brief Splits a lossless packet up into fragments, wraps each fragment in a GP_FRAGMENT |
157 | | * header, encrypts them, and send them in succession. |
158 | | * |
159 | | * This function will first try to add each packet fragment to the send array as an atomic |
160 | | * unit. If any chunk fails to be added the process will be reversed and an error will be |
161 | | * returned. Otherwise it will then try to send all the fragments in succession. |
162 | | * |
163 | | * Return true if all fragments are successfully added to the send array. |
164 | | */ |
165 | | non_null() |
166 | | bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, |
167 | | uint16_t length, uint8_t packet_type); |
168 | | |
169 | | |
170 | | /** @brief Encrypts `data` of `length` bytes, designated by `message_id`, using the shared key |
171 | | * associated with `gconn` and sends lossless packet over the wire. |
172 | | * |
173 | | * This function does not add the packet to the send array. |
174 | | * |
175 | | * Return 0 on success. |
176 | | * Return -1 if packet wrapping and encryption fails. |
177 | | * Return -2 if the packet fails to send. |
178 | | */ |
179 | | non_null(1, 2) nullable(3) |
180 | | int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data, |
181 | | uint16_t length, uint64_t message_id, uint8_t packet_type); |
182 | | |
183 | | /** @brief Called when a peer leaves the group. */ |
184 | | non_null() |
185 | | void gcc_peer_cleanup(GC_Connection *gconn); |
186 | | |
187 | | /** @brief Called on group exit. */ |
188 | | non_null() |
189 | | void gcc_cleanup(const GC_Chat *chat); |
190 | | |
191 | | #endif /* C_TOXCORE_TOXCORE_GROUP_CONNECTION_H */ |