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.c403
1 files changed, 0 insertions, 403 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c
deleted file mode 100644
index 8ad7fff1c..000000000
--- a/src/messenger/gnunet-service-messenger_tunnel.c
+++ /dev/null
@@ -1,403 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2022 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 "platform.h"
27#include "gnunet-service-messenger_tunnel.h"
28
29#include "gnunet-service-messenger_handle.h"
30#include "gnunet-service-messenger_message_recv.h"
31#include "gnunet-service-messenger_message_store.h"
32#include "gnunet-service-messenger_operation_store.h"
33#include "gnunet-service-messenger_operation.h"
34#include "messenger_api_util.h"
35
36struct GNUNET_MESSENGER_SrvTunnel*
37create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room,
38 const struct GNUNET_PeerIdentity *door)
39{
40 GNUNET_assert((room) && (door));
41
42 struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_new(struct GNUNET_MESSENGER_SrvTunnel);
43
44 tunnel->room = room;
45 tunnel->channel = NULL;
46
47 tunnel->peer = GNUNET_PEER_intern (door);
48
49 tunnel->messenger_version = 0;
50
51 tunnel->peer_message = NULL;
52
53 init_message_state(&(tunnel->state));
54
55 return tunnel;
56}
57
58void
59destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
60{
61 GNUNET_assert(tunnel);
62
63 if (tunnel->channel)
64 GNUNET_CADET_channel_destroy (tunnel->channel);
65
66 GNUNET_PEER_change_rc (tunnel->peer, -1);
67
68 if (tunnel->peer_message)
69 GNUNET_free(tunnel->peer_message);
70
71 clear_message_state(&(tunnel->state));
72
73 GNUNET_free(tunnel);
74}
75
76void
77bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
78 struct GNUNET_CADET_Channel *channel)
79{
80 GNUNET_assert(tunnel);
81
82 if (tunnel->channel)
83 delayed_disconnect_channel (tunnel->channel);
84
85 tunnel->channel = channel;
86}
87
88extern void
89callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room,
90 void *cls);
91
92void
93callback_tunnel_disconnect (void *cls,
94 const struct GNUNET_CADET_Channel *channel)
95{
96 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
97
98 if (tunnel)
99 {
100 tunnel->channel = NULL;
101
102 callback_room_disconnect (tunnel->room, cls);
103 }
104}
105
106extern int
107callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
108 void *cls,
109 struct GNUNET_MESSENGER_Message *message,
110 struct GNUNET_HashCode *hash);
111
112int
113check_tunnel_message (void *cls,
114 const struct GNUNET_MessageHeader *header)
115{
116 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
117
118 if (!tunnel)
119 return GNUNET_SYSERR;
120
121 const uint16_t length = ntohs (header->size) - sizeof(*header);
122 const char *buffer = (const char*) &header[1];
123
124 struct GNUNET_MESSENGER_Message message;
125
126 if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES))
127 {
128 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length);
129 return GNUNET_SYSERR;
130 }
131
132 uint16_t padding = 0;
133
134 if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding))
135 {
136 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n");
137 return GNUNET_SYSERR;
138 }
139
140 struct GNUNET_HashCode hash;
141 hash_message (&message, length - padding, buffer, &hash);
142
143 return callback_verify_room_message (tunnel->room, cls, &message, &hash);
144}
145
146extern int
147update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
148 struct GNUNET_MESSENGER_Message *message,
149 const struct GNUNET_HashCode *hash);
150
151extern void
152callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room,
153 struct GNUNET_MESSENGER_SrvHandle *handle,
154 const struct GNUNET_MESSENGER_Message *message,
155 const struct GNUNET_HashCode *hash);
156
157static void
158update_tunnel_last_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
159 const struct GNUNET_HashCode *hash)
160{
161 struct GNUNET_MESSENGER_OperationStore *operation_store = get_srv_room_operation_store(tunnel->room);
162
163 const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)?
164 GNUNET_YES : GNUNET_NO
165 );
166
167 struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(tunnel->room);
168
169 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
170
171 if (message)
172 update_message_state(&(tunnel->state), requested, message, hash);
173}
174
175void
176handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
177{
178 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
179
180 if (!tunnel)
181 return;
182
183 const uint16_t length = ntohs (header->size) - sizeof(*header);
184 const char *buffer = (const char*) &header[1];
185
186 struct GNUNET_MESSENGER_Message message;
187 struct GNUNET_HashCode hash;
188
189 uint16_t padding = 0;
190
191 decode_message (&message, length, buffer, GNUNET_YES, &padding);
192 hash_message (&message, length - padding, buffer, &hash);
193
194 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n",
195 GNUNET_MESSENGER_name_of_kind(message.header.kind));
196
197 const int new_message = update_room_message (
198 tunnel->room, copy_message (&message), &hash
199 );
200
201 if (GNUNET_YES != new_message)
202 goto receive_done;
203
204 update_tunnel_last_message (tunnel, &hash);
205
206 int forward_message = GNUNET_YES;
207
208 switch (message.header.kind)
209 {
210 case GNUNET_MESSENGER_KIND_INFO:
211 forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash);
212 break;
213 case GNUNET_MESSENGER_KIND_PEER:
214 forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash);
215 break;
216 case GNUNET_MESSENGER_KIND_REQUEST:
217 forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash);
218 break;
219 default:
220 break;
221 }
222
223 if (GNUNET_YES == forward_message)
224 {
225 forward_srv_room_message (tunnel->room, tunnel, &message, &hash);
226 callback_room_handle_message (tunnel->room, NULL, &message, &hash);
227 }
228
229receive_done:
230 cleanup_message(&message);
231
232 GNUNET_CADET_receive_done (tunnel->channel);
233}
234
235int
236connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
237{
238 GNUNET_assert(tunnel);
239
240 if (tunnel->channel)
241 return GNUNET_NO;
242
243 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
244
245 struct GNUNET_CADET_Handle *cadet = get_srv_room_cadet (tunnel->room);
246 const struct GNUNET_HashCode *key = get_srv_room_key (tunnel->room);
247
248 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI,
249 struct GNUNET_MessageHeader, NULL),
250 GNUNET_MQ_handler_end() };
251
252 struct GNUNET_HashCode port;
253 convert_messenger_key_to_port(key, &port);
254 tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, &port, NULL, callback_tunnel_disconnect, handlers);
255
256 return GNUNET_YES;
257}
258
259void
260disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
261{
262 GNUNET_assert(tunnel);
263
264 if (tunnel->channel)
265 {
266 delayed_disconnect_channel (tunnel->channel);
267
268 tunnel->channel = NULL;
269 }
270}
271
272int
273is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
274{
275 GNUNET_assert(tunnel);
276
277 return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
278}
279
280struct GNUNET_MESSENGER_MessageSent
281{
282 struct GNUNET_MESSENGER_SrvTunnel *tunnel;
283 struct GNUNET_HashCode hash;
284};
285
286static void
287callback_tunnel_sent (void *cls)
288{
289 struct GNUNET_MESSENGER_MessageSent *sent = cls;
290
291 if (sent->tunnel)
292 update_tunnel_last_message (sent->tunnel, &(sent->hash));
293
294 GNUNET_free(sent);
295}
296
297void
298send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
299 struct GNUNET_MQ_Envelope *env,
300 const struct GNUNET_HashCode *hash)
301{
302 GNUNET_assert((tunnel) && (env) && (hash));
303
304 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
305
306 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent);
307
308 GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode));
309
310 sent->tunnel = tunnel;
311
312 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent);
313 GNUNET_MQ_send (mq, env);
314}
315
316int
317send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
318 void *handle,
319 struct GNUNET_MESSENGER_Message *message)
320{
321 GNUNET_assert((tunnel) && (handle));
322
323 if (!message)
324 return GNUNET_NO;
325
326 struct GNUNET_HashCode hash;
327 struct GNUNET_MQ_Envelope *env = pack_srv_room_message (
328 tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
329 message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE
330 );
331
332 destroy_message(message);
333
334 if (!env)
335 return GNUNET_NO;
336
337 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
338 GNUNET_h2s(&hash));
339
340 send_tunnel_envelope (tunnel, env, &hash);
341 return GNUNET_YES;
342}
343
344void
345forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
346 const struct GNUNET_MESSENGER_Message *message,
347 const struct GNUNET_HashCode *hash)
348{
349 GNUNET_assert((tunnel) && (message) && (hash));
350
351 struct GNUNET_MESSENGER_Message *copy = copy_message(message);
352 struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
353
354 destroy_message(copy);
355
356 if (!env)
357 return;
358
359 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
360 GNUNET_h2s(hash));
361
362 send_tunnel_envelope (tunnel, env, hash);
363}
364
365const struct GNUNET_HashCode*
366get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
367{
368 GNUNET_assert(tunnel);
369
370 return tunnel->peer_message;
371}
372
373void
374get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel,
375 struct GNUNET_PeerIdentity *peer)
376{
377 GNUNET_assert(tunnel);
378
379 GNUNET_PEER_resolve(tunnel->peer, peer);
380}
381
382uint32_t
383get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
384{
385 GNUNET_assert(tunnel);
386
387 return tunnel->messenger_version;
388}
389
390int
391update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel,
392 uint32_t version)
393{
394 GNUNET_assert(tunnel);
395
396 if (version != GNUNET_MESSENGER_VERSION)
397 return GNUNET_SYSERR;
398
399 if (version > tunnel->messenger_version)
400 tunnel->messenger_version = version;
401
402 return GNUNET_OK;
403}