diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2024-02-01 20:40:40 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2024-02-01 20:40:40 +0100 |
commit | 25e42d202a4f9b356a5e8775cd7ef2c741b3d187 (patch) | |
tree | 70bb3e415ac216b26604744250db49c783b01fda /src | |
parent | 31a66fa661710e8d842e5742618664e067910c49 (diff) | |
download | gnunet-25e42d202a4f9b356a5e8775cd7ef2c741b3d187.tar.gz gnunet-25e42d202a4f9b356a5e8775cd7ef2c741b3d187.zip |
MESSENGER: Implement client side deletion and update callback for messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_messenger_service.h | 10 | ||||
-rw-r--r-- | src/service/messenger/messenger_api.c | 102 | ||||
-rw-r--r-- | src/service/messenger/messenger_api_contact_store.c | 5 | ||||
-rw-r--r-- | src/service/messenger/messenger_api_message.c | 24 | ||||
-rw-r--r-- | src/service/messenger/messenger_api_message.h | 12 | ||||
-rw-r--r-- | src/service/messenger/messenger_api_room.c | 437 | ||||
-rw-r--r-- | src/service/messenger/messenger_api_room.h | 28 |
7 files changed, 398 insertions, 220 deletions
diff --git a/src/include/gnunet_messenger_service.h b/src/include/gnunet_messenger_service.h index 8e1cd666d..8c009a0e6 100644 --- a/src/include/gnunet_messenger_service.h +++ b/src/include/gnunet_messenger_service.h | |||
@@ -669,6 +669,16 @@ enum GNUNET_MESSENGER_MessageFlags | |||
669 | * The recent flag. The flag indicates that the message was recently handled by the service. | 669 | * The recent flag. The flag indicates that the message was recently handled by the service. |
670 | */ | 670 | */ |
671 | GNUNET_MESSENGER_FLAG_RECENT = 8, | 671 | GNUNET_MESSENGER_FLAG_RECENT = 8, |
672 | |||
673 | /** | ||
674 | * The update flag. The flag indicates that the message was updated by the client. | ||
675 | */ | ||
676 | GNUNET_MESSENGER_FLAG_UPDATE = 16, | ||
677 | |||
678 | /** | ||
679 | * The delete flag. The flag indicates that the message was deleted by the service. | ||
680 | */ | ||
681 | GNUNET_MESSENGER_FLAG_DELETE = 32, | ||
672 | }; | 682 | }; |
673 | 683 | ||
674 | /** | 684 | /** |
diff --git a/src/service/messenger/messenger_api.c b/src/service/messenger/messenger_api.c index 7623e21c5..dc2e6045a 100644 --- a/src/service/messenger/messenger_api.c +++ b/src/service/messenger/messenger_api.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "gnunet_common.h" | 26 | #include "gnunet_common.h" |
27 | #include "gnunet_core_service.h" | ||
28 | #include "gnunet_messenger_service.h" | 27 | #include "gnunet_messenger_service.h" |
29 | 28 | ||
30 | #include "gnunet-service-messenger.h" | 29 | #include "gnunet-service-messenger.h" |
@@ -109,7 +108,7 @@ handle_room_open (void *cls, | |||
109 | if (! room) | 108 | if (! room) |
110 | return; | 109 | return; |
111 | 110 | ||
112 | GNUNET_memcpy (&(room->last_message), prev, sizeof(room->last_message)); | 111 | update_room_last_message (room, prev); |
113 | 112 | ||
114 | dequeue_messages_from_room (room); | 113 | dequeue_messages_from_room (room); |
115 | } | 114 | } |
@@ -134,7 +133,7 @@ handle_room_entry (void *cls, | |||
134 | if (! room) | 133 | if (! room) |
135 | return; | 134 | return; |
136 | 135 | ||
137 | GNUNET_memcpy (&(room->last_message), prev, sizeof(room->last_message)); | 136 | update_room_last_message (room, prev); |
138 | 137 | ||
139 | dequeue_messages_from_room (room); | 138 | dequeue_messages_from_room (room); |
140 | } | 139 | } |
@@ -152,7 +151,7 @@ handle_room_close (void *cls, | |||
152 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); | 151 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
153 | 152 | ||
154 | if (room) | 153 | if (room) |
155 | GNUNET_memcpy (&(room->last_message), prev, sizeof(room->last_message)); | 154 | update_room_last_message (room, prev); |
156 | 155 | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); | 156 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); |
158 | 157 | ||
@@ -174,7 +173,7 @@ handle_room_sync (void *cls, | |||
174 | if (! room) | 173 | if (! room) |
175 | return; | 174 | return; |
176 | 175 | ||
177 | GNUNET_memcpy (&(room->last_message), prev, sizeof(room->last_message)); | 176 | update_room_last_message (room, prev); |
178 | 177 | ||
179 | room->wait_for_sync = GNUNET_NO; | 178 | room->wait_for_sync = GNUNET_NO; |
180 | 179 | ||
@@ -225,12 +224,6 @@ handle_member_id (void *cls, | |||
225 | } | 224 | } |
226 | 225 | ||
227 | 226 | ||
228 | static void | ||
229 | delete_message_in_room (struct GNUNET_MESSENGER_Room *room, | ||
230 | const struct GNUNET_HashCode *hash, | ||
231 | const struct GNUNET_TIME_Relative delay); | ||
232 | |||
233 | |||
234 | static enum GNUNET_GenericReturnValue | 227 | static enum GNUNET_GenericReturnValue |
235 | check_recv_message (void *cls, | 228 | check_recv_message (void *cls, |
236 | const struct GNUNET_MESSENGER_RecvMessage *msg) | 229 | const struct GNUNET_MESSENGER_RecvMessage *msg) |
@@ -281,8 +274,7 @@ handle_recv_message (void *cls, | |||
281 | const struct GNUNET_HashCode *hash = &(msg->hash); | 274 | const struct GNUNET_HashCode *hash = &(msg->hash); |
282 | 275 | ||
283 | enum GNUNET_MESSENGER_MessageFlags flags = ( | 276 | enum GNUNET_MESSENGER_MessageFlags flags = ( |
284 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) | 277 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)); |
285 | ); | ||
286 | 278 | ||
287 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | 279 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); |
288 | const char *buffer = ((const char*) msg) + sizeof(*msg); | 280 | const char *buffer = ((const char*) msg) + sizeof(*msg); |
@@ -290,28 +282,8 @@ handle_recv_message (void *cls, | |||
290 | struct GNUNET_MESSENGER_Message message; | 282 | struct GNUNET_MESSENGER_Message message; |
291 | decode_message (&message, length, buffer, GNUNET_YES, NULL); | 283 | decode_message (&message, length, buffer, GNUNET_YES, NULL); |
292 | 284 | ||
293 | struct GNUNET_MESSENGER_Message *private_message = NULL; | ||
294 | const struct GNUNET_MESSENGER_Message *handle_msg = &message; | ||
295 | |||
296 | if (GNUNET_MESSENGER_KIND_PRIVATE == message.header.kind) | ||
297 | { | ||
298 | private_message = copy_message (&message); | ||
299 | |||
300 | if (GNUNET_YES != decrypt_message (private_message, get_handle_key ( | ||
301 | handle))) | ||
302 | { | ||
303 | destroy_message (private_message); | ||
304 | private_message = NULL; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | if (private_message) | ||
309 | flags |= GNUNET_MESSENGER_FLAG_PRIVATE; | ||
310 | |||
311 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", | 285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", |
312 | GNUNET_MESSENGER_name_of_kind (private_message ? | 286 | GNUNET_MESSENGER_name_of_kind (message.header.kind)); |
313 | private_message->header.kind : | ||
314 | message.header.kind)); | ||
315 | 287 | ||
316 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); | 288 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
317 | 289 | ||
@@ -332,66 +304,16 @@ handle_recv_message (void *cls, | |||
332 | 304 | ||
333 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw ( | 305 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw ( |
334 | store, context, sender); | 306 | store, context, sender); |
335 | |||
336 | struct GNUNET_MESSENGER_Contact *recipient = NULL; | ||
337 | |||
338 | if (!private_message) | ||
339 | goto skip_recipient; | ||
340 | |||
341 | const struct GNUNET_CRYPTO_PublicKey *recipient_key; | ||
342 | |||
343 | if (GNUNET_MESSENGER_KIND_TRANSCRIPT == private_message->header.kind) | ||
344 | { | ||
345 | struct GNUNET_MESSENGER_Message *transcript; | ||
346 | 307 | ||
347 | recipient_key = &(private_message->body.transcript.key); | 308 | handle_room_message (room, contact, &message, hash, flags); |
348 | transcript = read_transcript_message(private_message); | ||
349 | 309 | ||
350 | if (transcript) | 310 | if (flags & GNUNET_MESSENGER_FLAG_RECENT) |
351 | { | 311 | update_room_last_message (room, hash); |
352 | destroy_message(private_message); | ||
353 | private_message = transcript; | ||
354 | } | ||
355 | } | ||
356 | else | ||
357 | recipient_key = get_handle_pubkey(handle); | ||
358 | 312 | ||
359 | recipient = get_store_contact(store, context, recipient_key); | 313 | callback_room_message (room, hash); |
360 | |||
361 | skip_recipient: | ||
362 | if (private_message) | ||
363 | handle_msg = private_message; | ||
364 | |||
365 | if ((GNUNET_MESSENGER_KIND_DELETE == handle_msg->header.kind) && | ||
366 | (GNUNET_MESSENGER_FLAG_SENT & flags)) | ||
367 | { | ||
368 | struct GNUNET_TIME_Relative delay; | ||
369 | struct GNUNET_TIME_Absolute action; | ||
370 | |||
371 | delay = GNUNET_TIME_relative_ntoh (handle_msg->body.deletion.delay); | ||
372 | |||
373 | action = GNUNET_TIME_absolute_ntoh (handle_msg->header.timestamp); | ||
374 | action = GNUNET_TIME_absolute_add (action, delay); | ||
375 | |||
376 | delay = GNUNET_TIME_absolute_get_difference (GNUNET_TIME_absolute_get (), action); | ||
377 | |||
378 | link_room_deletion (room, &(handle_msg->body.deletion.hash), delay, delete_message_in_room); | ||
379 | } | ||
380 | |||
381 | contact = handle_room_message (room, contact, recipient, handle_msg, hash, flags); | ||
382 | |||
383 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message ( | ||
384 | room, hash); | ||
385 | |||
386 | if (handle->msg_callback) | ||
387 | handle->msg_callback (handle->msg_cls, room, contact, recipient, | ||
388 | stored_message, hash, flags); | ||
389 | 314 | ||
390 | skip_message: | 315 | skip_message: |
391 | cleanup_message (&message); | 316 | cleanup_message (&message); |
392 | |||
393 | if (private_message) | ||
394 | destroy_message (private_message); | ||
395 | } | 317 | } |
396 | 318 | ||
397 | 319 | ||
@@ -752,7 +674,7 @@ send_message_to_room (struct GNUNET_MESSENGER_Room *room, | |||
752 | hash_message (message, msg_length, msg_buffer, hash); | 674 | hash_message (message, msg_length, msg_buffer, hash); |
753 | sign_message (message, msg_length, msg_buffer, hash, key); | 675 | sign_message (message, msg_length, msg_buffer, hash, key); |
754 | 676 | ||
755 | GNUNET_memcpy (&(room->last_message), hash, sizeof(room->last_message)); | 677 | update_room_last_message (room, hash); |
756 | 678 | ||
757 | GNUNET_MQ_send (room->handle->mq, env); | 679 | GNUNET_MQ_send (room->handle->mq, env); |
758 | 680 | ||
@@ -1243,7 +1165,7 @@ GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, | |||
1243 | } | 1165 | } |
1244 | 1166 | ||
1245 | 1167 | ||
1246 | static void | 1168 | void |
1247 | delete_message_in_room (struct GNUNET_MESSENGER_Room *room, | 1169 | delete_message_in_room (struct GNUNET_MESSENGER_Room *room, |
1248 | const struct GNUNET_HashCode *hash, | 1170 | const struct GNUNET_HashCode *hash, |
1249 | const struct GNUNET_TIME_Relative delay) | 1171 | const struct GNUNET_TIME_Relative delay) |
diff --git a/src/service/messenger/messenger_api_contact_store.c b/src/service/messenger/messenger_api_contact_store.c index 538e97acc..75069b187 100644 --- a/src/service/messenger/messenger_api_contact_store.c +++ b/src/service/messenger/messenger_api_contact_store.c | |||
@@ -113,14 +113,13 @@ get_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | |||
113 | const struct GNUNET_HashCode *context, | 113 | const struct GNUNET_HashCode *context, |
114 | const struct GNUNET_CRYPTO_PublicKey *pubkey) | 114 | const struct GNUNET_CRYPTO_PublicKey *pubkey) |
115 | { | 115 | { |
116 | GNUNET_assert ((store) && (store->contacts) && (context) && (pubkey)); | 116 | GNUNET_assert ((store) && (store->contacts) && (pubkey)); |
117 | 117 | ||
118 | struct GNUNET_HashCode hash; | 118 | struct GNUNET_HashCode hash; |
119 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); | 119 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); |
120 | 120 | ||
121 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( | 121 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( |
122 | store, context, &hash | 122 | store, context, &hash); |
123 | ); | ||
124 | 123 | ||
125 | struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multihashmap_get ( | 124 | struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multihashmap_get ( |
126 | map, &hash); | 125 | map, &hash); |
diff --git a/src/service/messenger/messenger_api_message.c b/src/service/messenger/messenger_api_message.c index f6d8c31f7..d98938671 100644 --- a/src/service/messenger/messenger_api_message.c +++ b/src/service/messenger/messenger_api_message.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gnunet_messenger_service.h" | 29 | #include "gnunet_messenger_service.h" |
30 | #include "gnunet_signatures.h" | 30 | #include "gnunet_signatures.h" |
31 | #include <stdint.h> | 31 | #include <stdint.h> |
32 | #include <string.h> | ||
32 | 33 | ||
33 | struct GNUNET_MESSENGER_MessageSignature | 34 | struct GNUNET_MESSENGER_MessageSignature |
34 | { | 35 | { |
@@ -1123,34 +1124,29 @@ transcribe_message (const struct GNUNET_MESSENGER_Message *message, | |||
1123 | } | 1124 | } |
1124 | 1125 | ||
1125 | 1126 | ||
1126 | struct GNUNET_MESSENGER_Message* | 1127 | enum GNUNET_GenericReturnValue |
1127 | read_transcript_message (const struct GNUNET_MESSENGER_Message *transcript) | 1128 | read_transcript_message (struct GNUNET_MESSENGER_Message *message) |
1128 | { | 1129 | { |
1129 | GNUNET_assert (transcript); | 1130 | GNUNET_assert (message); |
1130 | 1131 | ||
1131 | if (GNUNET_MESSENGER_KIND_TRANSCRIPT != transcript->header.kind) | 1132 | if (GNUNET_MESSENGER_KIND_TRANSCRIPT != message->header.kind) |
1132 | return NULL; | 1133 | return GNUNET_NO; |
1133 | 1134 | ||
1134 | const uint16_t data_length = transcript->body.transcript.length; | 1135 | const uint16_t data_length = message->body.transcript.length; |
1135 | 1136 | ||
1136 | struct GNUNET_MESSENGER_ShortMessage shortened; | 1137 | struct GNUNET_MESSENGER_ShortMessage shortened; |
1137 | if (GNUNET_YES != decode_short_message (&shortened, | 1138 | if (GNUNET_YES != decode_short_message (&shortened, |
1138 | data_length, | 1139 | data_length, |
1139 | transcript->body.transcript.data)) | 1140 | message->body.transcript.data)) |
1140 | { | 1141 | { |
1141 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1142 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1142 | "Decoding decrypted message failed!\n"); | 1143 | "Decoding decrypted message failed!\n"); |
1143 | 1144 | ||
1144 | return NULL; | 1145 | return GNUNET_NO; |
1145 | } | 1146 | } |
1146 | 1147 | ||
1147 | struct GNUNET_MESSENGER_Message *message = create_message(shortened.kind); | ||
1148 | |||
1149 | if (!message) | ||
1150 | return NULL; | ||
1151 | |||
1152 | unfold_short_message(&shortened, message); | 1148 | unfold_short_message(&shortened, message); |
1153 | return message; | 1149 | return GNUNET_YES; |
1154 | } | 1150 | } |
1155 | 1151 | ||
1156 | 1152 | ||
diff --git a/src/service/messenger/messenger_api_message.h b/src/service/messenger/messenger_api_message.h index a19eb36ba..f5bc62519 100644 --- a/src/service/messenger/messenger_api_message.h +++ b/src/service/messenger/messenger_api_message.h | |||
@@ -257,13 +257,15 @@ transcribe_message (const struct GNUNET_MESSENGER_Message *message, | |||
257 | const struct GNUNET_CRYPTO_PublicKey *key); | 257 | const struct GNUNET_CRYPTO_PublicKey *key); |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * Read the original message from a message <i>transcript</i>. | 260 | * Read the original message from a transcript <i>message</i> and replaces its body |
261 | * and kind with the inner encrypted message. The function returns #GNUNET_YES if the | ||
262 | * operation succeeded, otherwise #GNUNET_NO. | ||
261 | * | 263 | * |
262 | * @param[in] transcript Message transcript | 264 | * @param[in,out] transcript Message transcript |
263 | * @return Original message | 265 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO |
264 | */ | 266 | */ |
265 | struct GNUNET_MESSENGER_Message* | 267 | enum GNUNET_GenericReturnValue |
266 | read_transcript_message (const struct GNUNET_MESSENGER_Message *transcript); | 268 | read_transcript_message (struct GNUNET_MESSENGER_Message *message); |
267 | 269 | ||
268 | typedef void (*GNUNET_MESSENGER_SignFunction)( | 270 | typedef void (*GNUNET_MESSENGER_SignFunction)( |
269 | const void *cls, | 271 | const void *cls, |
diff --git a/src/service/messenger/messenger_api_room.c b/src/service/messenger/messenger_api_room.c index 364a4e674..6b127fca5 100644 --- a/src/service/messenger/messenger_api_room.c +++ b/src/service/messenger/messenger_api_room.c | |||
@@ -25,8 +25,12 @@ | |||
25 | 25 | ||
26 | #include "messenger_api_room.h" | 26 | #include "messenger_api_room.h" |
27 | 27 | ||
28 | #include "gnunet_common.h" | ||
29 | #include "gnunet_messenger_service.h" | ||
30 | #include "messenger_api_contact_store.h" | ||
28 | #include "messenger_api_handle.h" | 31 | #include "messenger_api_handle.h" |
29 | #include "messenger_api_message.h" | 32 | #include "messenger_api_message.h" |
33 | #include <string.h> | ||
30 | 34 | ||
31 | struct GNUNET_MESSENGER_Room* | 35 | struct GNUNET_MESSENGER_Room* |
32 | create_room (struct GNUNET_MESSENGER_Handle *handle, | 36 | create_room (struct GNUNET_MESSENGER_Handle *handle, |
@@ -178,8 +182,11 @@ get_room_message (const struct GNUNET_MESSENGER_Room *room, | |||
178 | GNUNET_CONTAINER_multihashmap_get ( | 182 | GNUNET_CONTAINER_multihashmap_get ( |
179 | room->messages, hash | 183 | room->messages, hash |
180 | ); | 184 | ); |
185 | |||
186 | if (! entry) | ||
187 | return NULL; | ||
181 | 188 | ||
182 | return (entry? entry->message : NULL); | 189 | return entry->message; |
183 | } | 190 | } |
184 | 191 | ||
185 | 192 | ||
@@ -213,50 +220,85 @@ get_room_recipient (const struct GNUNET_MESSENGER_Room *room, | |||
213 | } | 220 | } |
214 | 221 | ||
215 | 222 | ||
216 | static struct GNUNET_MESSENGER_Contact* | 223 | void |
224 | callback_room_message (struct GNUNET_MESSENGER_Room *room, | ||
225 | const struct GNUNET_HashCode *hash) | ||
226 | { | ||
227 | GNUNET_assert ((room) && (hash)); | ||
228 | |||
229 | struct GNUNET_MESSENGER_Handle *handle = room->handle; | ||
230 | |||
231 | if (! handle) | ||
232 | return; | ||
233 | |||
234 | struct GNUNET_MESSENGER_RoomMessageEntry *entry; | ||
235 | entry = GNUNET_CONTAINER_multihashmap_get (room->messages, hash); | ||
236 | |||
237 | if (! entry) | ||
238 | return; | ||
239 | |||
240 | if (handle->msg_callback) | ||
241 | handle->msg_callback (handle->msg_cls, room, | ||
242 | entry->sender, | ||
243 | entry->recipient, | ||
244 | entry->message, | ||
245 | hash, | ||
246 | entry->flags); | ||
247 | |||
248 | if (entry->flags & GNUNET_MESSENGER_FLAG_UPDATE) | ||
249 | entry->flags ^= GNUNET_MESSENGER_FLAG_UPDATE; | ||
250 | } | ||
251 | |||
252 | |||
253 | static void | ||
254 | handle_message (struct GNUNET_MESSENGER_Room *room, | ||
255 | const struct GNUNET_HashCode *hash, | ||
256 | struct GNUNET_MESSENGER_RoomMessageEntry *entry); | ||
257 | |||
258 | |||
259 | void | ||
217 | handle_join_message (struct GNUNET_MESSENGER_Room *room, | 260 | handle_join_message (struct GNUNET_MESSENGER_Room *room, |
218 | struct GNUNET_MESSENGER_Contact *sender, | 261 | const struct GNUNET_HashCode *hash, |
219 | const struct GNUNET_MESSENGER_Message *message, | 262 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
220 | const struct GNUNET_HashCode *hash) | ||
221 | { | 263 | { |
222 | if (! sender) | 264 | GNUNET_assert ((room) && (hash) && (entry)); |
265 | |||
266 | if (! entry->sender) | ||
223 | { | 267 | { |
224 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( | 268 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( |
225 | room->handle); | 269 | room->handle); |
226 | struct GNUNET_HashCode context; | 270 | struct GNUNET_HashCode context; |
227 | 271 | ||
228 | get_context_from_member (&(room->key), &(message->header.sender_id), | 272 | get_context_from_member (&(room->key), &(entry->message->header.sender_id), |
229 | &context); | 273 | &context); |
230 | 274 | ||
231 | sender = get_store_contact (store, &context, &(message->body.join.key)); | 275 | entry->sender = get_store_contact (store, &context, &(entry->message->body.join.key)); |
232 | } | 276 | } |
233 | 277 | ||
234 | if ((GNUNET_YES != GNUNET_CONTAINER_multishortmap_contains_value ( | 278 | if ((GNUNET_YES != GNUNET_CONTAINER_multishortmap_contains_value ( |
235 | room->members, &(message->header.sender_id), sender)) && | 279 | room->members, &(entry->message->header.sender_id), entry->sender)) && |
236 | (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put (room->members, | 280 | (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put (room->members, |
237 | &(message->header. | 281 | &(entry->message->header.sender_id), |
238 | sender_id), sender, | 282 | entry->sender, |
239 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | 283 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) |
240 | increase_contact_rc (sender); | 284 | increase_contact_rc (entry->sender); |
241 | |||
242 | return sender; | ||
243 | } | 285 | } |
244 | 286 | ||
245 | 287 | ||
246 | static void | 288 | static void |
247 | handle_leave_message (struct GNUNET_MESSENGER_Room *room, | 289 | handle_leave_message (struct GNUNET_MESSENGER_Room *room, |
248 | struct GNUNET_MESSENGER_Contact *sender, | 290 | const struct GNUNET_HashCode *hash, |
249 | const struct GNUNET_MESSENGER_Message *message, | 291 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
250 | const struct GNUNET_HashCode *hash) | ||
251 | { | 292 | { |
252 | if ((! sender) || | 293 | GNUNET_assert ((room) && (hash) && (entry)); |
294 | |||
295 | if ((! entry->sender) || | ||
253 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->members, | 296 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->members, |
254 | &(message->header. | 297 | &(entry->message->header.sender_id), |
255 | sender_id), | 298 | entry->sender))) |
256 | sender))) | ||
257 | return; | 299 | return; |
258 | 300 | ||
259 | if (GNUNET_YES == decrease_contact_rc (sender)) | 301 | if (GNUNET_YES == decrease_contact_rc (entry->sender)) |
260 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
261 | "A contact does not share any room with you anymore!\n"); | 303 | "A contact does not share any room with you anymore!\n"); |
262 | } | 304 | } |
@@ -264,12 +306,12 @@ handle_leave_message (struct GNUNET_MESSENGER_Room *room, | |||
264 | 306 | ||
265 | static void | 307 | static void |
266 | handle_name_message (struct GNUNET_MESSENGER_Room *room, | 308 | handle_name_message (struct GNUNET_MESSENGER_Room *room, |
267 | struct GNUNET_MESSENGER_Contact *sender, | ||
268 | const struct GNUNET_MESSENGER_Message *message, | ||
269 | const struct GNUNET_HashCode *hash, | 309 | const struct GNUNET_HashCode *hash, |
270 | enum GNUNET_MESSENGER_MessageFlags flags) | 310 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
271 | { | 311 | { |
272 | if (GNUNET_MESSENGER_FLAG_SENT & flags) | 312 | GNUNET_assert ((room) && (hash) && (entry)); |
313 | |||
314 | if (GNUNET_MESSENGER_FLAG_SENT & entry->flags) | ||
273 | { | 315 | { |
274 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 316 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
275 | "Set rule for using handle name in room: %s\n", | 317 | "Set rule for using handle name in room: %s\n", |
@@ -277,176 +319,363 @@ handle_name_message (struct GNUNET_MESSENGER_Room *room, | |||
277 | 319 | ||
278 | const char *handle_name = get_handle_name (room->handle); | 320 | const char *handle_name = get_handle_name (room->handle); |
279 | 321 | ||
280 | if ((handle_name) && (0 == strcmp (handle_name, message->body.name.name))) | 322 | if ((handle_name) && (0 == strcmp (handle_name, entry->message->body.name.name))) |
281 | room->use_handle_name = GNUNET_YES; | 323 | room->use_handle_name = GNUNET_YES; |
282 | } | 324 | } |
283 | 325 | ||
284 | if (! sender) | 326 | if (! entry->sender) |
285 | return; | 327 | return; |
286 | 328 | ||
287 | set_contact_name (sender, message->body.name.name); | 329 | set_contact_name (entry->sender, entry->message->body.name.name); |
288 | } | 330 | } |
289 | 331 | ||
290 | 332 | ||
291 | static void | 333 | static void |
292 | handle_key_message (struct GNUNET_MESSENGER_Room *room, | 334 | handle_key_message (struct GNUNET_MESSENGER_Room *room, |
293 | struct GNUNET_MESSENGER_Contact *sender, | 335 | const struct GNUNET_HashCode *hash, |
294 | const struct GNUNET_MESSENGER_Message *message, | 336 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
295 | const struct GNUNET_HashCode *hash) | ||
296 | { | 337 | { |
297 | if (! sender) | 338 | GNUNET_assert ((room) && (hash) && (entry)); |
339 | |||
340 | if (! entry->sender) | ||
298 | return; | 341 | return; |
299 | 342 | ||
300 | struct GNUNET_HashCode context; | 343 | struct GNUNET_HashCode context; |
301 | get_context_from_member (&(room->key), &(message->header.sender_id), | 344 | get_context_from_member (&(room->key), &(entry->message->header.sender_id), |
302 | &context); | 345 | &context); |
303 | 346 | ||
304 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( | 347 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( |
305 | room->handle); | 348 | room->handle); |
306 | 349 | ||
307 | update_store_contact (store, sender, &context, &context, | 350 | update_store_contact (store, entry->sender, &context, &context, |
308 | &(message->body.key.key)); | 351 | &(entry->message->body.key.key)); |
309 | } | 352 | } |
310 | 353 | ||
311 | 354 | ||
312 | static void | 355 | static void |
313 | handle_id_message (struct GNUNET_MESSENGER_Room *room, | 356 | handle_id_message (struct GNUNET_MESSENGER_Room *room, |
314 | struct GNUNET_MESSENGER_Contact *sender, | ||
315 | const struct GNUNET_MESSENGER_Message *message, | ||
316 | const struct GNUNET_HashCode *hash, | 357 | const struct GNUNET_HashCode *hash, |
317 | enum GNUNET_MESSENGER_MessageFlags flags) | 358 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
318 | { | 359 | { |
319 | if (GNUNET_MESSENGER_FLAG_SENT & flags) | 360 | GNUNET_assert ((room) && (hash) && (entry)); |
320 | set_room_sender_id (room, &(message->body.id.id)); | ||
321 | 361 | ||
322 | if ((! sender) || | 362 | if (GNUNET_MESSENGER_FLAG_SENT & entry->flags) |
363 | set_room_sender_id (room, &(entry->message->body.id.id)); | ||
364 | |||
365 | if ((! entry->sender) || | ||
323 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->members, | 366 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->members, |
324 | &(message->header. | 367 | &(entry->message->header.sender_id), |
325 | sender_id), | 368 | entry->sender)) || |
326 | sender)) || | ||
327 | (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put (room->members, | 369 | (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put (room->members, |
328 | &(message->body.id.id), | 370 | &(entry->message->body.id.id), |
329 | sender, | 371 | entry->sender, |
330 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | 372 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) |
331 | return; | 373 | return; |
332 | 374 | ||
333 | struct GNUNET_HashCode context, next_context; | 375 | struct GNUNET_HashCode context, next_context; |
334 | get_context_from_member (&(room->key), &(message->header.sender_id), | 376 | get_context_from_member (&(room->key), &(entry->message->header.sender_id), |
335 | &context); | 377 | &context); |
336 | get_context_from_member (&(room->key), &(message->body.id.id), &next_context); | 378 | get_context_from_member (&(room->key), &(entry->message->body.id.id), &next_context); |
337 | 379 | ||
338 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( | 380 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( |
339 | room->handle); | 381 | room->handle); |
340 | 382 | ||
341 | update_store_contact (store, sender, &context, &next_context, | 383 | update_store_contact (store, entry->sender, &context, &next_context, |
342 | get_contact_key (sender)); | 384 | get_contact_key (entry->sender)); |
343 | } | 385 | } |
344 | 386 | ||
345 | 387 | ||
346 | static void | 388 | static void |
347 | handle_miss_message (struct GNUNET_MESSENGER_Room *room, | 389 | handle_miss_message (struct GNUNET_MESSENGER_Room *room, |
348 | struct GNUNET_MESSENGER_Contact *sender, | ||
349 | const struct GNUNET_MESSENGER_Message *message, | ||
350 | const struct GNUNET_HashCode *hash, | 390 | const struct GNUNET_HashCode *hash, |
351 | enum GNUNET_MESSENGER_MessageFlags flags) | 391 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
352 | { | 392 | { |
353 | if (GNUNET_MESSENGER_FLAG_SENT & flags) | 393 | GNUNET_assert ((room) && (hash) && (entry)); |
354 | { | 394 | |
355 | struct GNUNET_MESSENGER_ListTunnel *match = find_list_tunnels ( | 395 | if (0 == (GNUNET_MESSENGER_FLAG_SENT & entry->flags)) |
356 | &(room->entries), &(message->body.miss.peer), NULL); | 396 | return; |
397 | |||
398 | struct GNUNET_MESSENGER_ListTunnel *match = find_list_tunnels ( | ||
399 | &(room->entries), &(entry->message->body.miss.peer), NULL); | ||
400 | |||
401 | if (match) | ||
402 | remove_from_list_tunnels (&(room->entries), match); | ||
403 | } | ||
404 | |||
405 | |||
406 | static void | ||
407 | handle_private_message (struct GNUNET_MESSENGER_Room *room, | ||
408 | const struct GNUNET_HashCode *hash, | ||
409 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) | ||
410 | { | ||
411 | GNUNET_assert ((room) && (hash) && (entry)); | ||
412 | |||
413 | struct GNUNET_MESSENGER_Message *private_message = copy_message (entry->message); | ||
357 | 414 | ||
358 | if (match) | 415 | if (! private_message) |
359 | remove_from_list_tunnels (&(room->entries), match); | 416 | return; |
417 | |||
418 | if (GNUNET_YES != decrypt_message (private_message, | ||
419 | get_handle_key (room->handle))) | ||
420 | { | ||
421 | destroy_message (private_message); | ||
422 | private_message = NULL; | ||
360 | } | 423 | } |
424 | |||
425 | if (! private_message) | ||
426 | return; | ||
427 | |||
428 | destroy_message (entry->message); | ||
429 | |||
430 | entry->recipient = get_handle_contact (room->handle, &(room->key)); | ||
431 | |||
432 | entry->message = private_message; | ||
433 | entry->flags |= GNUNET_MESSENGER_FLAG_PRIVATE; | ||
434 | |||
435 | if ((entry->sender) && (entry->recipient)) | ||
436 | handle_message (room, hash, entry); | ||
361 | } | 437 | } |
362 | 438 | ||
363 | 439 | ||
440 | extern void | ||
441 | delete_message_in_room (struct GNUNET_MESSENGER_Room *room, | ||
442 | const struct GNUNET_HashCode *hash, | ||
443 | const struct GNUNET_TIME_Relative delay); | ||
444 | |||
445 | |||
364 | static void | 446 | static void |
365 | handle_delete_message (struct GNUNET_MESSENGER_Room *room, | 447 | handle_delete_message (struct GNUNET_MESSENGER_Room *room, |
366 | struct GNUNET_MESSENGER_Contact *sender, | 448 | const struct GNUNET_HashCode *hash, |
367 | const struct GNUNET_MESSENGER_Message *message, | 449 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
368 | const struct GNUNET_HashCode *hash) | ||
369 | { | 450 | { |
370 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = | 451 | GNUNET_assert ((room) && (hash) && (entry)); |
371 | GNUNET_CONTAINER_multihashmap_get ( | ||
372 | room->messages, &(message->body.deletion.hash) | ||
373 | ); | ||
374 | 452 | ||
375 | if ((entry) && ((entry->sender == sender) || (get_handle_contact ( | 453 | const struct GNUNET_HashCode *target_hash = &(entry->message->body.deletion.hash); |
376 | room->handle, &(room->key)) == | 454 | |
377 | sender)) && | 455 | if (get_handle_contact (room->handle, &(room->key)) == entry->sender) |
378 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (room->messages, | ||
379 | &(message->body. | ||
380 | deletion.hash), | ||
381 | entry))) | ||
382 | { | 456 | { |
383 | destroy_message (entry->message); | 457 | struct GNUNET_TIME_Relative delay; |
384 | GNUNET_free (entry); | 458 | struct GNUNET_TIME_Absolute action; |
459 | |||
460 | delay = GNUNET_TIME_relative_ntoh (entry->message->body.deletion.delay); | ||
461 | |||
462 | action = GNUNET_TIME_absolute_ntoh (entry->message->header.timestamp); | ||
463 | action = GNUNET_TIME_absolute_add (action, delay); | ||
464 | |||
465 | delay = GNUNET_TIME_absolute_get_difference (GNUNET_TIME_absolute_get (), | ||
466 | action); | ||
467 | |||
468 | link_room_deletion(room, target_hash, delay, delete_message_in_room); | ||
469 | } | ||
470 | |||
471 | struct GNUNET_MESSENGER_RoomMessageEntry *target = | ||
472 | GNUNET_CONTAINER_multihashmap_get (room->messages, target_hash); | ||
473 | |||
474 | if (! target) | ||
475 | return; | ||
476 | |||
477 | if (((target->sender != entry->sender) && | ||
478 | (get_handle_contact (room->handle, &(room->key)) != entry->sender))) | ||
479 | return; | ||
480 | |||
481 | target->flags |= GNUNET_MESSENGER_FLAG_DELETE; | ||
482 | callback_room_message (room, target_hash); | ||
483 | |||
484 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (room->messages, | ||
485 | target_hash, | ||
486 | target)) | ||
487 | { | ||
488 | destroy_message (target->message); | ||
489 | GNUNET_free (target); | ||
385 | } | 490 | } |
386 | } | 491 | } |
387 | 492 | ||
388 | 493 | ||
389 | struct GNUNET_MESSENGER_Contact* | 494 | static void |
390 | handle_room_message (struct GNUNET_MESSENGER_Room *room, | 495 | handle_transcript_message (struct GNUNET_MESSENGER_Room *room, |
391 | struct GNUNET_MESSENGER_Contact *sender, | 496 | const struct GNUNET_HashCode *hash, |
392 | struct GNUNET_MESSENGER_Contact *recipient, | 497 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) |
393 | const struct GNUNET_MESSENGER_Message *message, | ||
394 | const struct GNUNET_HashCode *hash, | ||
395 | enum GNUNET_MESSENGER_MessageFlags flags) | ||
396 | { | 498 | { |
397 | if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->messages, | 499 | GNUNET_assert ((room) && (hash) && (entry)); |
398 | hash)) | ||
399 | return sender; | ||
400 | 500 | ||
401 | switch (message->header.kind) | 501 | if (get_handle_contact (room->handle, &(room->key)) != entry->sender) |
502 | return; | ||
503 | |||
504 | const struct GNUNET_HashCode *original_hash = &(entry->message->body.transcript.hash); | ||
505 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store ( | ||
506 | room->handle); | ||
507 | |||
508 | struct GNUNET_MESSENGER_RoomMessageEntry *original = | ||
509 | GNUNET_CONTAINER_multihashmap_get (room->messages, original_hash); | ||
510 | struct GNUNET_MESSENGER_Message *original_message; | ||
511 | |||
512 | if (original) | ||
513 | goto read_transcript; | ||
514 | |||
515 | original = GNUNET_new (struct GNUNET_MESSENGER_RoomMessageEntry); | ||
516 | |||
517 | if (! original) | ||
518 | return; | ||
519 | |||
520 | original->sender = NULL; | ||
521 | original->recipient = NULL; | ||
522 | |||
523 | original->message = NULL; | ||
524 | original->flags = GNUNET_MESSENGER_FLAG_NONE; | ||
525 | |||
526 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, | ||
527 | original_hash, | ||
528 | original, | ||
529 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
530 | { | ||
531 | GNUNET_free (original); | ||
532 | return; | ||
533 | } | ||
534 | |||
535 | read_transcript: | ||
536 | original_message = copy_message (entry->message); | ||
537 | |||
538 | if (! original_message) | ||
539 | return; | ||
540 | |||
541 | if (GNUNET_YES != read_transcript_message (original_message)) | ||
542 | { | ||
543 | destroy_message (original_message); | ||
544 | return; | ||
545 | } | ||
546 | |||
547 | original->recipient = get_store_contact (store, | ||
548 | NULL, | ||
549 | &(entry->message->body.transcript.key)); | ||
550 | |||
551 | if (original->message) | ||
552 | { | ||
553 | enum GNUNET_MESSENGER_MessageKind kind = original_message->header.kind; | ||
554 | memcpy (&(original_message->header), &(original->message->header), | ||
555 | sizeof(struct GNUNET_MESSENGER_MessageHeader)); | ||
556 | original_message->header.kind = kind; | ||
557 | |||
558 | destroy_message (original->message); | ||
559 | } | ||
560 | |||
561 | original->message = original_message; | ||
562 | original->flags |= GNUNET_MESSENGER_FLAG_PRIVATE; | ||
563 | |||
564 | link_room_message(room, hash, original_hash); | ||
565 | link_room_message(room, original_hash, hash); | ||
566 | |||
567 | if ((original->sender) && (original->recipient)) | ||
568 | { | ||
569 | original->flags |= GNUNET_MESSENGER_FLAG_UPDATE; | ||
570 | handle_message (room, original_hash, original); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | |||
575 | static void | ||
576 | handle_message (struct GNUNET_MESSENGER_Room *room, | ||
577 | const struct GNUNET_HashCode *hash, | ||
578 | struct GNUNET_MESSENGER_RoomMessageEntry *entry) | ||
579 | { | ||
580 | GNUNET_assert ((room) && (hash) && (entry)); | ||
581 | |||
582 | switch (entry->message->header.kind) | ||
402 | { | 583 | { |
403 | case GNUNET_MESSENGER_KIND_JOIN: | 584 | case GNUNET_MESSENGER_KIND_JOIN: |
404 | sender = handle_join_message (room, sender, message, hash); | 585 | handle_join_message (room, hash, entry); |
405 | break; | 586 | break; |
406 | case GNUNET_MESSENGER_KIND_LEAVE: | 587 | case GNUNET_MESSENGER_KIND_LEAVE: |
407 | handle_leave_message (room, sender, message, hash); | 588 | handle_leave_message (room, hash, entry); |
408 | break; | 589 | break; |
409 | case GNUNET_MESSENGER_KIND_NAME: | 590 | case GNUNET_MESSENGER_KIND_NAME: |
410 | handle_name_message (room, sender, message, hash, flags); | 591 | handle_name_message (room, hash, entry); |
411 | break; | 592 | break; |
412 | case GNUNET_MESSENGER_KIND_KEY: | 593 | case GNUNET_MESSENGER_KIND_KEY: |
413 | handle_key_message (room, sender, message, hash); | 594 | handle_key_message (room, hash, entry); |
414 | break; | 595 | break; |
415 | case GNUNET_MESSENGER_KIND_ID: | 596 | case GNUNET_MESSENGER_KIND_ID: |
416 | handle_id_message (room, sender, message, hash, flags); | 597 | handle_id_message (room, hash, entry); |
417 | break; | 598 | break; |
418 | case GNUNET_MESSENGER_KIND_MISS: | 599 | case GNUNET_MESSENGER_KIND_MISS: |
419 | handle_miss_message (room, sender, message, hash, flags); | 600 | handle_miss_message (room, hash, entry); |
601 | break; | ||
602 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
603 | handle_private_message (room, hash, entry); | ||
420 | break; | 604 | break; |
421 | case GNUNET_MESSENGER_KIND_DELETE: | 605 | case GNUNET_MESSENGER_KIND_DELETE: |
422 | handle_delete_message (room, sender, message, hash); | 606 | handle_delete_message (room, hash, entry); |
607 | break; | ||
608 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | ||
609 | handle_transcript_message (room, hash, entry); | ||
423 | break; | 610 | break; |
424 | default: | 611 | default: |
425 | break; | 612 | break; |
426 | } | 613 | } |
427 | 614 | ||
428 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_new (struct | 615 | if (entry->flags & GNUNET_MESSENGER_FLAG_UPDATE) |
429 | GNUNET_MESSENGER_RoomMessageEntry); | 616 | callback_room_message (room, hash); |
617 | } | ||
618 | |||
619 | |||
620 | void | ||
621 | handle_room_message (struct GNUNET_MESSENGER_Room *room, | ||
622 | struct GNUNET_MESSENGER_Contact *sender, | ||
623 | const struct GNUNET_MESSENGER_Message *message, | ||
624 | const struct GNUNET_HashCode *hash, | ||
625 | enum GNUNET_MESSENGER_MessageFlags flags) | ||
626 | { | ||
627 | GNUNET_assert ((room) && (message) && (hash)); | ||
628 | |||
629 | struct GNUNET_MESSENGER_RoomMessageEntry *entry; | ||
630 | entry = GNUNET_CONTAINER_multihashmap_get (room->messages, hash); | ||
631 | |||
632 | if (entry) | ||
633 | goto update_entry; | ||
634 | |||
635 | entry = GNUNET_new (struct GNUNET_MESSENGER_RoomMessageEntry); | ||
430 | 636 | ||
431 | if (! entry) | 637 | if (! entry) |
432 | return sender; | 638 | return; |
433 | 639 | ||
434 | entry->sender = sender; | 640 | entry->sender = NULL; |
435 | entry->recipient = recipient; | 641 | entry->recipient = NULL; |
436 | entry->message = copy_message (message); | 642 | |
643 | entry->message = NULL; | ||
644 | entry->flags = GNUNET_MESSENGER_FLAG_NONE; | ||
437 | 645 | ||
438 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, | 646 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, |
439 | entry, | 647 | entry, |
440 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 648 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
441 | { | 649 | { |
442 | destroy_message (entry->message); | ||
443 | GNUNET_free (entry); | 650 | GNUNET_free (entry); |
651 | return; | ||
652 | } | ||
653 | |||
654 | update_entry: | ||
655 | entry->sender = sender; | ||
656 | entry->flags = flags; | ||
657 | |||
658 | if (entry->message) | ||
659 | { | ||
660 | enum GNUNET_MESSENGER_MessageKind kind = message->header.kind; | ||
661 | memcpy (&(entry->message->header), &(message->header), | ||
662 | sizeof(struct GNUNET_MESSENGER_MessageHeader)); | ||
663 | entry->message->header.kind = kind; | ||
444 | } | 664 | } |
665 | else | ||
666 | entry->message = copy_message (message); | ||
667 | |||
668 | handle_message (room, hash, entry); | ||
669 | } | ||
445 | 670 | ||
446 | if (flags & GNUNET_MESSENGER_FLAG_RECENT) | ||
447 | GNUNET_memcpy (&(room->last_message), hash, sizeof(room->last_message)); | ||
448 | 671 | ||
449 | return sender; | 672 | void |
673 | update_room_last_message (struct GNUNET_MESSENGER_Room *room, | ||
674 | const struct GNUNET_HashCode *hash) | ||
675 | { | ||
676 | GNUNET_assert ((room) && (hash)); | ||
677 | |||
678 | GNUNET_memcpy (&(room->last_message), hash, sizeof(room->last_message)); | ||
450 | } | 679 | } |
451 | 680 | ||
452 | 681 | ||
diff --git a/src/service/messenger/messenger_api_room.h b/src/service/messenger/messenger_api_room.h index 79571bc2e..7587fb256 100644 --- a/src/service/messenger/messenger_api_room.h +++ b/src/service/messenger/messenger_api_room.h | |||
@@ -40,7 +40,9 @@ struct GNUNET_MESSENGER_RoomMessageEntry | |||
40 | { | 40 | { |
41 | struct GNUNET_MESSENGER_Contact *sender; | 41 | struct GNUNET_MESSENGER_Contact *sender; |
42 | struct GNUNET_MESSENGER_Contact *recipient; | 42 | struct GNUNET_MESSENGER_Contact *recipient; |
43 | |||
43 | struct GNUNET_MESSENGER_Message *message; | 44 | struct GNUNET_MESSENGER_Message *message; |
45 | enum GNUNET_MESSENGER_MessageFlags flags; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | struct GNUNET_MESSENGER_Room | 48 | struct GNUNET_MESSENGER_Room |
@@ -153,6 +155,16 @@ get_room_recipient (const struct GNUNET_MESSENGER_Room *room, | |||
153 | const struct GNUNET_HashCode *hash); | 155 | const struct GNUNET_HashCode *hash); |
154 | 156 | ||
155 | /** | 157 | /** |
158 | * Executes the message callback for a given <i>hash</i> in a <i>room</i>. | ||
159 | * | ||
160 | * @param[in,out] room Room | ||
161 | * @param[in] hash Hash of message | ||
162 | */ | ||
163 | void | ||
164 | callback_room_message (struct GNUNET_MESSENGER_Room *room, | ||
165 | const struct GNUNET_HashCode *hash); | ||
166 | |||
167 | /** | ||
156 | * Handles a <i>message</i> with a given <i>hash</i> in a <i>room</i> for the client API to update | 168 | * Handles a <i>message</i> with a given <i>hash</i> in a <i>room</i> for the client API to update |
157 | * members and its information. The function also stores the message in map locally for access afterwards. | 169 | * members and its information. The function also stores the message in map locally for access afterwards. |
158 | * | 170 | * |
@@ -161,21 +173,29 @@ get_room_recipient (const struct GNUNET_MESSENGER_Room *room, | |||
161 | * | 173 | * |
162 | * @param[in,out] room Room | 174 | * @param[in,out] room Room |
163 | * @param[in,out] sender Contact of sender | 175 | * @param[in,out] sender Contact of sender |
164 | * @param[in,out] recipient Contact of recipient | ||
165 | * @param[in] message Message | 176 | * @param[in] message Message |
166 | * @param[in] hash Hash of message | 177 | * @param[in] hash Hash of message |
167 | * @param[in] flags Flags of message | 178 | * @param[in] flags Flags of message |
168 | * @return Contact of sender | ||
169 | */ | 179 | */ |
170 | struct GNUNET_MESSENGER_Contact* | 180 | void |
171 | handle_room_message (struct GNUNET_MESSENGER_Room *room, | 181 | handle_room_message (struct GNUNET_MESSENGER_Room *room, |
172 | struct GNUNET_MESSENGER_Contact *sender, | 182 | struct GNUNET_MESSENGER_Contact *sender, |
173 | struct GNUNET_MESSENGER_Contact *recipient, | ||
174 | const struct GNUNET_MESSENGER_Message *message, | 183 | const struct GNUNET_MESSENGER_Message *message, |
175 | const struct GNUNET_HashCode *hash, | 184 | const struct GNUNET_HashCode *hash, |
176 | enum GNUNET_MESSENGER_MessageFlags flags); | 185 | enum GNUNET_MESSENGER_MessageFlags flags); |
177 | 186 | ||
178 | /** | 187 | /** |
188 | * Updates the last message <i>hash</i> of a <i>room</i> for the client API so that new messages can | ||
189 | * point to the latest message hash while sending. | ||
190 | * | ||
191 | * @param[in,out] room Room | ||
192 | * @param[in] hash Hash of message | ||
193 | */ | ||
194 | void | ||
195 | update_room_last_message (struct GNUNET_MESSENGER_Room *room, | ||
196 | const struct GNUNET_HashCode *hash); | ||
197 | |||
198 | /** | ||
179 | * Iterates through all members of a given <i>room</i> to forward each of them to a selected | 199 | * Iterates through all members of a given <i>room</i> to forward each of them to a selected |
180 | * <i>callback</i> with a custom closure. | 200 | * <i>callback</i> with a custom closure. |
181 | * | 201 | * |