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.c233
1 files changed, 152 insertions, 81 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c
index df9e5c4c7..f7e8713c6 100644
--- a/src/messenger/gnunet-service-messenger_tunnel.c
+++ b/src/messenger/gnunet-service-messenger_tunnel.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V. 3 Copyright (C) 2020--2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -26,7 +26,8 @@
26#include "gnunet-service-messenger_tunnel.h" 26#include "gnunet-service-messenger_tunnel.h"
27 27
28#include "gnunet-service-messenger_handle.h" 28#include "gnunet-service-messenger_handle.h"
29#include "gnunet-service-messenger_util.h" 29#include "gnunet-service-messenger_message_recv.h"
30#include "messenger_api_util.h"
30 31
31struct GNUNET_MESSENGER_SrvTunnel* 32struct GNUNET_MESSENGER_SrvTunnel*
32create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) 33create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door)
@@ -39,7 +40,8 @@ create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerId
39 tunnel->channel = NULL; 40 tunnel->channel = NULL;
40 41
41 tunnel->peer = GNUNET_PEER_intern (door); 42 tunnel->peer = GNUNET_PEER_intern (door);
42 tunnel->contact_id = NULL; 43
44 tunnel->messenger_version = 0;
43 45
44 tunnel->peer_message = NULL; 46 tunnel->peer_message = NULL;
45 tunnel->last_message = NULL; 47 tunnel->last_message = NULL;
@@ -57,9 +59,6 @@ destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
57 59
58 GNUNET_PEER_change_rc (tunnel->peer, -1); 60 GNUNET_PEER_change_rc (tunnel->peer, -1);
59 61
60 if (tunnel->contact_id)
61 GNUNET_free(tunnel->contact_id);
62
63 if (tunnel->peer_message) 62 if (tunnel->peer_message)
64 GNUNET_free(tunnel->peer_message); 63 GNUNET_free(tunnel->peer_message);
65 64
@@ -69,22 +68,15 @@ destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
69 GNUNET_free(tunnel); 68 GNUNET_free(tunnel);
70} 69}
71 70
72int 71void
73bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) 72bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
74{ 73{
75 GNUNET_assert(tunnel); 74 GNUNET_assert(tunnel);
76 75
77 if (tunnel->channel) 76 if (tunnel->channel)
78 {
79 if (tunnel->contact_id)
80 return GNUNET_NO;
81
82 delayed_disconnect_channel (tunnel->channel); 77 delayed_disconnect_channel (tunnel->channel);
83 }
84 78
85 tunnel->channel = channel; 79 tunnel->channel = channel;
86
87 return GNUNET_YES;
88} 80}
89 81
90extern void 82extern void
@@ -113,52 +105,49 @@ check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
113 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; 105 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
114 106
115 if (!tunnel) 107 if (!tunnel)
116 return GNUNET_NO; 108 return GNUNET_SYSERR;
117 109
118 const uint16_t length = ntohs (header->size) - sizeof(*header); 110 const uint16_t length = ntohs (header->size) - sizeof(*header);
119 const char *buffer = (const char*) &header[1]; 111 const char *buffer = (const char*) &header[1];
120 112
121 struct GNUNET_MESSENGER_Message message; 113 struct GNUNET_MESSENGER_Message message;
122 114
123 if (length < sizeof(message.header)) 115 if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN))
124 return GNUNET_NO; 116 {
125 117 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length);
126 if (GNUNET_YES != decode_message (&message, length, buffer)) 118 return GNUNET_SYSERR;
127 return GNUNET_NO; 119 }
128
129 struct GNUNET_HashCode hash;
130 hash_message (length, buffer, &hash);
131 120
132 int result = callback_verify_room_message (tunnel->room, cls, &message, &hash); 121 uint16_t padding = 0;
133 122
134 if (GNUNET_MESSENGER_KIND_PEER == message.header.kind) 123 if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding))
135 { 124 {
136 struct GNUNET_PeerIdentity identity; 125 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n");
137 126 return GNUNET_SYSERR;
138 GNUNET_PEER_resolve (tunnel->peer, &identity);
139
140 if (0 == GNUNET_memcmp(&(message.body.peer.peer), &(identity)))
141 {
142 if (tunnel->contact_id)
143 {
144 if (0 != GNUNET_memcmp(tunnel->contact_id, &(message.header.sender_id)))
145 result = GNUNET_SYSERR;
146 }
147 else
148 {
149 tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
150
151 GNUNET_memcpy(tunnel->contact_id, &(message.header.sender_id), sizeof(struct GNUNET_ShortHashCode));
152 }
153 }
154 } 127 }
155 128
156 return (result == GNUNET_YES ? GNUNET_OK : GNUNET_NO); 129 struct GNUNET_HashCode hash;
130 hash_message (&message, length - padding, buffer, &hash);
131
132 return callback_verify_room_message (tunnel->room, cls, &message, &hash);
157} 133}
158 134
135extern int
136update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
137 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
138
159extern void 139extern void
160callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, 140callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle,
161 const struct GNUNET_HashCode *hash); 141 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
142
143static void
144update_tunnel_last_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_HashCode *hash)
145{
146 if (!tunnel->last_message)
147 tunnel->last_message = GNUNET_new(struct GNUNET_HashCode);
148
149 GNUNET_memcpy(tunnel->last_message, hash, sizeof(*hash));
150}
162 151
163void 152void
164handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) 153handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
@@ -171,19 +160,48 @@ handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
171 struct GNUNET_MESSENGER_Message message; 160 struct GNUNET_MESSENGER_Message message;
172 struct GNUNET_HashCode hash; 161 struct GNUNET_HashCode hash;
173 162
174 decode_message (&message, length, buffer); 163 uint16_t padding = 0;
175 hash_message (length, buffer, &hash);
176 164
177 if (tunnel) 165 decode_message (&message, length, buffer, GNUNET_YES, &padding);
178 { 166 hash_message (&message, length - padding, buffer, &hash);
179 if (!tunnel->last_message) 167
180 tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); 168 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n",
169 GNUNET_MESSENGER_name_of_kind(message.header.kind));
170
171 if (!tunnel)
172 return;
173
174 const int new_message = update_room_message (tunnel->room, copy_message (&message), &hash);
175
176 if (GNUNET_YES != new_message)
177 goto receive_done;
181 178
182 GNUNET_memcpy(tunnel->last_message, &hash, sizeof(struct GNUNET_HashCode)); 179 update_tunnel_last_message (tunnel, &hash);
183 180
184 callback_room_recv (tunnel->room, cls, copy_message (&message), &hash); 181 int forward_message = GNUNET_YES;
182
183 switch (message.header.kind)
184 {
185 case GNUNET_MESSENGER_KIND_INFO:
186 forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash);
187 break;
188 case GNUNET_MESSENGER_KIND_PEER:
189 forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash);
190 break;
191 case GNUNET_MESSENGER_KIND_REQUEST:
192 forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash);
193 break;
194 default:
195 break;
196 }
197
198 if (GNUNET_YES == forward_message)
199 {
200 forward_room_message (tunnel->room, tunnel, &message, &hash);
201 callback_room_handle_message (tunnel->room, NULL, &message, &hash);
185 } 202 }
186 203
204receive_done:
187 GNUNET_CADET_receive_done (tunnel->channel); 205 GNUNET_CADET_receive_done (tunnel->channel);
188} 206}
189 207
@@ -198,7 +216,7 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
198 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); 216 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
199 217
200 struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); 218 struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room);
201 struct GNUNET_HashCode *key = get_room_key (tunnel->room); 219 const struct GNUNET_HashCode *key = get_room_key (tunnel->room);
202 220
203 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, 221 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI,
204 struct GNUNET_MessageHeader, NULL), 222 struct GNUNET_MessageHeader, NULL),
@@ -212,6 +230,8 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
212void 230void
213disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) 231disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
214{ 232{
233 GNUNET_assert(tunnel);
234
215 if (tunnel->channel) 235 if (tunnel->channel)
216 { 236 {
217 delayed_disconnect_channel (tunnel->channel); 237 delayed_disconnect_channel (tunnel->channel);
@@ -223,6 +243,8 @@ disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
223int 243int
224is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) 244is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
225{ 245{
246 GNUNET_assert(tunnel);
247
226 return (tunnel->channel ? GNUNET_YES : GNUNET_NO); 248 return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
227} 249}
228 250
@@ -232,30 +254,23 @@ struct GNUNET_MESSENGER_MessageSent
232 struct GNUNET_HashCode hash; 254 struct GNUNET_HashCode hash;
233}; 255};
234 256
235extern void
236callback_room_sent (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls,
237 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
238
239static void 257static void
240callback_tunnel_sent (void *cls) 258callback_tunnel_sent (void *cls)
241{ 259{
242 struct GNUNET_MESSENGER_MessageSent *sent = cls; 260 struct GNUNET_MESSENGER_MessageSent *sent = cls;
243 261
244 if (sent->tunnel) 262 if (sent->tunnel)
245 { 263 update_tunnel_last_message (sent->tunnel, &(sent->hash));
246 if (!sent->tunnel->last_message)
247 sent->tunnel->last_message = GNUNET_new(struct GNUNET_HashCode);
248
249 GNUNET_memcpy(sent->tunnel->last_message, &(sent->hash), sizeof(struct GNUNET_HashCode));
250 }
251 264
252 GNUNET_free(sent); 265 GNUNET_free(sent);
253} 266}
254 267
255void 268void
256send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, 269send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env,
257 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) 270 const struct GNUNET_HashCode *hash)
258{ 271{
272 GNUNET_assert((tunnel) && (env) && (hash));
273
259 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); 274 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
260 275
261 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); 276 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent);
@@ -266,35 +281,91 @@ send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, s
266 281
267 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); 282 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent);
268 GNUNET_MQ_send (mq, env); 283 GNUNET_MQ_send (mq, env);
269
270 callback_room_sent (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, tunnel, message, hash);
271} 284}
272 285
273void 286int
274send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, 287send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
275 struct GNUNET_HashCode *hash)
276{ 288{
277 struct GNUNET_MQ_Envelope *env = pack_room_message (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, 289 GNUNET_assert((tunnel) && (handle));
278 message, hash, 290
279 GNUNET_MESSENGER_PACK_MODE_ENVELOPE); 291 if (!message)
292 return GNUNET_NO;
293
294 struct GNUNET_HashCode hash;
295 struct GNUNET_MQ_Envelope *env = pack_room_message (
296 tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
297 message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE
298 );
299
300 destroy_message(message);
301
302 if (!env)
303 return GNUNET_NO;
304
305 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
306 GNUNET_h2s(&hash));
280 307
281 if (env) 308 send_tunnel_envelope (tunnel, env, &hash);
282 send_tunnel_envelope (tunnel, handle, env, copy_message (message), hash); 309 return GNUNET_YES;
283} 310}
284 311
285void 312void
286forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, 313forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message,
287 const struct GNUNET_HashCode *hash) 314 const struct GNUNET_HashCode *hash)
288{ 315{
289 struct GNUNET_MESSENGER_Message *clone = copy_message (message); 316 if (!message)
290 struct GNUNET_MQ_Envelope *env = pack_message (clone, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); 317 return;
318
319 GNUNET_assert((tunnel) && (message) && (hash));
320
321 struct GNUNET_MESSENGER_Message *copy = copy_message(message);
322 struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
323
324 destroy_message(copy);
325
326 if (!env)
327 return;
328
329 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
330 GNUNET_h2s(hash));
291 331
292 if (env) 332 send_tunnel_envelope (tunnel, env, hash);
293 send_tunnel_envelope (tunnel, NULL, env, clone, hash);
294} 333}
295 334
296const struct GNUNET_HashCode* 335const struct GNUNET_HashCode*
297get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) 336get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
298{ 337{
338 GNUNET_assert(tunnel);
339
299 return tunnel->peer_message; 340 return tunnel->peer_message;
300} 341}
342
343void
344get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer)
345{
346 GNUNET_assert(tunnel);
347
348 GNUNET_PEER_resolve(tunnel->peer, peer);
349}
350
351uint32_t
352get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
353{
354 GNUNET_assert(tunnel);
355
356 return tunnel->messenger_version;
357}
358
359int
360update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, uint32_t version)
361{
362 GNUNET_assert(tunnel);
363
364 if (version != GNUNET_MESSENGER_VERSION)
365 return GNUNET_SYSERR;
366
367 if (version > tunnel->messenger_version)
368 tunnel->messenger_version = version;
369
370 return GNUNET_OK;
371}