#include "silcclient.h"
#include "client_internal.h"
-/************************** Types and definitions ***************************/
-
-
/************************ Static utility functions **************************/
/* Connection machine FSM destructor. This will finish the thread where
/* Delete connection */
silc_client_del_connection(conn->client, conn);
- /* Finish the thread were this machine was running */
+ /* Finish the thread were this machine was running. Its destructor is the
+ silc_client_connection_finished. */
silc_fsm_finish(thread);
}
/* Connection callback will not be called after user aborted connecting */
conn->callback = NULL;
+ conn->internal->cop = NULL;
/* Signal to close connection */
if (!conn->internal->disconnected) {
conn->internal->disconnected = TRUE;
- SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
+
+ /* If user aborts before connection machine is even up yet, then don't
+ send signal yet. It will process this event when it comes up. */
+ if (silc_fsm_is_started(&conn->internal->fsm))
+ SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
}
}
silc_fsm_event_init(&conn->internal->wait_event, connfsm);
silc_fsm_start_sync(connfsm, silc_client_connection_st_run);
- /* Schedule any events set in initialization */
+ /* Schedule any events possibly set in initialization */
+ if (conn->internal->disconnected)
+ SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
if (conn->internal->connect)
SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
if (conn->internal->key_exchange)
/* Process events */
thread = &conn->internal->event_thread;
+ if (conn->internal->disconnected) {
+ /** Event: disconnected */
+ SILC_LOG_DEBUG(("Event: disconnected"));
+ silc_fsm_next(fsm, silc_client_connection_st_close);
+ return SILC_FSM_YIELD;
+ }
+
if (conn->internal->connect) {
SILC_LOG_DEBUG(("Event: connect"));
conn->internal->connect = FALSE;
return SILC_FSM_CONTINUE;
}
- if (conn->internal->disconnected) {
- /** Event: disconnected */
- SILC_LOG_DEBUG(("Event: disconnected"));
- silc_fsm_next(fsm, silc_client_connection_st_close);
- return SILC_FSM_YIELD;
- }
-
/* NOT REACHED */
SILC_ASSERT(FALSE);
return SILC_FSM_CONTINUE;
SILC_LOG_DEBUG(("Closing remote connection"));
- /* Close connection */
- silc_packet_stream_destroy(conn->stream);
+ /* Close connection. */
+ if (conn->stream)
+ silc_packet_stream_destroy(conn->stream);
SILC_LOG_DEBUG(("Finishing connection machine"));
return SILC_FSM_FINISH;
/* Process events */
- if (client->internal->run_callback && client->internal->running) {
+ if (client->internal->run_callback) {
/* Call running callbcak back to application */
- SILC_LOG_DEBUG(("We are up, call running callback"));
client->internal->run_callback = FALSE;
- client->internal->running(client, client->internal->running_context);
+ if (client->internal->running) {
+ SILC_LOG_DEBUG(("We are up, call running callback"));
+ client->internal->running(client, client->internal->running_context);
+ }
return SILC_FSM_CONTINUE;
}
if (client->internal->stop) {
/* Stop client libarry. If we have running connections, wait until
they finish first. */
- SILC_LOG_DEBUG(("Event: stop"));
- if (silc_atomic_get_int16(&client->internal->conns) == 0)
+ if (silc_atomic_get_int16(&client->internal->conns) == 0) {
+ SILC_LOG_DEBUG(("Event: stop"));
silc_fsm_next(fsm, silc_client_st_stop);
+ }
return SILC_FSM_CONTINUE;
}
if (conn->internal->sha1hash)
silc_hash_free(conn->internal->sha1hash);
silc_atomic_uninit16(&conn->internal->cmd_ident);
+ silc_free(conn->internal->away_message);
+ if (conn->internal->rekey)
+ silc_ske_free_rekey_material(conn->internal->rekey);
+ if (conn->internal->cop)
+ silc_async_free(conn->internal->cop);
silc_free(conn->internal);
memset(conn, 'F', sizeof(*conn));
if (!client || !remote_host)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
/* Add new connection */
conn = silc_client_add_connection(client, SILC_CONN_SERVER, TRUE, params,
public_key, private_key, remote_host,
if (!client || !remote_host)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
if (params)
params->no_authentication = TRUE;
if (!client || !stream)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
if (!silc_socket_stream_get_info(stream, NULL, &host, NULL, &port)) {
SILC_LOG_ERROR(("Socket stream does not have remote host name set"));
callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
return NULL;
}
- conn->stream = (void *)stream;
+ conn->internal->user_stream = stream;
/* Signal connection to start key exchange */
conn->internal->key_exchange = TRUE;
{
SILC_LOG_DEBUG(("Closing connection %p", conn));
- /* If connection machine is not running, we just delete the connection */
- if (!silc_fsm_is_started(&conn->internal->fsm)) {
- silc_packet_stream_destroy(conn->stream);
- silc_client_del_connection(conn->client, conn);
- return;
- }
-
/* Signal to close connection */
conn->internal->status = SILC_CLIENT_CONN_DISCONNECTED;
if (!conn->internal->disconnected) {
void silc_client_free(SilcClient client)
{
- silc_schedule_uninit(client->schedule);
+ if (client->schedule)
+ silc_schedule_uninit(client->schedule);
if (client->rng)
silc_rng_free(client->rng);
silc_hmac_unregister_all();
}
+ if (client->internal->packet_engine)
+ silc_packet_engine_stop(client->internal->packet_engine);
+ if (client->internal->ftp_sessions)
+ silc_dlist_uninit(client->internal->ftp_sessions);
+ if (client->internal->lock)
+ silc_mutex_free(client->internal->lock);
silc_atomic_uninit16(&client->internal->conns);
silc_free(client->username);
silc_free(client->hostname);
{
SILC_LOG_DEBUG(("Stopping client"));
+ if (!silc_fsm_is_started(&client->internal->fsm)) {
+ SILC_LOG_WARNING(("Attempting to stop client library before it has been "
+ "started (silc_client_init not called)"));
+ return;
+ }
+
client->internal->running = (SilcClientRunning)stopped;
client->internal->running_context = context;