gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: MESSENGER: Fix message order via client-


From: gnunet
Subject: [gnunet] branch master updated: MESSENGER: Fix message order via client-side message control
Date: Mon, 04 Mar 2024 17:59:31 +0100

This is an automated email from the git hooks/post-receive script.

thejackimonster pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 28c33aabe MESSENGER: Fix message order via client-side message control
28c33aabe is described below

commit 28c33aabecf1a00eff1c82583efe26e57fe59a64
Author: TheJackiMonster <thejackimonster@gmail.com>
AuthorDate: Mon Mar 4 17:57:12 2024 +0100

    MESSENGER: Fix message order via client-side message control
    
    Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
---
 src/service/messenger/Makefile.am                  |   1 +
 src/service/messenger/meson.build                  |   1 +
 src/service/messenger/messenger_api.c              |  19 +-
 .../messenger/messenger_api_message_control.c      | 248 +++++++++++++++++++++
 .../messenger/messenger_api_message_control.h      | 105 +++++++++
 src/service/messenger/messenger_api_message_kind.c |   4 +-
 src/service/messenger/messenger_api_message_kind.h |  10 +-
 src/service/messenger/messenger_api_room.c         |  14 ++
 src/service/messenger/messenger_api_room.h         |  13 ++
 9 files changed, 396 insertions(+), 19 deletions(-)

diff --git a/src/service/messenger/Makefile.am 
b/src/service/messenger/Makefile.am
index b1ecc13c8..93dcf9a78 100644
--- a/src/service/messenger/Makefile.am
+++ b/src/service/messenger/Makefile.am
@@ -37,6 +37,7 @@ libgnunetmessenger_la_SOURCES = \
   messenger_api_contact.c messenger_api_contact.h \
   messenger_api_contact_store.c messenger_api_contact_store.h \
   messenger_api_message.c messenger_api_message.h \
+  messenger_api_message_control.c messenger_api_message_control.h \
   messenger_api_message_kind.c messenger_api_message_kind.h \
   messenger_api_list_tunnels.c messenger_api_list_tunnels.h \
   messenger_api_queue_messages.c messenger_api_queue_messages.h \
diff --git a/src/service/messenger/meson.build 
b/src/service/messenger/meson.build
index 1e37e192f..4a472b6b5 100644
--- a/src/service/messenger/meson.build
+++ b/src/service/messenger/meson.build
@@ -2,6 +2,7 @@ libgnunetmessenger_src = ['messenger_api.c',
                           'messenger_api_contact.c',
                           'messenger_api_contact_store.c',
                           'messenger_api_message.c',
+                          'messenger_api_message_control.c',
                           'messenger_api_message_kind.c',
                           'messenger_api_list_tunnels.c',
                           'messenger_api_queue_messages.c',
diff --git a/src/service/messenger/messenger_api.c 
b/src/service/messenger/messenger_api.c
index 8afb9e42e..1d782ac13 100644
--- a/src/service/messenger/messenger_api.c
+++ b/src/service/messenger/messenger_api.c
@@ -34,6 +34,7 @@
 #include "messenger_api_contact_store.h"
 #include "messenger_api_handle.h"
 #include "messenger_api_message.h"
+#include "messenger_api_message_control.h"
 #include "messenger_api_message_kind.h"
 #include "messenger_api_room.h"
 #include "messenger_api_util.h"
@@ -295,22 +296,16 @@ handle_recv_message (void *cls,
     goto skip_message;
   }
 
-  struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store (
-    handle);
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Raw contact from sender and context: (%s : %s)\n",
               GNUNET_h2s (sender), GNUNET_h2s_full (context));
 
-  struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw (
-    store, context, sender);
-
-  handle_room_message (room, contact, &message, hash, flags);
-
-  if (flags & GNUNET_MESSENGER_FLAG_RECENT)
-    update_room_last_message (room, hash);
-
-  callback_room_message (room, hash);
+  process_message_control (room->control,
+                           sender,
+                           context,
+                           hash,
+                           &message,
+                           flags);
 
 skip_message:
   cleanup_message (&message);
diff --git a/src/service/messenger/messenger_api_message_control.c 
b/src/service/messenger/messenger_api_message_control.c
new file mode 100644
index 000000000..30c52587f
--- /dev/null
+++ b/src/service/messenger/messenger_api_message_control.c
@@ -0,0 +1,248 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2024 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @author Tobias Frisch
+ * @file src/messenger/messenger_api_message_control.c
+ * @brief messenger api: client and service implementation of GNUnet MESSENGER 
service
+ */
+
+#include "messenger_api_message_control.h"
+
+#include "gnunet_common.h"
+#include "gnunet_messenger_service.h"
+#include "gnunet_scheduler_lib.h"
+#include "messenger_api_contact.h"
+#include "messenger_api_contact_store.h"
+#include "messenger_api_handle.h"
+#include "messenger_api_message.h"
+#include "messenger_api_room.h"
+
+struct GNUNET_MESSENGER_MessageControl*
+create_message_control (struct GNUNET_MESSENGER_Room *room)
+{
+  GNUNET_assert (room);
+
+  struct GNUNET_MESSENGER_MessageControl *control;
+
+  control = GNUNET_new (struct GNUNET_MESSENGER_MessageControl);
+  control->room = room;
+
+  control->peer_messages = GNUNET_CONTAINER_multishortmap_create (8, 
GNUNET_NO);
+  control->member_messages = GNUNET_CONTAINER_multishortmap_create (8,
+                                                                    GNUNET_NO);
+
+  control->head = NULL;
+  control->tail = NULL;
+
+  return control;
+}
+
+
+void
+destroy_message_control (struct GNUNET_MESSENGER_MessageControl *control)
+{
+  GNUNET_assert (control);
+
+  struct GNUNET_MESSENGER_MessageControlQueue *queue;
+  while (control->head)
+  {
+    queue = control->head;
+
+    if (queue->task)
+      GNUNET_SCHEDULER_cancel (queue->task);
+
+    destroy_message (queue->message);
+
+    GNUNET_CONTAINER_DLL_remove (control->head, control->tail, queue);
+    GNUNET_free (queue);
+  }
+
+  GNUNET_CONTAINER_multishortmap_destroy (control->peer_messages);
+  GNUNET_CONTAINER_multishortmap_destroy (control->member_messages);
+
+  GNUNET_free (control);
+}
+
+
+static void
+enqueue_message_control (struct GNUNET_MESSENGER_MessageControl *control,
+                         const struct GNUNET_HashCode *sender,
+                         const struct GNUNET_HashCode *context,
+                         const struct GNUNET_HashCode *hash,
+                         const struct GNUNET_MESSENGER_Message *message,
+                         enum GNUNET_MESSENGER_MessageFlags flags)
+{
+  GNUNET_assert ((control) && (sender) && (context) && (hash) && (message));
+
+  struct GNUNET_CONTAINER_MultiShortmap *map;
+  if (GNUNET_YES == is_peer_message (message))
+    map = control->peer_messages;
+  else
+    map = control->member_messages;
+
+  struct GNUNET_MESSENGER_MessageControlQueue *queue;
+
+  queue = GNUNET_new (struct GNUNET_MESSENGER_MessageControlQueue);
+  queue->control = control;
+
+  GNUNET_memcpy (&(queue->sender), sender, sizeof (queue->sender));
+  GNUNET_memcpy (&(queue->context), context, sizeof (queue->context));
+  GNUNET_memcpy (&(queue->hash), hash, sizeof (queue->hash));
+
+  queue->message = copy_message (message);
+  queue->flags = flags;
+  queue->task = NULL;
+
+  GNUNET_CONTAINER_DLL_insert (control->head, control->tail, queue);
+
+  GNUNET_CONTAINER_multishortmap_put (map,
+                                      &(message->header.sender_id),
+                                      queue,
+                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+}
+
+
+static void
+handle_message_control (struct GNUNET_MESSENGER_MessageControl *control,
+                        struct GNUNET_MESSENGER_Contact *contact,
+                        const struct GNUNET_HashCode *hash,
+                        const struct GNUNET_MESSENGER_Message *message,
+                        enum GNUNET_MESSENGER_MessageFlags flags)
+{
+  GNUNET_assert ((control) && (hash) && (message));
+
+  handle_room_message (control->room, contact, message, hash, flags);
+
+  if (flags & GNUNET_MESSENGER_FLAG_RECENT)
+    update_room_last_message (control->room, hash);
+
+  callback_room_message (control->room, hash);
+}
+
+
+static void
+task_message_control (void *cls)
+{
+  GNUNET_assert (cls);
+
+  struct GNUNET_MESSENGER_MessageControlQueue *queue = cls;
+  struct GNUNET_MESSENGER_MessageControl *control = queue->control;
+
+  queue->task = NULL;
+
+  struct GNUNET_MESSENGER_Handle *handle = get_room_handle (control->room);
+  struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store (
+    handle);
+
+  struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw (
+    store, &(queue->context), &(queue->sender));
+
+  struct GNUNET_CONTAINER_MultiShortmap *map;
+  if (GNUNET_YES == is_peer_message (queue->message))
+    map = control->peer_messages;
+  else
+    map = control->member_messages;
+
+  GNUNET_CONTAINER_multishortmap_remove (map,
+                                         &(queue->message->header.sender_id),
+                                         queue);
+
+  GNUNET_CONTAINER_DLL_remove (control->head, control->tail, queue);
+
+  handle_message_control (control,
+                          contact,
+                          &(queue->hash),
+                          queue->message,
+                          queue->flags);
+
+  destroy_message (queue->message);
+
+  GNUNET_free (queue);
+}
+
+
+static enum GNUNET_GenericReturnValue
+iterate_message_control (void *cls,
+                         const struct GNUNET_ShortHashCode *key,
+                         void *value)
+{
+  GNUNET_assert ((cls) && (key) && (value));
+
+  struct GNUNET_MESSENGER_MessageControlQueue *queue = value;
+
+  if (queue->task)
+    return GNUNET_YES;
+
+  queue->task = GNUNET_SCHEDULER_add_now (task_message_control, queue);
+  return GNUNET_YES;
+}
+
+
+void
+process_message_control (struct GNUNET_MESSENGER_MessageControl *control,
+                         const struct GNUNET_HashCode *sender,
+                         const struct GNUNET_HashCode *context,
+                         const struct GNUNET_HashCode *hash,
+                         const struct GNUNET_MESSENGER_Message *message,
+                         enum GNUNET_MESSENGER_MessageFlags flags)
+{
+  GNUNET_assert ((control) && (sender) && (context) && (hash) && (message));
+
+  struct GNUNET_MESSENGER_Handle *handle = get_room_handle (control->room);
+  struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store (
+    handle);
+
+  struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw (
+    store, context, sender);
+
+  if ((! contact) &&
+      (GNUNET_MESSENGER_KIND_JOIN != message->header.kind) &&
+      (GNUNET_MESSENGER_KIND_PEER != message->header.kind))
+    enqueue_message_control (control, sender, context, hash, message, flags);
+  else
+    handle_message_control (control, contact, hash, message, flags);
+
+  struct GNUNET_CONTAINER_MultiShortmap *map = NULL;
+  const struct GNUNET_ShortHashCode *id = &(message->header.sender_id);
+
+  switch (message->header.kind)
+  {
+  case GNUNET_MESSENGER_KIND_JOIN:
+    map = control->member_messages;
+    break;
+  case GNUNET_MESSENGER_KIND_PEER:
+    map = control->peer_messages;
+    break;
+  case GNUNET_MESSENGER_KIND_ID:
+    map = control->member_messages;
+    id = &(message->body.id.id);
+    break;
+  default:
+    break;
+  }
+
+  if (! map)
+    return;
+
+  GNUNET_CONTAINER_multishortmap_get_multiple (map,
+                                               id,
+                                               iterate_message_control,
+                                               NULL);
+}
diff --git a/src/service/messenger/messenger_api_message_control.h 
b/src/service/messenger/messenger_api_message_control.h
new file mode 100644
index 000000000..a990210f0
--- /dev/null
+++ b/src/service/messenger/messenger_api_message_control.h
@@ -0,0 +1,105 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2024 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @author Tobias Frisch
+ * @file src/messenger/messenger_api_message_control.h
+ * @brief messenger api: client and service implementation of GNUnet MESSENGER 
service
+ */
+
+#ifndef GNUNET_MESSENGER_API_MESSAGE_CONTROL_H
+#define GNUNET_MESSENGER_API_MESSAGE_CONTROL_H
+
+#include "gnunet_common.h"
+#include "gnunet_messenger_service.h"
+#include "gnunet_util_lib.h"
+
+struct GNUNET_MESSENGER_Message;
+struct GNUNET_MESSENGER_MessageControl;
+
+struct GNUNET_MESSENGER_MessageControlQueue
+{
+  struct GNUNET_MESSENGER_MessageControl *control;
+
+  struct GNUNET_HashCode sender;
+  struct GNUNET_HashCode context;
+  struct GNUNET_HashCode hash;
+
+  struct GNUNET_MESSENGER_Message *message;
+  enum GNUNET_MESSENGER_MessageFlags flags;
+  struct GNUNET_SCHEDULER_Task *task;
+
+  struct GNUNET_MESSENGER_MessageControlQueue *prev;
+  struct GNUNET_MESSENGER_MessageControlQueue *next;
+};
+
+struct GNUNET_MESSENGER_Room;
+
+struct GNUNET_MESSENGER_MessageControl
+{
+  struct GNUNET_MESSENGER_Room *room;
+
+  struct GNUNET_CONTAINER_MultiShortmap *peer_messages;
+  struct GNUNET_CONTAINER_MultiShortmap *member_messages;
+
+  struct GNUNET_MESSENGER_MessageControlQueue *head;
+  struct GNUNET_MESSENGER_MessageControlQueue *tail;
+};
+
+/**
+ * Creates and allocates a new message control for a <i>room</i> of the client 
API.
+ *
+ * @param[in,out] room Room
+ * @return New message control
+ */
+struct GNUNET_MESSENGER_MessageControl*
+create_message_control (struct GNUNET_MESSENGER_Room *room);
+
+/**
+ * Destroys a message control and frees its memory fully from the client API.
+ *
+ * @param[in,out] control Message control
+ */
+void
+destroy_message_control (struct GNUNET_MESSENGER_MessageControl *control);
+
+/**
+ * Processes a new <i>message</i> with its <i>hash</i> and regarding 
information about
+ * <i>sender</i>, <i>context</i> and message <i>flags</i> using a selected 
message
+ * <i>control</i>.
+ *
+ * The message control will ensure order of messages so that senders of 
messages
+ * can be identified via previously processed messages.
+ *
+ * @param[in,out] control Message control
+ * @param[in] sender Sender hash
+ * @param[in] context Context hash
+ * @param[in] hash Message hash
+ * @param[in] message Message
+ * @param[in] flags Message flags
+ */
+void
+process_message_control (struct GNUNET_MESSENGER_MessageControl *control,
+                         const struct GNUNET_HashCode *sender,
+                         const struct GNUNET_HashCode *context,
+                         const struct GNUNET_HashCode *hash,
+                         const struct GNUNET_MESSENGER_Message *message,
+                         enum GNUNET_MESSENGER_MessageFlags flags);
+
+#endif //GNUNET_MESSENGER_API_MESSAGE_CONTROL_H
\ No newline at end of file
diff --git a/src/service/messenger/messenger_api_message_kind.c 
b/src/service/messenger/messenger_api_message_kind.c
index 537d54708..33338af9d 100644
--- a/src/service/messenger/messenger_api_message_kind.c
+++ b/src/service/messenger/messenger_api_message_kind.c
@@ -19,8 +19,8 @@
  */
 /**
  * @author Tobias Frisch
- * @file src/messenger/gnunet-service-messenger_message_kind.c
- * @brief GNUnet MESSENGER service
+ * @file src/messenger/messenger_api_message_kind.c
+ * @brief messenger api: client and service implementation of GNUnet MESSENGER 
service
  */
 
 #include "messenger_api_message_kind.h"
diff --git a/src/service/messenger/messenger_api_message_kind.h 
b/src/service/messenger/messenger_api_message_kind.h
index 97952d11f..a5bb12947 100644
--- a/src/service/messenger/messenger_api_message_kind.h
+++ b/src/service/messenger/messenger_api_message_kind.h
@@ -19,12 +19,12 @@
  */
 /**
  * @author Tobias Frisch
- * @file src/messenger/gnunet-service-messenger_message_kind.h
- * @brief GNUnet MESSENGER service
+ * @file src/messenger/messenger_api_message_kind.h
+ * @brief messenger api: client and service implementation of GNUnet MESSENGER 
service
  */
 
-#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
-#define GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
+#ifndef GNUNET_MESSENGER_API_MESSAGE_KIND_H
+#define GNUNET_MESSENGER_API_MESSAGE_KIND_H
 
 #include "gnunet_messenger_service.h"
 #include "gnunet_reclaim_lib.h"
@@ -136,4 +136,4 @@ create_message_delete (const struct GNUNET_HashCode *hash,
 struct GNUNET_MESSENGER_Message*
 create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier);
 
-#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
+#endif //GNUNET_MESSENGER_API_MESSAGE_KIND_H
diff --git a/src/service/messenger/messenger_api_room.c 
b/src/service/messenger/messenger_api_room.c
index 715934f1c..e1970b668 100644
--- a/src/service/messenger/messenger_api_room.c
+++ b/src/service/messenger/messenger_api_room.c
@@ -30,6 +30,7 @@
 #include "messenger_api_contact_store.h"
 #include "messenger_api_handle.h"
 #include "messenger_api_message.h"
+#include "messenger_api_message_control.h"
 #include <string.h>
 
 struct GNUNET_MESSENGER_Room*
@@ -60,6 +61,8 @@ create_room (struct GNUNET_MESSENGER_Handle *handle,
 
   init_queue_messages (&(room->queue));
 
+  room->control = create_message_control (room);
+
   return room;
 }
 
@@ -94,6 +97,8 @@ destroy_room (struct GNUNET_MESSENGER_Room *room)
 {
   GNUNET_assert (room);
 
+  destroy_message_control (room->control);
+
   clear_queue_messages (&(room->queue));
   clear_list_tunnels (&(room->entries));
 
@@ -138,6 +143,15 @@ is_room_available (const struct GNUNET_MESSENGER_Room 
*room)
 }
 
 
+struct GNUNET_MESSENGER_Handle*
+get_room_handle (struct GNUNET_MESSENGER_Room *room)
+{
+  GNUNET_assert (room);
+
+  return room->handle;
+}
+
+
 const struct GNUNET_ShortHashCode*
 get_room_sender_id (const struct GNUNET_MESSENGER_Room *room)
 {
diff --git a/src/service/messenger/messenger_api_room.h 
b/src/service/messenger/messenger_api_room.h
index 4a7f6d6a2..f8460f4e1 100644
--- a/src/service/messenger/messenger_api_room.h
+++ b/src/service/messenger/messenger_api_room.h
@@ -32,8 +32,10 @@
 
 #include "gnunet_messenger_service.h"
 
+#include "messenger_api_handle.h"
 #include "messenger_api_list_tunnels.h"
 #include "messenger_api_contact.h"
+#include "messenger_api_message_control.h"
 #include "messenger_api_queue_messages.h"
 
 struct GNUNET_MESSENGER_RoomMessageEntry
@@ -66,6 +68,8 @@ struct GNUNET_MESSENGER_Room
   struct GNUNET_CONTAINER_MultiHashMap *links;
 
   struct GNUNET_MESSENGER_QueueMessages queue;
+
+  struct GNUNET_MESSENGER_MessageControl *control;
 };
 
 typedef void (*GNUNET_MESSENGER_RoomLinkDeletion) (struct
@@ -103,6 +107,15 @@ destroy_room (struct GNUNET_MESSENGER_Room *room);
 enum GNUNET_GenericReturnValue
 is_room_available (const struct GNUNET_MESSENGER_Room *room);
 
+/**
+ * Returns the messenger handle of the <i>room</i>.
+ *
+ * @param[in,out] room Room
+ * @return Messenger handle or NULL
+ */
+struct GNUNET_MESSENGER_Handle*
+get_room_handle (struct GNUNET_MESSENGER_Room *room);
+
 /**
  * Returns the member id of the <i>room</i>'s sender.
  *

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]