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.c383
1 files changed, 0 insertions, 383 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c
deleted file mode 100644
index b9d063813..000000000
--- a/src/messenger/gnunet-service-messenger_tunnel.c
+++ /dev/null
@@ -1,383 +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 struct GNUNET_HashCode port;
239 convert_messenger_key_to_port(key, &port);
240 tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, &port, NULL, callback_tunnel_disconnect, handlers);
241
242 return GNUNET_YES;
243}
244
245void
246disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
247{
248 GNUNET_assert(tunnel);
249
250 if (tunnel->channel)
251 {
252 delayed_disconnect_channel (tunnel->channel);
253
254 tunnel->channel = NULL;
255 }
256}
257
258int
259is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
260{
261 GNUNET_assert(tunnel);
262
263 return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
264}
265
266struct GNUNET_MESSENGER_MessageSent
267{
268 struct GNUNET_MESSENGER_SrvTunnel *tunnel;
269 struct GNUNET_HashCode hash;
270};
271
272static void
273callback_tunnel_sent (void *cls)
274{
275 struct GNUNET_MESSENGER_MessageSent *sent = cls;
276
277 if (sent->tunnel)
278 update_tunnel_last_message (sent->tunnel, &(sent->hash));
279
280 GNUNET_free(sent);
281}
282
283void
284send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env,
285 const struct GNUNET_HashCode *hash)
286{
287 GNUNET_assert((tunnel) && (env) && (hash));
288
289 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
290
291 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent);
292
293 GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode));
294
295 sent->tunnel = tunnel;
296
297 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent);
298 GNUNET_MQ_send (mq, env);
299}
300
301int
302send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
303{
304 GNUNET_assert((tunnel) && (handle));
305
306 if (!message)
307 return GNUNET_NO;
308
309 struct GNUNET_HashCode hash;
310 struct GNUNET_MQ_Envelope *env = pack_room_message (
311 tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
312 message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE
313 );
314
315 destroy_message(message);
316
317 if (!env)
318 return GNUNET_NO;
319
320 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
321 GNUNET_h2s(&hash));
322
323 send_tunnel_envelope (tunnel, env, &hash);
324 return GNUNET_YES;
325}
326
327void
328forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message,
329 const struct GNUNET_HashCode *hash)
330{
331 GNUNET_assert((tunnel) && (message) && (hash));
332
333 struct GNUNET_MESSENGER_Message *copy = copy_message(message);
334 struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
335
336 destroy_message(copy);
337
338 if (!env)
339 return;
340
341 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
342 GNUNET_h2s(hash));
343
344 send_tunnel_envelope (tunnel, env, hash);
345}
346
347const struct GNUNET_HashCode*
348get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
349{
350 GNUNET_assert(tunnel);
351
352 return tunnel->peer_message;
353}
354
355void
356get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer)
357{
358 GNUNET_assert(tunnel);
359
360 GNUNET_PEER_resolve(tunnel->peer, peer);
361}
362
363uint32_t
364get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
365{
366 GNUNET_assert(tunnel);
367
368 return tunnel->messenger_version;
369}
370
371int
372update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, uint32_t version)
373{
374 GNUNET_assert(tunnel);
375
376 if (version != GNUNET_MESSENGER_VERSION)
377 return GNUNET_SYSERR;
378
379 if (version > tunnel->messenger_version)
380 tunnel->messenger_version = version;
381
382 return GNUNET_OK;
383}