aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_room.c
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2021-03-20 13:53:23 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2021-04-04 17:58:11 +0200
commitac3aa3cc3a617bc54ed8beb2b5a30c0b95483525 (patch)
tree6e0444e568722f18501746665a07dfa3434c7ad6 /src/messenger/gnunet-service-messenger_room.c
parent2413977f917534aa24ef562a28da193a2cdaa343 (diff)
downloadgnunet-ac3aa3cc3a617bc54ed8beb2b5a30c0b95483525.tar.gz
gnunet-ac3aa3cc3a617bc54ed8beb2b5a30c0b95483525.zip
-multiple fixes and correction regarding messenger service
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added message states to tunnels Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed requests for deleted messages returning previous ones Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added automatic solving of member id collissions Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added light timestamp verification Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed decoding asserts and member session forwarding Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added permission check for member sessions during local join Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat (limited to 'src/messenger/gnunet-service-messenger_room.c')
-rw-r--r--src/messenger/gnunet-service-messenger_room.c277
1 files changed, 180 insertions, 97 deletions
diff --git a/src/messenger/gnunet-service-messenger_room.c b/src/messenger/gnunet-service-messenger_room.c
index 027df682c..e8fe5b1f3 100644
--- a/src/messenger/gnunet-service-messenger_room.c
+++ b/src/messenger/gnunet-service-messenger_room.c
@@ -62,7 +62,7 @@ create_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_Hash
62 init_operation_store(get_room_operation_store(room), room); 62 init_operation_store(get_room_operation_store(room), room);
63 63
64 init_list_tunnels (&(room->basement)); 64 init_list_tunnels (&(room->basement));
65 init_list_messages (&(room->last_messages)); 65 init_message_state(&(room->state));
66 66
67 room->peer_message = NULL; 67 room->peer_message = NULL;
68 68
@@ -117,7 +117,7 @@ destroy_room (struct GNUNET_MESSENGER_SrvRoom *room)
117 GNUNET_CONTAINER_multipeermap_destroy (room->tunnels); 117 GNUNET_CONTAINER_multipeermap_destroy (room->tunnels);
118 118
119 clear_list_tunnels (&(room->basement)); 119 clear_list_tunnels (&(room->basement));
120 clear_list_messages (&(room->last_messages)); 120 clear_message_state(&(room->state));
121 121
122 if (room->peer_message) 122 if (room->peer_message)
123 GNUNET_free(room->peer_message); 123 GNUNET_free(room->peer_message);
@@ -149,22 +149,6 @@ get_room_operation_store (struct GNUNET_MESSENGER_SrvRoom *room)
149 return &(room->operation_store); 149 return &(room->operation_store);
150} 150}
151 151
152const struct GNUNET_ShortHashCode*
153get_room_host_id (const struct GNUNET_MESSENGER_SrvRoom *room)
154{
155 GNUNET_assert(room);
156
157 return get_handle_member_id (room->host, get_room_key(room));
158}
159
160void
161change_room_host_id (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *unique_id)
162{
163 GNUNET_assert(room);
164
165 change_handle_member_id (room->host, get_room_key(room), unique_id);
166}
167
168static int 152static int
169send_room_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, 153send_room_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle,
170 struct GNUNET_MESSENGER_SrvTunnel *tunnel) 154 struct GNUNET_MESSENGER_SrvTunnel *tunnel)
@@ -243,27 +227,50 @@ struct GNUNET_MESSENGER_MemberNotify
243 struct GNUNET_MESSENGER_MemberSession *session; 227 struct GNUNET_MESSENGER_MemberSession *session;
244}; 228};
245 229
246static int 230static void
247iterate_notify_about_members (void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, 231notify_about_members (struct GNUNET_MESSENGER_MemberNotify *notify, struct GNUNET_MESSENGER_MemberSession *session,
248 struct GNUNET_MESSENGER_MemberSession *session) 232 struct GNUNET_CONTAINER_MultiHashMap *map, int check_permission)
249{ 233{
250 struct GNUNET_MESSENGER_MemberNotify *notify = cls; 234 if (session->prev)
251 235 notify_about_members (notify, session->prev, map, GNUNET_YES);
252 if (notify->session == session)
253 return GNUNET_YES;
254 236
237 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(notify->room);
255 struct GNUNET_MESSENGER_ListMessage *element; 238 struct GNUNET_MESSENGER_ListMessage *element;
256 239
257 for (element = session->messages.head; element; element = element->next) 240 for (element = session->messages.head; element; element = element->next)
258 { 241 {
259 const struct GNUNET_MESSENGER_Message *message = get_room_message ( 242 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(map, &(element->hash)))
260 notify->room, notify->handle, &(element->hash), GNUNET_NO 243 continue;
261 ); 244
245 if ((GNUNET_YES == check_permission) &&
246 (GNUNET_YES != check_member_session_history(notify->session, &(element->hash), GNUNET_NO)))
247 continue;
248
249 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), NULL,
250 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
251 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notification of session message could be duplicated!\n");
252
253 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, &(element->hash));
262 254
263 if (message) 255 if (message)
264 notify_handle_message (notify->handle, get_room_key(notify->room), session, message, &(element->hash)); 256 notify_handle_message (notify->handle, get_room_key(notify->room), session, message, &(element->hash));
265 } 257 }
258}
259
260static int
261iterate_notify_about_members (void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key,
262 struct GNUNET_MESSENGER_MemberSession *session)
263{
264 struct GNUNET_MESSENGER_MemberNotify *notify = cls;
266 265
266 if ((notify->session == session) || (GNUNET_YES == is_member_session_completed(session)))
267 return GNUNET_YES;
268
269 struct GNUNET_CONTAINER_MultiHashMap *map = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO);
270
271 notify_about_members (notify, session, map, GNUNET_NO);
272
273 GNUNET_CONTAINER_multihashmap_destroy(map);
267 return GNUNET_YES; 274 return GNUNET_YES;
268} 275}
269 276
@@ -407,11 +414,7 @@ pack_room_message (const struct GNUNET_MESSENGER_SrvRoom *room, const struct GNU
407 GNUNET_assert(id); 414 GNUNET_assert(id);
408 415
409 GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode)); 416 GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode));
410 417 get_message_state_chain_hash (&(room->state), &(message->header.previous));
411 if (room->last_messages.head)
412 GNUNET_memcpy(&(message->header.previous), &(room->last_messages.head->hash), sizeof(struct GNUNET_HashCode));
413 else
414 memset (&(message->header.previous), 0, sizeof(struct GNUNET_HashCode));
415 418
416 return pack_message (message, hash, get_handle_ego (handle), mode); 419 return pack_message (message, hash, get_handle_ego (handle), mode);
417} 420}
@@ -510,6 +513,9 @@ send_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGE
510 case GNUNET_MESSENGER_KIND_PEER: 513 case GNUNET_MESSENGER_KIND_PEER:
511 send_message_peer (room, handle, message, &hash); 514 send_message_peer (room, handle, message, &hash);
512 break; 515 break;
516 case GNUNET_MESSENGER_KIND_ID:
517 send_message_id (room, handle, message, &hash);
518 break;
513 case GNUNET_MESSENGER_KIND_REQUEST: 519 case GNUNET_MESSENGER_KIND_REQUEST:
514 send_message_request (room, handle, message, &hash); 520 send_message_request (room, handle, message, &hash);
515 break; 521 break;
@@ -551,7 +557,9 @@ check_room_peer_status (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MES
551 if (!room->peer_message) 557 if (!room->peer_message)
552 return; 558 return;
553 559
554 const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, room->peer_message, GNUNET_NO); 560 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
561
562 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, room->peer_message);
555 563
556 if (!message) 564 if (!message)
557 { 565 {
@@ -581,15 +589,6 @@ resend_peer_message:
581 send_room_message (room, room->host, create_message_peer (room->service)); 589 send_room_message (room, room->host, create_message_peer (room->service));
582} 590}
583 591
584static void
585merge_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle,
586 const struct GNUNET_HashCode *hash)
587{
588 GNUNET_assert((room) && (handle) && (hash));
589
590 send_room_message (room, handle, create_message_merge (hash));
591}
592
593void 592void
594merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle) 593merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
595{ 594{
@@ -598,21 +597,21 @@ merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_M
598 if (!handle) 597 if (!handle)
599 return; 598 return;
600 599
601 if (!room->last_messages.head) 600 const struct GNUNET_HashCode *hash;
601
602merge_next:
603 hash = get_message_state_merge_hash (&(room->state));
604
605 if (!hash)
602 return; 606 return;
603 607
604 while (room->last_messages.head != room->last_messages.tail) 608 send_room_message (room, handle, create_message_merge (hash));
605 merge_room_message (room, handle, &(room->last_messages.tail->hash)); 609 goto merge_next;
606} 610}
607 611
608void 612void
609callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash) 613callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
610{ 614{
611 const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, hash, GNUNET_NO);
612
613 if (message)
614 add_to_list_messages(&(room->last_messages), &(message->header.previous));
615
616 if (GNUNET_OK != delete_store_message (get_room_message_store(room), hash)) 615 if (GNUNET_OK != delete_store_message (get_room_message_store(room), hash))
617 { 616 {
618 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! (%s)\n", GNUNET_h2s(hash)); 617 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! (%s)\n", GNUNET_h2s(hash));
@@ -626,7 +625,7 @@ callback_room_merge (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_
626 if (!room->host) 625 if (!room->host)
627 return; 626 return;
628 627
629 merge_room_message (room, room->host, hash); 628 send_room_message (room, room->host, create_message_merge (hash));
630} 629}
631 630
632int 631int
@@ -643,7 +642,9 @@ delete_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSEN
643 return GNUNET_SYSERR; 642 return GNUNET_SYSERR;
644 } 643 }
645 644
646 const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, hash, GNUNET_NO); 645 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
646
647 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
647 648
648 if (!message) 649 if (!message)
649 return GNUNET_YES; 650 return GNUNET_YES;
@@ -691,23 +692,56 @@ get_room_tunnel (const struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNE
691 return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer); 692 return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer);
692} 693}
693 694
694const struct GNUNET_MESSENGER_Message* 695static int
695get_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, 696request_room_message_step (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash,
696 const struct GNUNET_HashCode *hash, int request) 697 const struct GNUNET_MESSENGER_MemberSession *session,
698 GNUNET_MESSENGER_MessageRequestCallback callback, void* cls)
697{ 699{
698 GNUNET_assert((room) && (hash)); 700 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
699 701
700 const struct GNUNET_MESSENGER_Message *message = get_store_message (get_room_message_store(room), hash); 702 const struct GNUNET_MESSENGER_MessageLink *link = get_store_message_link(
703 message_store, hash, GNUNET_YES
704 );
701 705
702 if ((message) || (!handle) || (GNUNET_YES != request)) 706 if (!link)
703 return message; 707 goto forward;
704 708
705 struct GNUNET_MESSENGER_OperationStore* operation_store = get_room_operation_store(room); 709 int result = request_room_message_step(room, &(link->first), session, callback, cls);
706 710
707 if (GNUNET_OK == use_store_operation(operation_store, hash, GNUNET_MESSENGER_OP_REQUEST, GNUNET_MESSENGER_REQUEST_DELAY)) 711 if ((GNUNET_YES == link->multiple) &&
708 send_room_message (room, handle, create_message_request (hash)); 712 (GNUNET_YES == request_room_message_step(room, &(link->second), session, callback, cls)))
713 return GNUNET_YES;
714 else
715 return result;
709 716
710 return NULL; 717forward:
718 if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO))
719 return GNUNET_YES;
720
721 const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
722
723 if (!message)
724 return GNUNET_NO;
725
726 if (callback)
727 callback (cls, room, message, hash);
728
729 return GNUNET_YES;
730}
731
732int
733request_room_message (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash,
734 const struct GNUNET_MESSENGER_MemberSession *session,
735 GNUNET_MESSENGER_MessageRequestCallback callback, void* cls)
736{
737 GNUNET_assert((room) && (hash));
738
739 int result = request_room_message_step (room, hash, session, callback, cls);
740
741 if ((GNUNET_NO == result) && (callback))
742 callback (cls, room, NULL, hash);
743
744 return result;
711} 745}
712 746
713void 747void
@@ -739,6 +773,23 @@ callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, void *cls,
739 return GNUNET_SYSERR; 773 return GNUNET_SYSERR;
740 } 774 }
741 775
776 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
777
778 const struct GNUNET_MESSENGER_Message *previous = get_store_message(message_store, &(message->header.previous));
779
780 if (!previous)
781 goto skip_time_comparison;
782
783 struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh(message->header.timestamp);
784 struct GNUNET_TIME_Absolute last = GNUNET_TIME_absolute_ntoh(previous->header.timestamp);
785
786 if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(timestamp, last).rel_value_us)
787 {
788 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Timestamp does not check out!\n");
789 return GNUNET_SYSERR;
790 }
791
792skip_time_comparison:
742 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n", 793 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n",
743 GNUNET_MESSENGER_name_of_kind(message->header.kind)); 794 GNUNET_MESSENGER_name_of_kind(message->header.kind));
744 795
@@ -753,12 +804,13 @@ idle_request_room_messages (void *cls)
753 room->idle = NULL; 804 room->idle = NULL;
754 805
755 struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); 806 struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
807 const struct GNUNET_HashCode *hash = get_message_state_merge_hash(&(room->state));
756 808
757 if ((room->last_messages.head != room->last_messages.tail) && 809 if ((hash) &&
758 (GNUNET_MESSENGER_OP_UNKNOWN == get_store_operation_type(operation_store, &(room->last_messages.tail->hash)))) 810 (GNUNET_MESSENGER_OP_UNKNOWN == get_store_operation_type(operation_store, hash)))
759 use_store_operation( 811 use_store_operation(
760 operation_store, 812 operation_store,
761 &(room->last_messages.tail->hash), 813 hash,
762 GNUNET_MESSENGER_OP_MERGE, 814 GNUNET_MESSENGER_OP_MERGE,
763 GNUNET_MESSENGER_MERGE_DELAY 815 GNUNET_MESSENGER_MERGE_DELAY
764 ); 816 );
@@ -772,6 +824,46 @@ idle_request_room_messages (void *cls)
772} 824}
773 825
774void 826void
827solve_room_member_collisions (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_IDENTITY_PublicKey *public_key,
828 const struct GNUNET_ShortHashCode *member_id, struct GNUNET_TIME_Absolute timestamp)
829{
830 GNUNET_assert ((room) && (public_key) && (member_id));
831
832 struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
833 struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, member_id);
834
835 if ((!member) || (1 >= GNUNET_CONTAINER_multihashmap_size(member->sessions)))
836 return;
837
838 struct GNUNET_MESSENGER_ListHandles *handles = &(room->service->handles);
839 struct GNUNET_MESSENGER_ListHandle* element;
840
841 for (element = handles->head; element; element = element->next)
842 {
843 if (0 != GNUNET_memcmp(member_id, get_handle_member_id(element->handle, get_room_key(room))))
844 continue;
845
846 if (0 == GNUNET_memcmp(public_key, &(get_handle_ego(element->handle)->pub)))
847 continue;
848
849 struct GNUNET_MESSENGER_MemberSession *session = get_member_session(member, &(get_handle_ego(element->handle)->pub));
850
851 if (!session)
852 continue;
853
854 struct GNUNET_TIME_Absolute start = get_member_session_start(session);
855
856 if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(start, timestamp).rel_value_us)
857 continue;
858
859 struct GNUNET_ShortHashCode random_id;
860 generate_free_member_id (&random_id, member_store->members);
861
862 send_room_message(room, element->handle, create_message_id(&random_id));
863 }
864}
865
866void
775rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room) 867rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room)
776{ 868{
777 GNUNET_assert(room); 869 GNUNET_assert(room);
@@ -821,25 +913,27 @@ rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room)
821static void 913static void
822handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room) 914handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room)
823{ 915{
916 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
917 struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
918
824 while (room->handling.head) 919 while (room->handling.head)
825 { 920 {
826 struct GNUNET_MESSENGER_ListMessage *element = room->handling.head; 921 struct GNUNET_MESSENGER_ListMessage *element = room->handling.head;
827 922
828 const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(element->hash), GNUNET_NO); 923 const struct GNUNET_MESSENGER_Message *message = get_store_message (message_store, &(element->hash));
829 924
830 if (!msg) 925 if (!message)
831 goto finish_handling; 926 goto finish_handling;
832 927
833 struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); 928 struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
834 struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, msg);
835 929
836 if (!member) 930 if (!member)
837 goto finish_handling; 931 goto finish_handling;
838 932
839 struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, msg, &(element->hash)); 933 struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, &(element->hash));
840 934
841 if (session) 935 if (session)
842 handle_service_message (room->service, room, session, msg, &(element->hash)); 936 handle_service_message (room->service, room, session, message, &(element->hash));
843 937
844finish_handling: 938finish_handling:
845 GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element); 939 GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element);
@@ -847,17 +941,6 @@ finish_handling:
847 } 941 }
848} 942}
849 943
850static void
851remove_room_last_message (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
852{
853 remove_from_list_messages(&(room->last_messages), hash);
854
855 struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
856
857 if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, hash))
858 cancel_store_operation(operation_store, hash);
859}
860
861int 944int
862update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, 945update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
863 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) 946 struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
@@ -873,11 +956,13 @@ update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
873 if (GNUNET_YES == requested) 956 if (GNUNET_YES == requested)
874 cancel_store_operation(operation_store, hash); 957 cancel_store_operation(operation_store, hash);
875 958
876 const struct GNUNET_MESSENGER_Message *old_message = get_room_message (room, NULL, hash, GNUNET_NO); 959 struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
960
961 const struct GNUNET_MESSENGER_Message *old_message = get_store_message (message_store, hash);
877 962
878 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", GNUNET_h2s (get_room_key(room))); 963 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", GNUNET_h2s (get_room_key(room)));
879 964
880 if ((old_message) || (GNUNET_OK != put_store_message (get_room_message_store(room), hash, message))) 965 if ((old_message) || (GNUNET_OK != put_store_message (message_store, hash, message)))
881 { 966 {
882 if (old_message != message) 967 if (old_message != message)
883 destroy_message(message); 968 destroy_message(message);
@@ -886,16 +971,19 @@ update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
886 return GNUNET_NO; 971 return GNUNET_NO;
887 } 972 }
888 973
974 update_message_state(&(room->state), requested, message, hash);
975
889 if ((GNUNET_YES == requested) || 976 if ((GNUNET_YES == requested) ||
890 (GNUNET_MESSENGER_KIND_INFO == message->header.kind) || 977 (GNUNET_MESSENGER_KIND_INFO == message->header.kind) ||
891 (GNUNET_MESSENGER_KIND_REQUEST == message->header.kind)) 978 (GNUNET_MESSENGER_KIND_REQUEST == message->header.kind))
892 return GNUNET_YES; 979 return GNUNET_YES;
893 980
894 if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind) 981 if ((GNUNET_MESSENGER_KIND_MERGE == message->header.kind) &&
895 remove_room_last_message(room, &(message->body.merge.previous)); 982 (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->body.merge.previous))))
896 remove_room_last_message(room, &(message->header.previous)); 983 cancel_store_operation(operation_store, &(message->body.merge.previous));
897 984
898 add_to_list_messages (&(room->last_messages), hash); 985 if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->header.previous)))
986 cancel_store_operation(operation_store, &(message->header.previous));
899 987
900 return GNUNET_YES; 988 return GNUNET_YES;
901} 989}
@@ -1053,8 +1141,7 @@ load_room (struct GNUNET_MESSENGER_SrvRoom *room)
1053 char *last_messages_file; 1141 char *last_messages_file;
1054 GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list"); 1142 GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list");
1055 1143
1056 load_list_messages(&(room->last_messages), last_messages_file); 1144 load_message_state(&(room->state), room_dir);
1057 GNUNET_free(last_messages_file);
1058 } 1145 }
1059 1146
1060 GNUNET_free(room_dir); 1147 GNUNET_free(room_dir);
@@ -1081,11 +1168,7 @@ save_room (struct GNUNET_MESSENGER_SrvRoom *room)
1081 save_list_tunnels(&(room->basement), basement_file); 1168 save_list_tunnels(&(room->basement), basement_file);
1082 GNUNET_free(basement_file); 1169 GNUNET_free(basement_file);
1083 1170
1084 char *last_messages_file; 1171 save_message_state(&(room->state), room_dir);
1085 GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list");
1086
1087 save_list_messages(&(room->last_messages), last_messages_file);
1088 GNUNET_free(last_messages_file);
1089 } 1172 }
1090 1173
1091 GNUNET_free(room_dir); 1174 GNUNET_free(room_dir);