/* 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 */
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;
}
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;
}
{
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 */
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 */
/* 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;
/* 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
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),
*
* 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
*
*
* 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
*