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.c249
1 files changed, 165 insertions, 84 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c
index df9e5c4c7..80d8dfa5e 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,11 @@
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 "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"
30 34
31struct GNUNET_MESSENGER_SrvTunnel* 35struct GNUNET_MESSENGER_SrvTunnel*
32create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) 36create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door)
@@ -39,10 +43,12 @@ create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerId
39 tunnel->channel = NULL; 43 tunnel->channel = NULL;
40 44
41 tunnel->peer = GNUNET_PEER_intern (door); 45 tunnel->peer = GNUNET_PEER_intern (door);
42 tunnel->contact_id = NULL; 46
47 tunnel->messenger_version = 0;
43 48
44 tunnel->peer_message = NULL; 49 tunnel->peer_message = NULL;
45 tunnel->last_message = NULL; 50
51 init_message_state(&(tunnel->state));
46 52
47 return tunnel; 53 return tunnel;
48} 54}
@@ -57,34 +63,23 @@ destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
57 63
58 GNUNET_PEER_change_rc (tunnel->peer, -1); 64 GNUNET_PEER_change_rc (tunnel->peer, -1);
59 65
60 if (tunnel->contact_id)
61 GNUNET_free(tunnel->contact_id);
62
63 if (tunnel->peer_message) 66 if (tunnel->peer_message)
64 GNUNET_free(tunnel->peer_message); 67 GNUNET_free(tunnel->peer_message);
65 68
66 if (tunnel->last_message) 69 clear_message_state(&(tunnel->state));
67 GNUNET_free(tunnel->last_message);
68 70
69 GNUNET_free(tunnel); 71 GNUNET_free(tunnel);
70} 72}
71 73
72int 74void
73bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) 75bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
74{ 76{
75 GNUNET_assert(tunnel); 77 GNUNET_assert(tunnel);
76 78
77 if (tunnel->channel) 79 if (tunnel->channel)
78 {
79 if (tunnel->contact_id)
80 return GNUNET_NO;
81
82 delayed_disconnect_channel (tunnel->channel); 80 delayed_disconnect_channel (tunnel->channel);
83 }
84 81
85 tunnel->channel = channel; 82 tunnel->channel = channel;
86
87 return GNUNET_YES;
88} 83}
89 84
90extern void 85extern void
@@ -113,52 +108,57 @@ check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
113 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; 108 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
114 109
115 if (!tunnel) 110 if (!tunnel)
116 return GNUNET_NO; 111 return GNUNET_SYSERR;
117 112
118 const uint16_t length = ntohs (header->size) - sizeof(*header); 113 const uint16_t length = ntohs (header->size) - sizeof(*header);
119 const char *buffer = (const char*) &header[1]; 114 const char *buffer = (const char*) &header[1];
120 115
121 struct GNUNET_MESSENGER_Message message; 116 struct GNUNET_MESSENGER_Message message;
122 117
123 if (length < sizeof(message.header)) 118 if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN))
124 return GNUNET_NO; 119 {
125 120 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length);
126 if (GNUNET_YES != decode_message (&message, length, buffer)) 121 return GNUNET_SYSERR;
127 return GNUNET_NO; 122 }
128
129 struct GNUNET_HashCode hash;
130 hash_message (length, buffer, &hash);
131 123
132 int result = callback_verify_room_message (tunnel->room, cls, &message, &hash); 124 uint16_t padding = 0;
133 125
134 if (GNUNET_MESSENGER_KIND_PEER == message.header.kind) 126 if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding))
135 { 127 {
136 struct GNUNET_PeerIdentity identity; 128 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n");
137 129 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 } 130 }
155 131
156 return (result == GNUNET_YES ? GNUNET_OK : GNUNET_NO); 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);
157} 136}
158 137
138extern int
139update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
140 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
141
159extern void 142extern void
160callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, 143callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle,
161 const struct GNUNET_HashCode *hash); 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 162
163void 163void
164handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) 164handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
@@ -171,19 +171,50 @@ handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
171 struct GNUNET_MESSENGER_Message message; 171 struct GNUNET_MESSENGER_Message message;
172 struct GNUNET_HashCode hash; 172 struct GNUNET_HashCode hash;
173 173
174 decode_message (&message, length, buffer); 174 uint16_t padding = 0;
175 hash_message (length, buffer, &hash);
176 175
177 if (tunnel) 176 decode_message (&message, length, buffer, GNUNET_YES, &padding);
178 { 177 hash_message (&message, length - padding, buffer, &hash);
179 if (!tunnel->last_message) 178
180 tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); 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;
181 191
182 GNUNET_memcpy(tunnel->last_message, &hash, sizeof(struct GNUNET_HashCode)); 192 update_tunnel_last_message (tunnel, &hash);
183 193
184 callback_room_recv (tunnel->room, cls, copy_message (&message), &hash); 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;
185 } 209 }
186 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:
187 GNUNET_CADET_receive_done (tunnel->channel); 218 GNUNET_CADET_receive_done (tunnel->channel);
188} 219}
189 220
@@ -198,7 +229,7 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
198 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); 229 const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
199 230
200 struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); 231 struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room);
201 struct GNUNET_HashCode *key = get_room_key (tunnel->room); 232 const struct GNUNET_HashCode *key = get_room_key (tunnel->room);
202 233
203 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, 234 struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI,
204 struct GNUNET_MessageHeader, NULL), 235 struct GNUNET_MessageHeader, NULL),
@@ -212,6 +243,8 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
212void 243void
213disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) 244disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
214{ 245{
246 GNUNET_assert(tunnel);
247
215 if (tunnel->channel) 248 if (tunnel->channel)
216 { 249 {
217 delayed_disconnect_channel (tunnel->channel); 250 delayed_disconnect_channel (tunnel->channel);
@@ -223,6 +256,8 @@ disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel)
223int 256int
224is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) 257is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
225{ 258{
259 GNUNET_assert(tunnel);
260
226 return (tunnel->channel ? GNUNET_YES : GNUNET_NO); 261 return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
227} 262}
228 263
@@ -232,30 +267,23 @@ struct GNUNET_MESSENGER_MessageSent
232 struct GNUNET_HashCode hash; 267 struct GNUNET_HashCode hash;
233}; 268};
234 269
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 270static void
240callback_tunnel_sent (void *cls) 271callback_tunnel_sent (void *cls)
241{ 272{
242 struct GNUNET_MESSENGER_MessageSent *sent = cls; 273 struct GNUNET_MESSENGER_MessageSent *sent = cls;
243 274
244 if (sent->tunnel) 275 if (sent->tunnel)
245 { 276 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 277
252 GNUNET_free(sent); 278 GNUNET_free(sent);
253} 279}
254 280
255void 281void
256send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, 282send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env,
257 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) 283 const struct GNUNET_HashCode *hash)
258{ 284{
285 GNUNET_assert((tunnel) && (env) && (hash));
286
259 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); 287 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
260 288
261 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); 289 struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent);
@@ -266,35 +294,88 @@ send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, s
266 294
267 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); 295 GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent);
268 GNUNET_MQ_send (mq, env); 296 GNUNET_MQ_send (mq, env);
269
270 callback_room_sent (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, tunnel, message, hash);
271} 297}
272 298
273void 299int
274send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, 300send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
275 struct GNUNET_HashCode *hash)
276{ 301{
277 struct GNUNET_MQ_Envelope *env = pack_room_message (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, 302 GNUNET_assert((tunnel) && (handle));
278 message, hash, 303
279 GNUNET_MESSENGER_PACK_MODE_ENVELOPE); 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;
280 317
281 if (env) 318 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
282 send_tunnel_envelope (tunnel, handle, env, copy_message (message), hash); 319 GNUNET_h2s(&hash));
320
321 send_tunnel_envelope (tunnel, env, &hash);
322 return GNUNET_YES;
283} 323}
284 324
285void 325void
286forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, 326forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message,
287 const struct GNUNET_HashCode *hash) 327 const struct GNUNET_HashCode *hash)
288{ 328{
289 struct GNUNET_MESSENGER_Message *clone = copy_message (message); 329 GNUNET_assert((tunnel) && (message) && (hash));
290 struct GNUNET_MQ_Envelope *env = pack_message (clone, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); 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;
291 338
292 if (env) 339 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
293 send_tunnel_envelope (tunnel, NULL, env, clone, hash); 340 GNUNET_h2s(hash));
341
342 send_tunnel_envelope (tunnel, env, hash);
294} 343}
295 344
296const struct GNUNET_HashCode* 345const struct GNUNET_HashCode*
297get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) 346get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
298{ 347{
348 GNUNET_assert(tunnel);
349
299 return tunnel->peer_message; 350 return tunnel->peer_message;
300} 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}