From: Pekka Riikonen Date: Tue, 8 May 2007 16:34:53 +0000 (+0000) Subject: Fixed file transfer disconnection crash. X-Git-Tag: silc.toolkit.1.1.beta2~20 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=2b4b7f7d53c9cfa3d7dedd3f29c1cb1de6505876 Fixed file transfer disconnection crash. Fixed private message waiting to be per client entry instead of per connection. --- diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index af1ff208..ac1116d2 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -43,6 +43,7 @@ typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey; /* Internal client entry context */ typedef struct SilcClientEntryInternalStruct { + void *prv_waiter; /* Private message packet waiter */ SilcRwLock lock; /* Read/write lock */ SilcCipher send_key; /* Private message key for sending */ SilcCipher receive_key; /* Private message key for receiving */ diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index 5c098274..a38d03c0 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -108,7 +108,7 @@ static void silc_client_ftp_data(SilcSFTP sftp, silc_sftp_close(sftp, session->read_handle, NULL, NULL); session->read_handle = NULL; - /* Close the read file descriptor */ + /* Close the real file descriptor */ silc_file_close(session->fd); return; } @@ -130,7 +130,7 @@ static void silc_client_ftp_data(SilcSFTP sftp, silc_sftp_close(sftp, session->read_handle, NULL, NULL); session->read_handle = NULL; - /* Close the read file descriptor */ + /* Close the real file descriptor */ silc_file_close(session->fd); return; } @@ -380,6 +380,8 @@ static void silc_client_ftp_session_free(SilcClientFtpSession session) { SILC_LOG_DEBUG(("Free session %d", session->session_id)); + silc_schedule_task_del_by_context(session->client->schedule, session); + silc_dlist_del(session->client->internal->ftp_sessions, session); /* Abort connecting */ diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index 4af35450..8b48e733 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -139,7 +139,6 @@ struct SilcClientConnectionInternalStruct { SilcStream user_stream; /* Low level stream in connecting */ char *disconnect_message; /* Disconnection message */ char *away_message; /* Away message */ - void *prv_waiter; /* Private message packet waiter */ SilcIDCache client_cache; /* Client entry cache */ SilcIDCache channel_cache; /* Channel entry cache */ diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index c9884942..2242fd34 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -197,14 +197,21 @@ SILC_FSM_STATE(silc_client_private_message_error) /* Initialize private message waiter for the `conn' connection. */ SilcBool silc_client_private_message_wait_init(SilcClient client, - SilcClientConnection conn) + SilcClientConnection conn, + SilcClientEntry client_entry) { - if (conn->internal->prv_waiter) + SilcID id; + + if (client_entry->internal.prv_waiter) return TRUE; - conn->internal->prv_waiter = - silc_packet_wait_init(conn->stream, SILC_PACKET_PRIVATE_MESSAGE, -1); - if (!conn->internal->prv_waiter) + /* We want SILC_PACKET_PRIVATE_MESSAGE packets from this source ID. */ + id.type = SILC_ID_CLIENT; + id.u.client_id = client_entry->id; + + client_entry->internal.prv_waiter = + silc_packet_wait_init(conn->stream, &id, SILC_PACKET_PRIVATE_MESSAGE, -1); + if (!client_entry->internal.prv_waiter) return FALSE; return TRUE; @@ -213,12 +220,13 @@ SilcBool silc_client_private_message_wait_init(SilcClient client, /* Uninitializes private message waiter. */ void silc_client_private_message_wait_uninit(SilcClient client, - SilcClientConnection conn) + SilcClientConnection conn, + SilcClientEntry client_entry) { - if (!conn->internal->prv_waiter) + if (!client_entry->internal.prv_waiter) return; - silc_packet_wait_uninit(conn->internal->prv_waiter, conn->stream); - conn->internal->prv_waiter = NULL; + silc_packet_wait_uninit(client_entry->internal.prv_waiter, conn->stream); + client_entry->internal.prv_waiter = NULL; } /* Blocks the calling process or thread until private message has been @@ -230,42 +238,15 @@ SilcBool silc_client_private_message_wait(SilcClient client, SilcMessagePayload *payload) { SilcPacket packet; - SilcClientID remote_id; - SilcFSMThread thread; - if (!conn->internal->prv_waiter) + if (!client_entry->internal.prv_waiter) return FALSE; /* Block until private message arrives */ do { - if ((silc_packet_wait(conn->internal->prv_waiter, 0, &packet)) < 0) + if ((silc_packet_wait(client_entry->internal.prv_waiter, 0, &packet)) < 0) return FALSE; - /* Parse sender ID */ - if (!silc_id_str2id(packet->src_id, packet->src_id_len, - SILC_ID_CLIENT, &remote_id, - sizeof(remote_id))) { - silc_packet_free(packet); - continue; - } - - /* If the private message is not for the requested client, pass it to - normal private message processing. */ - if (!SILC_ID_CLIENT_COMPARE(&remote_id, &client_entry->id)) { - thread = silc_fsm_thread_alloc(&conn->internal->fsm, conn, - silc_client_fsm_destructor, NULL, FALSE); - if (!thread) { - silc_packet_free(packet); - continue; - } - - /* The packet will be processed in the connection thread, after this - FSM thread is started. */ - silc_fsm_set_state_context(thread, packet); - silc_fsm_start(thread, silc_client_private_message); - continue; - } - /* Parse the payload and decrypt it also if private message key is set */ *payload = silc_message_payload_parse(silc_buffer_data(&packet->buffer), diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index f491e37e..94f78481 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -1195,21 +1195,23 @@ SilcBool silc_client_send_private_message(SilcClient client, * * SilcBool * silc_client_private_message_wait_init(SilcClient client, - * SilcClientConnection conn); + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * - * Initializes private message waiting functionality for the connection - * indicated by `conn'. Once this is called private message from remote - * connection indicated by `conn' for any client entry beloning to that - * connection may be waited for, for example in a thread. The function + * Initializes private message waiting functionality for the client + * indicated by `client_entry'. Once this is called private message + * from remote connection indicated by `conn' for `client_entry' may + * be waiter for, for example in a thread. The function * silc_client_private_message_wait is used to block the current thread * until a private message is received from a specified client entry. * Return FALSE in case an internal error occurred. * ***/ SilcBool silc_client_private_message_wait_init(SilcClient client, - SilcClientConnection conn); + SilcClientConnection conn, + SilcClientEntry client_entry); /****f* silcclient/SilcClientAPI/silc_client_private_message_wait_uninit * @@ -1217,18 +1219,20 @@ SilcBool silc_client_private_message_wait_init(SilcClient client, * * void * silc_client_private_message_wait_uninit(SilcClient client, - * SilcClientConnection conn); + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * - * Unintializes private message waiting for connection indicated by - * `conn'. After this call private message cannot be waited anymore. - * This call may be called from any thread. This call will signal all - * private message waiting threads to stop waiting. + * Unintializes private message waiting for client indicated by + * `client_entry'. After this call private message cannot be waited + * anymore and silc_client_private_message_wait will return with FALSE + * value. * ***/ void silc_client_private_message_wait_uninit(SilcClient client, - SilcClientConnection conn); + SilcClientConnection conn, + SilcClientEntry client_entry); /****f* silcclient/SilcClientAPI/silc_client_private_message_wait *