diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-04-06 02:30:45 +0200 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-04-06 02:30:45 +0200 |
commit | 4423dd264ef99fe9617e5d871857d15e88639f51 (patch) | |
tree | b242b1ad2fb5d433000dd6d5c1f1d6d5b9c665dd | |
parent | de5dccb421f01bb09764ae1da40cb226c30b8d45 (diff) |
Added some safety for stopping chat handle
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | include/gnunet_chat_lib.h | 5 | ||||
-rw-r--r-- | src/gnunet_chat_handle.c | 114 | ||||
-rw-r--r-- | src/gnunet_chat_handle.h | 24 | ||||
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 76 | ||||
-rw-r--r-- | src/gnunet_chat_lib.c | 74 | ||||
-rw-r--r-- | src/gnunet_chat_lib_intern.c | 60 | ||||
-rw-r--r-- | src/gnunet_chat_lobby.c | 17 | ||||
-rw-r--r-- | src/gnunet_chat_lobby.h | 4 | ||||
-rw-r--r-- | src/gnunet_chat_lobby_intern.c | 30 | ||||
-rw-r--r-- | src/gnunet_chat_message.c | 5 | ||||
-rw-r--r-- | src/gnunet_chat_message.h | 1 | ||||
-rw-r--r-- | tests/test_gnunet_chat_lobby.c | 8 |
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) |