commit f3336d34b37cf157ed8b4dbcb63994c4a8ba06e5
parent 200b953fce91737a4279ae62668e4562e9c47027
Author: Jacki <jacki@thejackimonster.de>
Date: Sat, 10 Feb 2024 16:49:19 +0100
Handle messages with delay and dependencies in order
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
1 file changed, 137 insertions(+), 110 deletions(-)
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
@@ -37,6 +37,7 @@
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_reclaim_service.h>
#include <gnunet/gnunet_scheduler_lib.h>
+#include <gnunet/gnunet_time_lib.h>
#include <gnunet/gnunet_util_lib.h>
#include <stdio.h>
#include <string.h>
@@ -781,9 +782,100 @@ on_handle_message_callback(void *cls)
if (! message->msg)
return;
+ const struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh(
+ message->msg->header.timestamp
+ );
+
+ struct GNUNET_TIME_Relative task_delay;
+ switch (message->msg->header.kind)
+ {
+ case GNUNET_MESSENGER_KIND_DELETE:
+ {
+ const struct GNUNET_TIME_Relative delay = GNUNET_TIME_relative_ntoh(
+ message->msg->body.deletion.delay
+ );
+
+ task_delay = GNUNET_TIME_absolute_get_difference(
+ GNUNET_TIME_absolute_get(),
+ GNUNET_TIME_absolute_add(timestamp, delay)
+ );
+
+ break;
+ }
+ default:
+ {
+ task_delay = GNUNET_TIME_relative_get_zero_();
+ break;
+ }
+ }
+
+ if (! GNUNET_TIME_relative_is_zero(task_delay))
+ {
+ message->task = GNUNET_SCHEDULER_add_delayed(
+ task_delay,
+ on_handle_message_callback,
+ message
+ );
+
+ return;
+ }
+
struct GNUNET_CHAT_Context *context = message->context;
struct GNUNET_CHAT_Handle *handle = context->handle;
+ switch (message->msg->header.kind)
+ {
+ case GNUNET_MESSENGER_KIND_INVITE:
+ {
+ struct GNUNET_CHAT_Invitation *invitation = invitation_create_from_message(
+ context, &(message->hash), &(message->msg->body.invite)
+ );
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ context->invites, &(message->hash), invitation,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ invitation_destroy(invitation);
+ break;
+ }
+ case GNUNET_MESSENGER_KIND_FILE:
+ {
+ GNUNET_CONTAINER_multihashmap_put(
+ context->files, &(message->hash), NULL,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
+ );
+
+ struct GNUNET_CHAT_File *file = GNUNET_CONTAINER_multihashmap_get(
+ context->handle->files, &(message->msg->body.file.hash)
+ );
+
+ if (file)
+ break;
+
+ file = file_create_from_message(
+ context->handle, &(message->msg->body.file)
+ );
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ context->handle->files, &(file->hash), file,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ file_destroy(file);
+ break;
+ }
+ case GNUNET_MESSENGER_KIND_TAG:
+ {
+ if (message->msg->body.tag.tag)
+ break;
+
+ GNUNET_CONTAINER_multihashmap_put(
+ context->rejections, &(message->msg->body.tag.hash),
+ message, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+
+ break;
+ }
+ default:
+ break;
+ }
+
if (!(handle->msg_cb))
goto clear_dependencies;
@@ -800,7 +892,47 @@ on_handle_message_callback(void *cls)
handle->contacts, &shorthash
);
- if ((!contact) || (GNUNET_YES == contact->blocked))
+ if (!contact)
+ goto clear_dependencies;
+
+ switch (message->msg->header.kind)
+ {
+ case GNUNET_MESSENGER_KIND_KEY:
+ {
+ contact_update_key(contact);
+ break;
+ }
+ case GNUNET_MESSENGER_KIND_TICKET:
+ {
+ struct GNUNET_CHAT_InternalTickets *tickets = GNUNET_new(
+ struct GNUNET_CHAT_InternalTickets
+ );
+
+ if (!tickets)
+ break;
+
+ tickets->ticket = ticket_create_from_message(
+ handle, sender, &(message->msg->body.ticket)
+ );
+
+ if (!tickets->ticket)
+ {
+ GNUNET_free(tickets);
+ break;
+ }
+
+ GNUNET_CONTAINER_DLL_insert_tail(
+ contact->tickets_head,
+ contact->tickets_tail,
+ tickets
+ );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (GNUNET_YES == contact->blocked)
goto clear_dependencies;
handle->msg_cb(handle->msg_cls, context, message);
@@ -879,15 +1011,14 @@ on_handle_message (void *cls,
}
else
{
- struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(
+ const struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(
timestamp, *time
);
- if (GNUNET_TIME_relative_get_zero_().rel_value_us == delta.rel_value_us)
+ if (GNUNET_TIME_relative_is_zero(delta))
*time = timestamp;
}
- struct GNUNET_SCHEDULER_Task *task = NULL;
const struct GNUNET_HashCode *dependency = NULL;
struct GNUNET_CHAT_Message *message = GNUNET_CONTAINER_multihashmap_get(
@@ -920,113 +1051,10 @@ on_handle_message (void *cls,
context->messages, hash, message,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
{
- if (task)
- GNUNET_SCHEDULER_cancel(task);
-
message_destroy(message);
return;
}
- switch (msg->header.kind)
- {
- case GNUNET_MESSENGER_KIND_KEY:
- {
- contact_update_key(contact);
- break;
- }
- case GNUNET_MESSENGER_KIND_INVITE:
- {
- struct GNUNET_CHAT_Invitation *invitation = invitation_create_from_message(
- context, hash, &(msg->body.invite)
- );
-
- if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
- context->invites, hash, invitation,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- invitation_destroy(invitation);
- break;
- }
- case GNUNET_MESSENGER_KIND_FILE:
- {
- GNUNET_CONTAINER_multihashmap_put(
- context->files, hash, NULL,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
- );
-
- struct GNUNET_CHAT_File *file = GNUNET_CONTAINER_multihashmap_get(
- context->handle->files, &(msg->body.file.hash)
- );
-
- if (file)
- break;
-
- file = file_create_from_message(
- context->handle, &(msg->body.file)
- );
-
- if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
- context->handle->files, &(file->hash), file,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- file_destroy(file);
- break;
- }
- case GNUNET_MESSENGER_KIND_DELETE:
- {
- struct GNUNET_TIME_Relative delay = GNUNET_TIME_relative_ntoh(
- msg->body.deletion.delay
- );
-
- task = GNUNET_SCHEDULER_add_delayed(
- GNUNET_TIME_absolute_get_difference(
- GNUNET_TIME_absolute_get(),
- GNUNET_TIME_absolute_add(timestamp, delay)
- ),
- on_handle_message_callback,
- message
- );
- break;
- }
- case GNUNET_MESSENGER_KIND_TICKET:
- {
- struct GNUNET_CHAT_InternalTickets *tickets = GNUNET_new(
- struct GNUNET_CHAT_InternalTickets
- );
-
- if (!tickets)
- break;
-
- tickets->ticket = ticket_create_from_message(
- handle, sender, &(msg->body.ticket)
- );
-
- if (!tickets->ticket)
- {
- GNUNET_free(tickets);
- break;
- }
-
- GNUNET_CONTAINER_DLL_insert_tail(
- contact->tickets_head,
- contact->tickets_tail,
- tickets
- );
- break;
- }
- case GNUNET_MESSENGER_KIND_TAG:
- {
- if (msg->body.tag.tag)
- break;
-
- GNUNET_CONTAINER_multihashmap_put(
- context->rejections, &(msg->body.tag.hash),
- message, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-
- break;
- }
- default:
- break;
- }
-
handle_callback:
switch (msg->header.kind)
{
@@ -1060,11 +1088,10 @@ handle_callback:
);
GNUNET_MESSENGER_get_message(room, dependency);
+ return;
}
- else if (!task)
- on_handle_message_callback(message);
- message->task = task;
+ on_handle_message_callback(message);
}
int