summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-04-06 02:30:45 +0200
committerTheJackiMonster <thejackimonster@gmail.com>2022-04-06 02:30:45 +0200
commit4423dd264ef99fe9617e5d871857d15e88639f51 (patch)
treeb242b1ad2fb5d433000dd6d5c1f1d6d5b9c665dd
parentde5dccb421f01bb09764ae1da40cb226c30b8d45 (diff)
Added some safety for stopping chat handle
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--include/gnunet_chat_lib.h5
-rw-r--r--src/gnunet_chat_handle.c114
-rw-r--r--src/gnunet_chat_handle.h24
-rw-r--r--src/gnunet_chat_handle_intern.c76
-rw-r--r--src/gnunet_chat_lib.c74
-rw-r--r--src/gnunet_chat_lib_intern.c60
-rw-r--r--src/gnunet_chat_lobby.c17
-rw-r--r--src/gnunet_chat_lobby.h4
-rw-r--r--src/gnunet_chat_lobby_intern.c30
-rw-r--r--src/gnunet_chat_message.c5
-rw-r--r--src/gnunet_chat_message.h1
-rw-r--r--tests/test_gnunet_chat_lobby.c8
12 files changed, 257 insertions, 161 deletions
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
index 6d3a581..2590dd2 100644
--- a/include/gnunet_chat_lib.h
+++ b/include/gnunet_chat_lib.h
@@ -365,12 +365,9 @@ GNUNET_CHAT_account_create (struct GNUNET_CHAT_Handle *handle,
* Deletes an existing chat account of a given chat <i>handle</i> under a
* unique <i>name</i>.
*
- * If there is no account known to this chat handle under the provided name, the
- * function will fail and return #GNUNET_NO.
- *
* @param[in,out] handle Chat handle
* @param[in] name Account name
- * @return #GNUNET_OK on success, #GNUNET_NO on failure and otherwise #GNUNET_SYSERR
+ * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
*/
int
GNUNET_CHAT_account_delete(struct GNUNET_CHAT_Handle *handle,
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
index c5d70a8..05c0054 100644
--- a/src/gnunet_chat_handle.c
+++ b/src/gnunet_chat_handle.c
@@ -377,6 +377,115 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle)
handle_update_key(handle);
}
+int
+handle_create_account (struct GNUNET_CHAT_Handle *handle,
+ const char *name)
+{
+ GNUNET_assert((handle) && (name));
+
+ struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
+ while (accounts)
+ {
+ if (!(accounts->account))
+ goto skip_account;
+
+ if ((accounts->account->name) &&
+ (0 == strcmp(accounts->account->name, name)))
+ return GNUNET_NO;
+
+ skip_account:
+ accounts = accounts->next;
+ }
+
+ accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts);
+ accounts->account = NULL;
+ accounts->handle = handle;
+
+ accounts->op = GNUNET_IDENTITY_create(
+ handle->identity,
+ name,
+ NULL,
+ GNUNET_IDENTITY_TYPE_ECDSA,
+ cb_account_creation,
+ accounts
+ );
+
+ if (!(accounts->op))
+ {
+ GNUNET_free(accounts);
+ return GNUNET_SYSERR;
+ }
+
+ GNUNET_CONTAINER_DLL_insert_tail(
+ handle->accounts_head,
+ handle->accounts_tail,
+ accounts
+ );
+
+ return GNUNET_OK;
+}
+
+int
+handle_delete_account (struct GNUNET_CHAT_Handle *handle,
+ const char *name)
+{
+ GNUNET_assert((handle) && (name));
+
+ struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
+ while (accounts)
+ {
+ if (!(accounts->account))
+ goto skip_account;
+
+ if ((accounts->account->name) &&
+ (0 == strcmp(accounts->account->name, name)))
+ break;
+
+ skip_account:
+ accounts = accounts->next;
+ }
+
+ if (!accounts)
+ {
+ accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts);
+ accounts->account = NULL;
+ accounts->handle = handle;
+
+ accounts->op = GNUNET_IDENTITY_delete(
+ handle->identity,
+ name,
+ cb_account_deletion,
+ accounts
+ );
+
+ if (!(accounts->op))
+ {
+ GNUNET_free(accounts);
+ return GNUNET_SYSERR;
+ }
+
+ GNUNET_CONTAINER_DLL_insert_tail(
+ handle->accounts_head,
+ handle->accounts_tail,
+ accounts
+ );
+
+ return GNUNET_OK;
+ }
+
+ if (accounts->op)
+ GNUNET_IDENTITY_cancel(accounts->op);
+
+ accounts->op = GNUNET_IDENTITY_delete(
+ handle->identity,
+ name,
+ cb_account_deletion,
+ accounts
+ );
+
+ return (accounts->op? GNUNET_OK : GNUNET_SYSERR);
+}
+
const char*
handle_get_directory (const struct GNUNET_CHAT_Handle *handle)
{
@@ -412,7 +521,7 @@ handle_send_internal_message (struct GNUNET_CHAT_Handle *handle,
{
GNUNET_assert((handle) && (GNUNET_CHAT_FLAG_NONE != flag));
- if (!(handle->msg_cb))
+ if ((handle->destruction) || (!(handle->msg_cb)))
return;
struct GNUNET_CHAT_InternalMessages *internal = GNUNET_new(
@@ -444,6 +553,9 @@ handle_send_room_name (struct GNUNET_CHAT_Handle *handle,
{
GNUNET_assert((handle) && (handle->messenger) && (room));
+ if (handle->destruction)
+ return;
+
const char *name = GNUNET_MESSENGER_get_name(handle->messenger);
if (!name)
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
index 3028186..37a6faf 100644
--- a/src/gnunet_chat_handle.h
+++ b/src/gnunet_chat_handle.h
@@ -177,6 +177,30 @@ void
handle_disconnect (struct GNUNET_CHAT_Handle *handle);
/**
+ * Enqueues a creation for a chat account with a specific
+ * <i>name</i> as identifier for a given chat <i>handle</i>.
+ *
+ * @param[in,out] handle Chat handle
+ * @param[in] name Chat account name
+ * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
+ */
+int
+handle_create_account (struct GNUNET_CHAT_Handle *handle,
+ const char *name);
+
+/**
+ * Enqueues a deletion for a chat account with a specific
+ * <i>name</i> as identifier for a given chat <i>handle</i>.
+ *
+ * @param[in,out] handle Chat handle
+ * @param[in] name Chat account name
+ * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
+ */
+int
+handle_delete_account (struct GNUNET_CHAT_Handle *handle,
+ const char *name);
+
+/**
* Returns the main directory path to store information
* of a given chat <i>handle</i>.
*
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
index e278eaf..08b7cfd 100644
--- a/src/gnunet_chat_handle_intern.c
+++ b/src/gnunet_chat_handle_intern.c
@@ -259,6 +259,12 @@ on_handle_gnunet_identity(void *cls,
account_destroy(accounts->account);
+ if (accounts->op)
+ {
+ accounts->account = NULL;
+ goto send_refresh;
+ }
+
GNUNET_CONTAINER_DLL_remove(
handle->accounts_head,
handle->accounts_tail,
@@ -271,7 +277,7 @@ on_handle_gnunet_identity(void *cls,
goto send_refresh;
check_matching_name:
- if ((accounts->account->name) && (name) &&
+ if ((name) && (accounts->account->name) &&
(0 == strcmp(accounts->account->name, name)))
{
accounts->account->ego = ego;
@@ -304,6 +310,60 @@ send_refresh:
handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL);
}
+void
+cb_account_creation (void *cls,
+ const struct GNUNET_IDENTITY_PrivateKey *key,
+ const char *emsg)
+{
+ GNUNET_assert(cls);
+
+ struct GNUNET_CHAT_InternalAccounts *accounts = (
+ (struct GNUNET_CHAT_InternalAccounts*) cls
+ );
+
+ struct GNUNET_CHAT_Handle *handle = accounts->handle;
+
+ GNUNET_CONTAINER_DLL_remove(
+ handle->accounts_head,
+ handle->accounts_tail,
+ accounts
+ );
+
+ GNUNET_free(accounts);
+
+ if (emsg)
+ handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg);
+ else if (key)
+ handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL);
+}
+
+void
+cb_account_deletion (void *cls,
+ const char *emsg)
+{
+ GNUNET_assert(cls);
+
+ struct GNUNET_CHAT_InternalAccounts *accounts = (
+ (struct GNUNET_CHAT_InternalAccounts*) cls
+ );
+
+ struct GNUNET_CHAT_Handle *handle = accounts->handle;
+
+ GNUNET_CONTAINER_DLL_remove(
+ handle->accounts_head,
+ handle->accounts_tail,
+ accounts
+ );
+
+ GNUNET_free(accounts);
+
+ if (emsg)
+ {
+ handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg);
+ return;
+ }
+}
+
int
intern_provide_contact_for_member(struct GNUNET_CHAT_Handle *handle,
const struct GNUNET_MESSENGER_Contact *member,
@@ -410,6 +470,13 @@ on_monitor_namestore_record(void *cls,
{
struct GNUNET_CHAT_Handle *chat = cls;
+ if (chat->destruction)
+ {
+ GNUNET_NAMESTORE_zone_monitor_stop(chat->monitor);
+ chat->monitor = NULL;
+ return;
+ }
+
handle_process_records(chat, label, count, data);
if (chat->monitor)
@@ -471,6 +538,8 @@ on_handle_message_callback(void *cls)
(message->context) &&
(message->context->handle));
+ message->task = NULL;
+
struct GNUNET_CHAT_Context *context = message->context;
switch (message->msg->header.kind)
@@ -512,7 +581,8 @@ on_handle_message (void *cls,
(msg) &&
(hash));
- if ((GNUNET_OK != handle_request_context_by_room(handle, room)) ||
+ if ((handle->destruction) ||
+ (GNUNET_OK != handle_request_context_by_room(handle, room)) ||
(GNUNET_OK != intern_provide_contact_for_member(handle, sender, NULL)))
return;
@@ -647,6 +717,8 @@ on_handle_message (void *cls,
if (!task)
on_handle_message_callback(message);
+ else
+ message->task = task;
}
int
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
index c52ddf4..8c7558d 100644
--- a/src/gnunet_chat_lib.c
+++ b/src/gnunet_chat_lib.c
@@ -88,46 +88,7 @@ GNUNET_CHAT_account_create (struct GNUNET_CHAT_Handle *handle,
if ((!handle) || (handle->destruction) || (!name))
return GNUNET_SYSERR;
- struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
- while (accounts)
- {
- if (!(accounts->account))
- goto skip_account;
-
- if ((accounts->account->name) &&
- (0 == strcmp(accounts->account->name, name)))
- return GNUNET_NO;
-
- skip_account:
- accounts = accounts->next;
- }
-
- accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts);
- accounts->account = NULL;
- accounts->handle = handle;
-
- accounts->op = GNUNET_IDENTITY_create(
- handle->identity,
- name,
- NULL,
- GNUNET_IDENTITY_TYPE_ECDSA,
- cb_account_creation,
- accounts
- );
-
- if (!(accounts->op))
- {
- GNUNET_free(accounts);
- return GNUNET_SYSERR;
- }
-
- GNUNET_CONTAINER_DLL_insert_tail(
- handle->accounts_head,
- handle->accounts_tail,
- accounts
- );
-
- return GNUNET_OK;
+ return handle_create_account(handle, name);
}
@@ -140,34 +101,7 @@ GNUNET_CHAT_account_delete(struct GNUNET_CHAT_Handle *handle,
if ((!handle) || (handle->destruction) || (!name))
return GNUNET_SYSERR;
- struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
- while (accounts)
- {
- if (!(accounts->account))
- goto skip_account;
-
- if ((accounts->account->name) &&
- (0 == strcmp(accounts->account->name, name)))
- break;
-
- skip_account:
- accounts = accounts->next;
- }
-
- if (!accounts)
- return GNUNET_NO;
-
- if (accounts->op)
- GNUNET_IDENTITY_cancel(accounts->op);
-
- accounts->op = GNUNET_IDENTITY_delete(
- handle->identity,
- name,
- cb_account_deletion,
- handle
- );
-
- return (accounts->op? GNUNET_OK : GNUNET_SYSERR);
+ return handle_delete_account(handle, name);
}
@@ -186,7 +120,7 @@ GNUNET_CHAT_iterate_accounts (const struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
while (accounts)
{
- if (!(accounts->account))
+ if ((!(accounts->account)) || (accounts->op))
goto skip_account;
result++;
@@ -361,7 +295,7 @@ GNUNET_CHAT_uri_to_string (const struct GNUNET_CHAT_Uri *uri)
char *key_string = GNUNET_IDENTITY_public_key_to_string(&(uri->zone));
char *string;
- GNUNET_asprintf(
+ GNUNET_asprintf (
&string,
"gnunet://chat/%s.%s",
key_string,
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c
index c4f570b..b9806a9 100644
--- a/src/gnunet_chat_lib_intern.c
+++ b/src/gnunet_chat_lib_intern.c
@@ -31,50 +31,32 @@ task_handle_destruction (void *cls)
struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls;
- handle->destruction = NULL;
- handle_destroy(handle);
-}
-
-void
-cb_account_creation (void *cls,
- const struct GNUNET_IDENTITY_PrivateKey *key,
- const char *emsg)
-{
- GNUNET_assert(cls);
-
- struct GNUNET_CHAT_InternalAccounts *accounts = (
- (struct GNUNET_CHAT_InternalAccounts*) cls
- );
-
- struct GNUNET_CHAT_Handle *handle = accounts->handle;
-
- GNUNET_CONTAINER_DLL_remove(
- handle->accounts_head,
- handle->accounts_tail,
- accounts
- );
-
- GNUNET_free(accounts);
-
- if (emsg)
- handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg);
- else if (key)
- handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL);
-}
-
-void
-cb_account_deletion (void *cls,
- const char *emsg)
-{
- GNUNET_assert(cls);
+ struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
+ while (accounts)
+ {
+ if ((accounts->op) && (accounts->account))
+ break;
- struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls;
+ accounts = accounts->next;
+ }
- if (emsg)
+ if (accounts)
{
- handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg);
+ handle->destruction = GNUNET_SCHEDULER_add_at_with_priority(
+ GNUNET_TIME_absolute_add(
+ GNUNET_TIME_absolute_get(),
+ GNUNET_TIME_relative_get_second_()
+ ),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ task_handle_destruction,
+ handle
+ );
+
return;
}
+
+ handle->destruction = NULL;
+ handle_destroy(handle);
}
void
diff --git a/src/gnunet_chat_lobby.c b/src/gnunet_chat_lobby.c
index dcc33bb..c6d0327 100644
--- a/src/gnunet_chat_lobby.c
+++ b/src/gnunet_chat_lobby.c
@@ -38,9 +38,7 @@ lobby_create (struct GNUNET_CHAT_Handle *handle)
lobby->context = NULL;
lobby->uri = NULL;
- lobby->op_create = NULL;
- lobby->op_delete = NULL;
-
+ lobby->op = NULL;
lobby->query = NULL;
lobby->expiration = GNUNET_TIME_absolute_get_forever_();
@@ -55,11 +53,8 @@ lobby_destroy (struct GNUNET_CHAT_Lobby *lobby)
{
GNUNET_assert(lobby);
- if (lobby->op_create)
- GNUNET_IDENTITY_cancel(lobby->op_create);
-
- if (lobby->op_delete)
- GNUNET_IDENTITY_cancel(lobby->op_delete);
+ if (lobby->op)
+ GNUNET_IDENTITY_cancel(lobby->op);
if (lobby->query)
GNUNET_NAMESTORE_cancel(lobby->query);
@@ -84,9 +79,9 @@ lobby_open (struct GNUNET_CHAT_Lobby *lobby,
lobby->callback = callback;
lobby->cls = cls;
- if (lobby->op_create)
+ if (lobby->op)
{
- GNUNET_IDENTITY_cancel(lobby->op_create);
+ GNUNET_IDENTITY_cancel(lobby->op);
goto open_zone;
}
@@ -119,7 +114,7 @@ lobby_open (struct GNUNET_CHAT_Lobby *lobby,
open_zone:
util_lobby_name(&key, &name);
- lobby->op_create = GNUNET_IDENTITY_create(
+ lobby->op = GNUNET_IDENTITY_create(
lobby->handle->identity,
name,
NULL,
diff --git a/src/gnunet_chat_lobby.h b/src/gnunet_chat_lobby.h
index c77fbae..3a55b42 100644
--- a/src/gnunet_chat_lobby.h
+++ b/src/gnunet_chat_lobby.h
@@ -43,9 +43,7 @@ struct GNUNET_CHAT_Lobby
struct GNUNET_CHAT_Context *context;
struct GNUNET_CHAT_Uri *uri;
- struct GNUNET_IDENTITY_Operation *op_create;
- struct GNUNET_IDENTITY_Operation *op_delete;
-
+ struct GNUNET_IDENTITY_Operation *op;
struct GNUNET_NAMESTORE_QueueEntry *query;
struct GNUNET_TIME_Absolute expiration;
diff --git a/src/gnunet_chat_lobby_intern.c b/src/gnunet_chat_lobby_intern.c
index 0c5a647..135dfe5 100644
--- a/src/gnunet_chat_lobby_intern.c
+++ b/src/gnunet_chat_lobby_intern.c
@@ -25,27 +25,6 @@
#include "gnunet_chat_context.h"
void
-cont_lobby_identity_delete (void *cls,
- const char *emsg)
-{
- struct GNUNET_CHAT_Lobby *lobby = cls;
-
- GNUNET_assert(lobby);
-
- lobby->op_delete = NULL;
-
- if (!emsg)
- return;
-
- handle_send_internal_message(
- lobby->handle,
- lobby->context,
- GNUNET_CHAT_FLAG_WARNING,
- emsg
- );
-}
-
-void
cont_lobby_write_records (void *cls,
GNUNET_UNUSED int32_t success,
const char *emsg)
@@ -63,12 +42,7 @@ cont_lobby_write_records (void *cls,
char *name;
util_lobby_name(key, &name);
- lobby->op_delete = GNUNET_IDENTITY_delete(
- lobby->handle->identity,
- name,
- cont_lobby_identity_delete,
- lobby
- );
+ handle_delete_account(lobby->handle, name);
GNUNET_free(name);
@@ -104,7 +78,7 @@ cont_lobby_identity_create (void *cls,
GNUNET_assert(lobby);
- lobby->op_create = NULL;
+ lobby->op = NULL;
if (emsg)
{
diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c
index e044415..d3c1385 100644
--- a/src/gnunet_chat_message.c
+++ b/src/gnunet_chat_message.c
@@ -37,6 +37,7 @@ message_create_from_msg (struct GNUNET_CHAT_Context *context,
struct GNUNET_CHAT_Message *message = GNUNET_new(struct GNUNET_CHAT_Message);
message->context = context;
+ message->task = NULL;
GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash));
message->flags = flags;
@@ -55,6 +56,7 @@ message_create_internally (struct GNUNET_CHAT_Context *context,
struct GNUNET_CHAT_Message *message = GNUNET_new(struct GNUNET_CHAT_Message);
message->context = context;
+ message->task = NULL;
memset(&(message->hash), 0, sizeof(message->hash));
message->flags = GNUNET_MESSENGER_FLAG_PRIVATE;
@@ -70,5 +72,8 @@ message_destroy (struct GNUNET_CHAT_Message* message)
{
GNUNET_assert(message);
+ if (message->task)
+ GNUNET_SCHEDULER_cancel(message->task);
+
GNUNET_free(message);
}
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h
index e39cc9c..3ea7283 100644
--- a/src/gnunet_chat_message.h
+++ b/src/gnunet_chat_message.h
@@ -53,6 +53,7 @@ enum GNUNET_CHAT_MessageFlag
struct GNUNET_CHAT_Message
{
struct GNUNET_CHAT_Context *context;
+ struct GNUNET_SCHEDULER_Task *task;
union {
const struct GNUNET_MESSENGER_Message *msg;
diff --git a/tests/test_gnunet_chat_lobby.c b/tests/test_gnunet_chat_lobby.c
index 8f079ed..53ef9e7 100644
--- a/tests/test_gnunet_chat_lobby.c
+++ b/tests/test_gnunet_chat_lobby.c
@@ -175,7 +175,9 @@ on_gnunet_chat_lobby_join_open(void *cls,
GNUNET_CHAT_lobby_join(chat, uri);
- GNUNET_SCHEDULER_add_now(
+ GNUNET_SCHEDULER_add_at_with_priority(
+ GNUNET_TIME_absolute_get(),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
on_gnunet_chat_lobby_join_task,
chat
);
@@ -244,9 +246,9 @@ call_gnunet_chat_lobby_join(const struct GNUNET_CONFIGURATION_Handle *cfg)
CREATE_GNUNET_TEST(test_gnunet_chat_lobby_join, call_gnunet_chat_lobby_join)
-START_SUITE(handle_suite, "Lobby")
+START_SUITE(lobby_suite, "Lobby")
ADD_TEST_TO_SUITE(test_gnunet_chat_lobby_base, "Open/Close")
ADD_TEST_TO_SUITE(test_gnunet_chat_lobby_join, "Join")
END_SUITE
-MAIN_SUITE(handle_suite, CK_NORMAL)
+MAIN_SUITE(lobby_suite, CK_NORMAL)