diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_tunnel.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_tunnel.c | 249 |
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 | ||
31 | struct GNUNET_MESSENGER_SrvTunnel* | 35 | struct GNUNET_MESSENGER_SrvTunnel* |
32 | create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) | 36 | create_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 | ||
72 | int | 74 | void |
73 | bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) | 75 | bind_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 | ||
90 | extern void | 85 | extern 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 | ||
138 | extern int | ||
139 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
140 | struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); | ||
141 | |||
159 | extern void | 142 | extern void |
160 | callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, | 143 | callback_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 | |||
146 | static void | ||
147 | update_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 | ||
163 | void | 163 | void |
164 | handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) | 164 | handle_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 | |||
217 | receive_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) | |||
212 | void | 243 | void |
213 | disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 244 | disconnect_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) | |||
223 | int | 256 | int |
224 | is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 257 | is_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 | ||
235 | extern void | ||
236 | callback_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 | |||
239 | static void | 270 | static void |
240 | callback_tunnel_sent (void *cls) | 271 | callback_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 | ||
255 | void | 281 | void |
256 | send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, | 282 | send_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 | ||
273 | void | 299 | int |
274 | send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, | 300 | send_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 | ||
285 | void | 325 | void |
286 | forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, | 326 | forward_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 | ||
296 | const struct GNUNET_HashCode* | 345 | const struct GNUNET_HashCode* |
297 | get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 346 | get_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 | |||
353 | void | ||
354 | get_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 | |||
361 | uint32_t | ||
362 | get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
363 | { | ||
364 | GNUNET_assert(tunnel); | ||
365 | |||
366 | return tunnel->messenger_version; | ||
367 | } | ||
368 | |||
369 | int | ||
370 | update_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 | } | ||