From: Pekka Riikonen Date: Fri, 15 Dec 2006 15:22:09 +0000 (+0000) Subject: Handle command reply lists in threads. X-Git-Tag: silc.client.1.1.beta1~106 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=124293f6809a8200f041c276d1846cb5de4dedf2 Handle command reply lists in threads. Removed unnecessary abort handling. --- diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 0c001e82..c7e4e6d8 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -185,7 +185,6 @@ static void silc_client_connect_abort(SilcAsyncOperation op, void *context) SilcClientConnection conn = context; SILC_LOG_DEBUG(("Connection %p aborted by application", conn)); - conn->internal->aborted = TRUE; /* Signal to close connection */ if (!conn->internal->disconnected) { @@ -408,7 +407,7 @@ SILC_FSM_STATE(silc_client_connection_st_close) return SILC_FSM_YIELD; } - /* Abort ongoing events */ + /* Abort ongoing event */ if (conn->internal->op) { SILC_LOG_DEBUG(("Abort event")); silc_async_abort(conn->internal->op, NULL, NULL); @@ -626,6 +625,7 @@ silc_client_add_connection(SilcClient client, struct SilcClientCommandContextStruct, next); silc_list_init(conn->internal->thread_pool, SilcFSMThreadStruct, next); + /* Allocate client, channel and serve caches */ conn->internal->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, NULL, NULL); conn->internal->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, @@ -640,8 +640,8 @@ silc_client_add_connection(SilcClient client, conn->internal->ftp_sessions = silc_dlist_init(); - /* Initiatlize our async operation so that application may abort us - while were connecting. */ + /* Initialize our async operation so that application may abort us + while we're connecting. */ conn->internal->cop = silc_async_alloc(silc_client_connect_abort, NULL, conn); if (!conn->internal->cop) { @@ -727,7 +727,6 @@ void silc_client_del_connection(SilcClient client, SilcClientConnection conn) silc_free(conn); } - /******************************* Client API *********************************/ /* Connects to remote server. This is the main routine used to connect @@ -745,6 +744,8 @@ silc_client_connect_to_server(SilcClient client, { SilcClientConnection conn; + SILC_LOG_DEBUG(("Connecting to server")); + if (!client || !remote_host) return NULL; @@ -780,6 +781,8 @@ silc_client_connect_to_client(SilcClient client, { SilcClientConnection conn; + SILC_LOG_DEBUG(("Connecting to client")); + if (!client || !remote_host) return NULL; @@ -814,6 +817,8 @@ silc_client_key_exchange(SilcClient client, const char *host; SilcUInt16 port; + SILC_LOG_DEBUG(("Performing key exchange")); + if (!client || !stream) return NULL; @@ -853,164 +858,6 @@ void silc_client_close_connection(SilcClient client, } #if 0 -/* Finalizes the connection to the remote SILC server. This is called - after authentication protocol has been completed. This send our - user information to the server to receive our client ID from - server. */ - -SILC_TASK_CALLBACK(silc_client_connect_to_server_final) -{ - SilcProtocol protocol = (SilcProtocol)context; - SilcClientConnAuthInternalContext *ctx = - (SilcClientConnAuthInternalContext *)protocol->context; - SilcClient client = (SilcClient)ctx->client; - SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; - SilcBuffer packet; - - SILC_LOG_DEBUG(("Start")); - - if (protocol->state == SILC_PROTOCOL_STATE_ERROR || - protocol->state == SILC_PROTOCOL_STATE_FAILURE) { - /* Error occured during protocol */ - SILC_LOG_DEBUG(("Error during authentication protocol")); - ctx->status = SILC_CLIENT_CONN_ERROR_AUTH; - goto err; - } - - if (conn->internal->params.detach_data) { - /* Send RESUME_CLIENT packet to the server, which is used to resume - old detached session back. */ - SilcBuffer auth; - SilcClientID *old_client_id; - unsigned char *old_id; - SilcUInt16 old_id_len; - - if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len)) { - ctx->status = SILC_CLIENT_CONN_ERROR_RESUME; - goto err; - } - - old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT); - if (!old_client_id) { - silc_free(old_id); - ctx->status = SILC_CLIENT_CONN_ERROR_RESUME; - goto err; - } - - /* Generate authentication data that server will verify */ - auth = silc_auth_public_key_auth_generate(client->public_key, - client->private_key, - client->rng, - conn->internal->hash, - old_client_id, SILC_ID_CLIENT); - if (!auth) { - silc_free(old_client_id); - silc_free(old_id); - ctx->status = SILC_CLIENT_CONN_ERROR_RESUME; - goto err; - } - - packet = silc_buffer_alloc_size(2 + old_id_len + auth->len); - silc_buffer_format(packet, - SILC_STR_UI_SHORT(old_id_len), - SILC_STR_UI_XNSTRING(old_id, old_id_len), - SILC_STR_UI_XNSTRING(auth->data, auth->len), - SILC_STR_END); - - /* Send the packet */ - silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT, - NULL, 0, NULL, NULL, - packet->data, packet->len, TRUE); - silc_buffer_free(packet); - silc_buffer_free(auth); - silc_free(old_client_id); - silc_free(old_id); - } else { - /* Send NEW_CLIENT packet to the server. We will become registered - to the SILC network after sending this packet and we will receive - client ID from the server. */ - packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + - strlen(client->realname)); - silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); - silc_buffer_format(packet, - SILC_STR_UI_SHORT(strlen(client->username)), - SILC_STR_UI_XNSTRING(client->username, - strlen(client->username)), - SILC_STR_UI_SHORT(strlen(client->realname)), - SILC_STR_UI_XNSTRING(client->realname, - strlen(client->realname)), - SILC_STR_END); - - /* Send the packet */ - silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT, - NULL, 0, NULL, NULL, - packet->data, packet->len, TRUE); - silc_buffer_free(packet); - } - - /* Save remote ID. */ - conn->remote_id = ctx->dest_id; - conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER); - conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER); - - /* Register re-key timeout */ - conn->internal->rekey->timeout = client->internal->params->rekey_secs; - conn->internal->rekey->context = (void *)client; - silc_schedule_task_add(client->schedule, conn->sock->sock, - silc_client_rekey_callback, - (void *)conn->sock, conn->internal->rekey->timeout, 0, - SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); - - silc_protocol_free(protocol); - silc_free(ctx->auth_data); - silc_socket_free(ctx->sock); - silc_free(ctx); - conn->sock->protocol = NULL; - return; - - err: - silc_protocol_free(protocol); - silc_free(ctx->auth_data); - silc_free(ctx->dest_id); - conn->sock->protocol = NULL; - silc_socket_free(ctx->sock); - - /* Notify application of failure */ - silc_schedule_task_add(client->schedule, ctx->sock->sock, - silc_client_connect_failure_auth, ctx, - 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); -} - -/* Client session resuming callback. If the session was resumed - this callback is called after the resuming is completed. This - will call the `connect' client operation to the application - since it has not been called yet. */ - -static void silc_client_resume_session_cb(SilcClient client, - SilcClientConnection conn, - SilcBool success, - void *context) -{ - SilcBuffer sidp; - - /* Notify application that connection is created to server */ - client->internal->ops->connected(client, conn, success ? - SILC_CLIENT_CONN_SUCCESS_RESUME : - SILC_CLIENT_CONN_ERROR_RESUME); - - if (success) { - /* Issue INFO command to fetch the real server name and server - information and other stuff. */ - silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL, - silc_client_command_reply_info_i, 0, - ++conn->cmd_ident); - sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER); - silc_client_command_send(client, conn, SILC_COMMAND_INFO, - conn->cmd_ident, 1, 2, sidp->data, sidp->len); - silc_buffer_free(sidp); - } -} - /* Processes incoming connection authentication method request packet. It is a reply to our previously sent request. The packet can be used to resolve the authentication method for the current session if the @@ -1118,7 +965,6 @@ silc_client_request_authentication_method(SilcClient client, } #endif /* 0 */ - /* Allocates new client object. This has to be done before client may work. After calling this one must call silc_client_init to initialize the client. The `application' is application specific user data pointer @@ -1203,7 +1049,7 @@ SilcBool silc_client_init(SilcClient client, const char *username, return FALSE; if (!username || !hostname) { - SILC_LOG_ERROR(("Username, hostname and realname must be given to " + SILC_LOG_ERROR(("Username and hostname must be given to " "silc_client_init")); return FALSE; } @@ -1258,6 +1104,12 @@ SilcBool silc_client_init(SilcClient client, const char *username, if (!client->schedule) return FALSE; + /* Allocate client lock */ + silc_mutex_alloc(&client->internal->lock); + + /* Register commands */ + silc_client_commands_register(client); + /* Start packet engine */ client->internal->packet_engine = silc_packet_engine_start(client->rng, FALSE, &silc_client_stream_cbs, @@ -1265,12 +1117,6 @@ SilcBool silc_client_init(SilcClient client, const char *username, if (!client->internal->packet_engine) return FALSE; - /* Allocate client lock */ - silc_mutex_alloc(&client->internal->lock); - - /* Register commands */ - silc_client_commands_register(client); - /* Initialize and start the client FSM */ client->internal->running = running; client->internal->running_context = context; @@ -1296,8 +1142,7 @@ void silc_client_run(SilcClient client) silc_schedule(client->schedule); } -/* Call scheduler one iteration and return. This cannot be called if threads - are in use. */ +/* Call scheduler one iteration and return. */ void silc_client_run_one(SilcClient client) { diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index bb5c071e..51fc8547 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -202,6 +202,13 @@ SILC_FSM_STATE(silc_client_channel_message) return SILC_FSM_CONTINUE; } + /* Check that user is on channel */ + if (!silc_client_on_channel(channel, client_entry)) { + /** User not on channel */ + silc_fsm_next(fsm, silc_client_channel_message_error); + return SILC_FSM_CONTINUE; + } + /* If there is no channel private key then just decrypt the message with the channel key. If private keys are set then just go through all private keys and check what decrypts correctly. */ diff --git a/lib/silcclient/client_connect.c b/lib/silcclient/client_connect.c index 8c149194..ccf5793c 100644 --- a/lib/silcclient/client_connect.c +++ b/lib/silcclient/client_connect.c @@ -32,12 +32,6 @@ static void silc_client_connect_callback(SilcNetStatus status, SilcClientConnection conn = silc_fsm_get_context(fsm); SilcClient client = conn->client; - if (conn->internal->aborted) { - silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); - return; - } - conn->internal->op = NULL; if (conn->internal->verbose) { switch (status) { @@ -127,14 +121,6 @@ static void silc_client_ke_verify_key(SilcSKE ske, SilcClient client = conn->client; VerifyKeyContext verify; - if (conn->internal->aborted) { - completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY, - completion_context); - silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); - return; - } - /* If we provided repository for SKE and we got here the key was not found from the repository. */ if (conn->internal->params.repository && @@ -178,13 +164,6 @@ static void silc_client_ke_completion(SilcSKE ske, SilcCipher send_key, receive_key; SilcHmac hmac_send, hmac_receive; - if (conn->internal->aborted) { - silc_ske_free_rekey_material(rekey); - silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); - return; - } - conn->internal->op = NULL; if (status != SILC_SKE_STATUS_OK) { /* Key exchange failed */ @@ -328,12 +307,6 @@ static void silc_client_connect_auth_completion(SilcConnAuth connauth, SilcClientConnection conn = silc_fsm_get_context(fsm); SilcClient client = conn->client; - if (conn->internal->aborted) { - silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); - return; - } - conn->internal->op = NULL; silc_connauth_free(connauth); diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index 1d3189ba..da8f0b24 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -934,19 +934,23 @@ void silc_client_nickname_format(SilcClient client, if (!clients && !client->internal->params->nickname_force_format) return; - len = 0; - freebase = TRUE; - while ((entry = silc_dlist_get(clients))) { - if (entry->internal.valid && entry != client_entry) - len++; - if (entry->internal.valid && entry != client_entry && - silc_utf8_strcasecmp(entry->nickname, client_entry->nickname)) { - freebase = FALSE; - unformatted = entry; + if (clients) { + len = 0; + freebase = TRUE; + while ((entry = silc_dlist_get(clients))) { + if (entry->internal.valid && entry != client_entry) + len++; + if (entry->internal.valid && entry != client_entry && + silc_utf8_strcasecmp(entry->nickname, client_entry->nickname)) { + freebase = FALSE; + unformatted = entry; + } + } + if (!len || freebase) { + silc_client_list_free(client, conn, clients); + return; } } - if (!len || freebase) - return; /* If we are changing nickname of our local entry we'll enforce that we will always get the unformatted nickname. Give our @@ -1012,18 +1016,20 @@ void silc_client_nickname_format(SilcClient client, char tmp[6]; int num, max = 1; - if (silc_dlist_count(clients) == 1) + if (clients && silc_dlist_count(clients) == 1) break; - silc_dlist_start(clients); - while ((entry = silc_dlist_get(clients))) { - if (!silc_utf8_strncasecmp(entry->nickname, newnick, off)) - continue; - if (strlen(entry->nickname) <= off) - continue; - num = atoi(&entry->nickname[off]); - if (num > max) - max = num; + if (clients) { + silc_dlist_start(clients); + while ((entry = silc_dlist_get(clients))) { + if (!silc_utf8_strncasecmp(entry->nickname, newnick, off)) + continue; + if (strlen(entry->nickname) <= off) + continue; + num = atoi(&entry->nickname[off]); + if (num > max) + max = num; + } } memset(tmp, 0, sizeof(tmp)); diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index d3437edf..7d42b470 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -186,7 +186,7 @@ struct SilcClientConnectionInternalStruct { /* Events */ unsigned int connect : 1; /* Connect remote host */ - unsigned int disconnected : 1; /* Disconnected by remote host */ + unsigned int disconnected : 1; /* Disconnect remote connection */ unsigned int key_exchange : 1; /* Start key exchange */ unsigned int rekeying : 1; /* Start rekey */ @@ -195,7 +195,6 @@ struct SilcClientConnectionInternalStruct { unsigned int registering : 1; /* Set when registering to network */ unsigned int rekey_responder : 1; /* Set when rekeying as responder */ unsigned int callback_called : 1; /* Set when connect callback called */ - unsigned int aborted : 1; /* Set when aborted by application */ SilcClientAway *away; SilcClientConnAuthRequest connauth; diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c index 42cb3677..2b28d454 100644 --- a/lib/silcclient/client_register.c +++ b/lib/silcclient/client_register.c @@ -186,12 +186,6 @@ SILC_FSM_STATE(silc_client_st_register_complete) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; - if (conn->internal->aborted) { - /** Aborted */ - silc_fsm_next(fsm, silc_client_st_register_error); - return SILC_FSM_CONTINUE; - } - if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_register_error); diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 0e952e9f..236fb0f6 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -69,6 +69,7 @@ static inline void silc_client_command_callback(SilcClientCommandContext cmd, ...) { SilcClientCommandReplyCallback cb; + SilcList list; va_list ap, cp; va_start(ap, cmd); @@ -83,8 +84,9 @@ silc_client_command_callback(SilcClientCommandContext cmd, ...) } /* Reply callback */ - silc_list_start(cmd->reply_callbacks); - while ((cb = silc_list_get(cmd->reply_callbacks))) + list = cmd->reply_callbacks; + silc_list_start(list); + while ((cb = silc_list_get(list))) if (!cb->do_not_call) { silc_va_copy(cp, ap); cb->do_not_call = !cb->reply(cmd->conn->client, cmd->conn, cmd->cmd,