diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_room.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_room.c | 277 |
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 | ||
152 | const struct GNUNET_ShortHashCode* | ||
153 | get_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 | |||
160 | void | ||
161 | change_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 | |||
168 | static int | 152 | static int |
169 | send_room_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, | 153 | send_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 | ||
246 | static int | 230 | static void |
247 | iterate_notify_about_members (void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, | 231 | notify_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 | |||
260 | static int | ||
261 | iterate_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 | ||
584 | static void | ||
585 | merge_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 | |||
593 | void | 592 | void |
594 | merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle) | 593 | merge_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 | |||
602 | merge_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 | ||
608 | void | 612 | void |
609 | callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash) | 613 | callback_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 | ||
632 | int | 631 | int |
@@ -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 | ||
694 | const struct GNUNET_MESSENGER_Message* | 695 | static int |
695 | get_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, | 696 | request_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; | 717 | forward: |
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 | |||
732 | int | ||
733 | request_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 | ||
713 | void | 747 | void |
@@ -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 | |||
792 | skip_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 | ||
774 | void | 826 | void |
827 | solve_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 | |||
866 | void | ||
775 | rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room) | 867 | rebuild_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) | |||
821 | static void | 913 | static void |
822 | handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room) | 914 | handle_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 | ||
844 | finish_handling: | 938 | finish_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 | ||
850 | static void | ||
851 | remove_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 | |||
861 | int | 944 | int |
862 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | 945 | update_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); |