aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_tunnel.c')
-rw-r--r--src/messenger/gnunet-service-messenger_tunnel.c381
1 files changed, 0 insertions, 381 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c
deleted file mode 100644
index 80d8dfa5e..000000000
--- a/src/messenger/gnunet-service-messenger_tunnel.c
+++ /dev/null
@@ -1,381 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @author Tobias Frisch
22 * @file src/messenger/gnunet-service-messenger_tunnel.c
23 * @brief GNUnet MESSENGER service
24 */
25
26#include "gnunet-service-messenger_tunnel.h"
27
28#include "gnunet-service-messenger_handle.h"
29#include "gnunet-service-messenger_message_recv.h"
30#include "gnunet-service-messenger_message_store.h"
31#include "gnunet-service-messenger_operation_store.h"
32#include "gnunet-service-messenger_operation.h"
33#include "messenger_api_util.h"
34
35struct GNUNET_MESSENGER_SrvTunnel*
36create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door)
37{
38 GNUNET_assert((room) && (door));
39
40 struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_new(struct GNUNET_MESSENGER_SrvTunnel);
41
42 tunnel->room = room;
43 tunnel->channel = NULL;
44
45 tunnel->peer = GNUNET_PEER_intern (door);
46
47 tunnel->messenger_version = 0;
48
49 tunnel->peer_message = NULL;
50
51 init_message_state(&(tunnel->state));
52
53 return tunnel;
54}
55
56void
57destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
58{
59 GNUNET_assert(tunnel);
60
61 if (tunnel->channel)
62 GNUNET_CADET_channel_destroy (tunnel->channel);
63
64 GNUNET_PEER_change_rc (tunnel->peer, -1);
65
66 if (tunnel->peer_message)
67 GNUNET_free(tunnel->peer_message);
68
69 clear_message_state(&(tunnel->state));
70
71 GNUNET_free(tunnel);
72}
73
74void
75bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
76{
77 GNUNET_assert(tunnel);
78
79 if (tunnel->channel)
80 delayed_disconnect_channel (tunnel->channel);
81
82 tunnel->channel = channel;
83}
84
85extern void
86callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room, void *cls);
87
88void
89callback_tunnel_disconnect (void *cls, const struct GNUNET_CADET_Channel *channel)
90{
91 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
92
93 if (tunnel)
94 {
95 tunnel->channel = NULL;
96
97 callback_room_disconnect (tunnel->room, cls);
98 }
99}
100
101extern int
102callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, void *cls,
103 struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash);
104
105int
106check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
107{
108 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
109
110 if (!tunnel)
111 return GNUNET_SYSERR;
112
113 const uint16_t length = ntohs (header->size) - sizeof(*header);
114 const char *buffer = (const char*) &header[1];
115
116 struct GNUNET_MESSENGER_Message message;
117
118 if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN))
119 {
120 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length);
121 return GNUNET_SYSERR;
122 }
123
124 uint16_t padding = 0;
125
126 if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding))
127 {
128 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n");
129 return GNUNET_SYSERR;
130 }
131
132 struct GNUNET_HashCode hash;
133 hash_message (&message, length - padding, buffer, &hash);
134
135 return callback_verify_room_message (tunnel->room, cls, &message, &hash);
136}
137
138extern int
139update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
140 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
141
142extern void
143callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle,
144 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
145
146static void
147update_tunnel_last_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_HashCode *hash)
148{
149 struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(tunnel->room);
150
151 const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)?
152 GNUNET_YES : GNUNET_NO
153 );
154
155 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(tunnel->room);
156
157 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
158
159 if (message)
160 update_message_state(&(tunnel->state), requested, message, hash);
161}
162
163void
164handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
165{
166 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
167
168 const uint16_t length = ntohs (header->size) - sizeof(*header);
169 const char *buffer = (const char*) &header[1];
170
171 struct GNUNET_MESSENGER_Message message;
172 struct GNUNET_HashCode hash;
173
174 uint16_t padding = 0;
175
176 decode_message (&message, length, buffer, GNUNET_YES, &padding);
177 hash_message (&message, length - padding, buffer, &hash);
178
179 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n",
180 GNUNET_MESSENGER_name_of_kind(message.header.kind));
181
182 if (!tunnel)
183 return;
184
185 const int new_message = update_room_message (
186 tunnel->room, copy_message (&message), &hash
187 );
188
189 if (GNUNET_YES != new_message)
190 goto receive_done;
191
192 update_tunnel_last_message (tunnel, &hash);
193
194 int forward_message = GNUNET_YES;
195
196 switch (message.header.kind)
197 {
198 case GNUNET_MESSENGER_KIND_INFO:
199 forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash);
200 break;
201 case GNUNET_MESSENGER_KIND_PEER:
202 forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash);
203 break;
204 case GNUNET_MESSENGER_KIND_REQUEST:
205 forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash);
206 break;
207 default:
208 break;
209 }
210
211 if (GNUNET_YES == forward_message)
212 {
213 forward_room_message (tunnel->room, tunnel, &message, &hash);
214 callback_room_handle_message (tunnel->room, NULL, &message, &hash);
215 }
216
217receive_done:
218 GNUNET_CADET_receive_done (tunnel->channel);
219}
220
221int
222connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
223{
224 GNUNET_assert(tunnel);
225
226 if (tunnel->channel)
227 return GNUNET_NO;
228
229 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
230
231 struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room);
232 const struct GNUNET_HashCode *key = get_room_key (tunnel->room);
233
234 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI,
235 struct GNUNET_MessageHeader, NULL),
236 GNUNET_MQ_handler_end() };
237
238 tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, key, NULL, callback_tunnel_disconnect, handlers);
239
240 return GNUNET_YES;
241}
242
243void
244disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
245{
246 GNUNET_assert(tunnel);
247
248 if (tunnel->channel)
249 {
250 delayed_disconnect_channel (tunnel->channel);
251
252 tunnel->channel = NULL;
253 }
254}
255
256int
257is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
258{
259 GNUNET_assert(tunnel);
260
261 return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
262}
263
264struct GNUNET_MESSENGER_MessageSent
265{
266 struct GNUNET_MESSENGER_SrvTunnel *tunnel;
267 struct GNUNET_HashCode hash;
268};
269
270static void
271callback_tunnel_sent (void *cls)
272{
273 struct GNUNET_MESSENGER_MessageSent *sent = cls;
274
275 if (sent->tunnel)
276 update_tunnel_last_message (sent->tunnel, &(sent->hash));
277
278 GNUNET_free(sent);
279}
280
281void
282send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env,
283 const struct GNUNET_HashCode *hash)
284{
285 GNUNET_assert((tunnel) && (env) && (hash));
286
287 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
288
289 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent);
290
291 GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode));
292
293 sent->tunnel = tunnel;
294
295 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent);
296 GNUNET_MQ_send (mq, env);
297}
298
299int
300send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
301{
302 GNUNET_assert((tunnel) && (handle));
303
304 if (!message)
305 return GNUNET_NO;
306
307 struct GNUNET_HashCode hash;
308 struct GNUNET_MQ_Envelope *env = pack_room_message (
309 tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
310 message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE
311 );
312
313 destroy_message(message);
314
315 if (!env)
316 return GNUNET_NO;
317
318 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
319 GNUNET_h2s(&hash));
320
321 send_tunnel_envelope (tunnel, env, &hash);
322 return GNUNET_YES;
323}
324
325void
326forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message,
327 const struct GNUNET_HashCode *hash)
328{
329 GNUNET_assert((tunnel) && (message) && (hash));
330
331 struct GNUNET_MESSENGER_Message *copy = copy_message(message);
332 struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
333
334 destroy_message(copy);
335
336 if (!env)
337 return;
338
339 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
340 GNUNET_h2s(hash));
341
342 send_tunnel_envelope (tunnel, env, hash);
343}
344
345const struct GNUNET_HashCode*
346get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
347{
348 GNUNET_assert(tunnel);
349
350 return tunnel->peer_message;
351}
352
353void
354get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer)
355{
356 GNUNET_assert(tunnel);
357
358 GNUNET_PEER_resolve(tunnel->peer, peer);
359}
360
361uint32_t
362get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
363{
364 GNUNET_assert(tunnel);
365
366 return tunnel->messenger_version;
367}
368
369int
370update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, uint32_t version)
371{
372 GNUNET_assert(tunnel);
373
374 if (version != GNUNET_MESSENGER_VERSION)
375 return GNUNET_SYSERR;
376
377 if (version > tunnel->messenger_version)
378 tunnel->messenger_version = version;
379
380 return GNUNET_OK;
381}