silc_schedule(client->schedule);
}
+/* Runs the client and returns immeadiately. This function is used when
+ the SILC Client object indicated by the `client' is run under some
+ other scheduler, or event loop or main loop. On GUI applications,
+ for example this may be desired to use to run the client under the
+ GUI application's main loop. Typically the GUI application would
+ register an idle task that calls this function multiple times in
+ a second to quickly process the SILC specific data. */
+
+void silc_client_run_one(SilcClient client)
+{
+ /* Run the scheduler once. */
+ silc_schedule_one(client->schedule, 0);
+}
+
static void silc_client_entry_destructor(SilcIDCache cache,
SilcIDCacheEntry entry)
{
return TRUE;
}
+/* Callback called when error has occurred during connecting to the server.
+ The `connect' client operation will be called. */
+
+SILC_TASK_CALLBACK(silc_client_connect_failure)
+{
+ SilcClientKEInternalContext *ctx =
+ (SilcClientKEInternalContext *)context;
+ SilcClient client = (SilcClient)ctx->client;
+
+ client->ops->connect(client, ctx->sock->user_data, FALSE);
+ silc_free(ctx);
+}
+
/* Start of the connection to the remote server. This is called after
succesful TCP/IP connection has been established to the remote host. */
silc_socket_free(ctx->sock);
/* Notify application of failure */
- client->ops->connect(client, ctx->sock->user_data, FALSE);
- silc_free(ctx);
+ silc_schedule_task_add(client->schedule, ctx->sock->sock,
+ silc_client_connect_failure, ctx,
+ 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
return;
}
silc_socket_free(ctx->sock);
/* Notify application of failure */
- client->ops->connect(client, ctx->sock->user_data, FALSE);
- silc_free(ctx);
+ silc_schedule_task_add(client->schedule, ctx->sock->sock,
+ silc_client_connect_failure, ctx,
+ 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
return;
}
*/
SilcIDPayload idp;
- idp = silc_id_payload_parse(buffer);
+ idp = silc_id_payload_parse(buffer->data, buffer->len);
if (!idp)
break;
if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
{
SilcClientConnection conn = (SilcClientConnection)sock->user_data;
int connecting = FALSE;
+ SilcClientID *client_id = silc_id_payload_get_id(idp);
SilcBuffer sidp;
if (!conn->local_entry)
/* Delete old ID from ID cache */
if (conn->local_id) {
+ /* Check whether they are different */
+ if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
+ silc_free(client_id);
+ return;
+ }
+
silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
silc_free(conn->local_id);
}
if (conn->local_id_data)
silc_free(conn->local_id_data);
- conn->local_id = silc_id_payload_get_id(idp);
+ conn->local_id = client_id;
conn->local_id_data = silc_id_payload_get_data(idp);
conn->local_id_data_len = silc_id_payload_get_len(idp);;
silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id,
(void *)conn->local_entry, FALSE);
- /* Issue INFO command to fetch the real server name and server information
- and other stuff. */
- sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
- silc_client_send_command(client, conn, SILC_COMMAND_INFO,
- ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
- silc_buffer_free(sidp);
+ if (connecting) {
+ /* Issue INFO comqmand to fetch the real server name and server information
+ and other stuff. */
+ sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
+ silc_client_send_command(client, conn, SILC_COMMAND_INFO,
+ ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
+ silc_buffer_free(sidp);
- /* Notify application of successful connection. We do it here now that
- we've received the Client ID and are allowed to send traffic. */
- if (connecting)
+ /* Notify application of successful connection. We do it here now that
+ we've received the Client ID and are allowed to send traffic. */
client->ops->connect(client, conn, TRUE);
+ }
}
/* Processed received Channel ID for a channel. This is called when client