and in protocol.c. This file implements the client-to-client key
agreement as defined by the SILC protocol. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
SILC_TASK_CALLBACK(silc_client_key_agreement_final);
silc_ske_free(ctx->ske);
if (ctx->dest_id)
silc_free(ctx->dest_id);
- silc_task_unregister_by_fd(client->io_queue, ke->fd);
+ silc_schedule_task_del_by_fd(client->schedule, ke->fd);
silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
silc_net_close_connection(ke->fd);
if (ke->timeout)
- silc_task_unregister(client->timeout_queue, ke->timeout);
+ silc_schedule_task_del(client->schedule, ke->timeout);
silc_client_del_socket(ke->client, ke->sock);
- silc_task_register(client->timeout_queue, 0,
+ silc_schedule_task_add(client->schedule, 0,
silc_client_key_agreement_close,
(void *)ke, 0, 1,
SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
sock = silc_net_accept_connection(ke->fd);
if (sock < 0) {
- client->ops->say(client, conn,
- "Could not accept key agreement connection: ",
- strerror(errno));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Could not accept key agreement connection: ",
+ strerror(errno));
ke->client_entry->ke = NULL;
ke->completion(ke->client, ke->conn, ke->client_entry,
SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
- silc_task_unregister_by_fd(client->io_queue, ke->fd);
+ silc_schedule_task_del_by_fd(client->schedule, ke->fd);
silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
silc_net_close_connection(ke->fd);
if (ke->timeout)
- silc_task_unregister(client->timeout_queue, ke->timeout);
+ silc_schedule_task_del(client->schedule, ke->timeout);
silc_free(ke);
return;
}
/* Perform name and address lookups for the remote host. */
silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
if (!newsocket->hostname && !newsocket->ip) {
- client->ops->say(client, conn,
- "Could not resolve the remote IP or hostname");
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Could not resolve the remote IP or hostname");
ke->client_entry->ke = NULL;
ke->completion(ke->client, ke->conn, ke->client_entry,
SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
- silc_task_unregister_by_fd(client->io_queue, ke->fd);
+ silc_schedule_task_del_by_fd(client->schedule, ke->fd);
silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
silc_net_close_connection(ke->fd);
if (ke->timeout)
- silc_task_unregister(client->timeout_queue, ke->timeout);
+ silc_schedule_task_del(client->schedule, ke->timeout);
silc_free(ke);
return;
}
silc_ske_free(ke->proto_ctx->ske);
ke->client_entry->ke = NULL;
if (ke->fd)
- silc_task_unregister_by_fd(ke->client->io_queue, ke->fd);
+ silc_schedule_task_del_by_fd(ke->client->schedule, ke->fd);
silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
silc_net_close_connection(ke->fd);
silc_free(ke);
void silc_client_send_key_agreement(SilcClient client,
SilcClientConnection conn,
SilcClientEntry client_entry,
- char *hostname,
+ const char *hostname,
+ const char *bindhost,
int port,
- uint32 timeout_secs,
+ SilcUInt32 timeout_secs,
SilcKeyAgreementCallback completion,
void *context)
{
SilcClientKeyAgreement ke = NULL;
SilcBuffer buffer;
- assert(client_entry);
+ if (!client_entry)
+ return;
+
+ if (client_entry->ke) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ALREADY_STARTED,
+ NULL, context);
+ return;
+ }
- if (client_entry->ke)
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
return;
+ }
- /* Create the listener if hostname and port was provided */
+ /* Create the listener if hostname and port was provided.
+ * also, use bindhost if it was specified.
+ */
+
if (hostname) {
ke = silc_calloc(1, sizeof(*ke));
- ke->fd = silc_net_create_server(port, hostname);
+
+ if (bindhost)
+ ke->fd = silc_net_create_server(port, bindhost);
+ else
+ ke->fd = silc_net_create_server(port, hostname);
if (ke->fd < 0) {
- client->ops->say(client, conn,
- "Cannot create listener on %s on port %d: %s",
- hostname, port, strerror(errno));
+ client->internal->ops->say(
+ client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Cannot create listener on %s on port %d: %s",
+ (bindhost) ? bindhost:hostname, port, strerror(errno));
completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
NULL, context);
silc_free(ke);
ke->completion = completion;
ke->context = context;
- /* Add listener task to the queue. This task receives the key
+ /* Add listener task to the scheduler. This task receives the key
negotiations. */
- silc_task_register(client->io_queue, ke->fd,
- silc_client_process_key_agreement,
- (void *)ke, 0, 0,
- SILC_TASK_FD,
- SILC_TASK_PRI_NORMAL);
+ silc_schedule_task_add(client->schedule, ke->fd,
+ silc_client_process_key_agreement,
+ (void *)ke, 0, 0,
+ SILC_TASK_FD,
+ SILC_TASK_PRI_NORMAL);
/* Register a timeout task that will be executed if the connector
will not start the key exchange protocol within the specified
timeout. */
- ke->timeout = silc_task_register(client->timeout_queue, 0,
- silc_client_key_agreement_timeout,
- (void *)ke, timeout_secs, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+ ke->timeout = silc_schedule_task_add(client->schedule, 0,
+ silc_client_key_agreement_timeout,
+ (void *)ke, timeout_secs, 0,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
}
/* Encode the key agreement payload */
silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
client_entry->id, SILC_ID_CLIENT, NULL, NULL,
buffer->data, buffer->len, FALSE);
- silc_free(buffer);
+ silc_buffer_free(buffer);
}
static int
int sock;
/* Create connection to server asynchronously */
- sock = silc_net_create_connection_async(ctx->port, ctx->host);
+ sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
if (sock < 0)
return -1;
/* Register task that will receive the async connect and will
read the result. */
- ctx->task = silc_task_register(ctx->client->io_queue, sock,
- silc_client_perform_key_agreement_start,
- (void *)ctx, 0, 0,
- SILC_TASK_FD,
- SILC_TASK_PRI_NORMAL);
- silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
- silc_schedule_set_listen_fd(ctx->client->schedule, sock, ctx->task->iomask);
+ ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
+ silc_client_perform_key_agreement_start,
+ (void *)ctx, 0, 0,
+ SILC_TASK_FD,
+ SILC_TASK_PRI_NORMAL);
+ silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
ctx->sock = sock;
if (opt != 0) {
if (ctx->tries < 2) {
/* Connection failed but lets try again */
- client->ops->say(client, conn, "Could not connect to client %s: %s",
- ctx->host, strerror(opt));
- client->ops->say(client, conn,
- "Connecting to port %d of client %s resumed",
- ctx->port, ctx->host);
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Could not connect to client %s: %s",
+ ctx->host, strerror(opt));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Connecting to port %d of client %s resumed",
+ ctx->port, ctx->host);
/* Unregister old connection try */
silc_schedule_unset_listen_fd(client->schedule, fd);
silc_net_close_connection(fd);
- silc_task_unregister(client->io_queue, ctx->task);
+ silc_schedule_task_del(client->schedule, ctx->task);
/* Try again */
silc_client_connect_to_client_internal(ctx);
ctx->tries++;
} else {
/* Connection failed and we won't try anymore */
- client->ops->say(client, conn, "Could not connect to client %s: %s",
- ctx->host, strerror(opt));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Could not connect to client %s: %s",
+ ctx->host, strerror(opt));
silc_schedule_unset_listen_fd(client->schedule, fd);
silc_net_close_connection(fd);
- silc_task_unregister(client->io_queue, ctx->task);
+ silc_schedule_task_del(client->schedule, ctx->task);
silc_free(ctx->host);
silc_free(ctx);
}
silc_schedule_unset_listen_fd(client->schedule, fd);
- silc_task_unregister(client->io_queue, ctx->task);
+ silc_schedule_task_del(client->schedule, ctx->task);
ke->fd = fd;
SILC_LOG_DEBUG(("Start"));
- assert(client_entry && hostname && port);
+ if (!client_entry)
+ return;
+
+ if (!hostname || !port) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
+ NULL, context);
+ return;
+ }
+
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
+ return;
+ }
ke = silc_calloc(1, sizeof(*ke));
ke->client = client;
SILC_LOG_DEBUG(("Start"));
- assert(client_entry);
+ if (!client_entry)
+ return;
+
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
+ return;
+ }
ke = silc_calloc(1, sizeof(*ke));
ke->client = client;
SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
/* Execute the protocol */
- silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
+ silc_protocol_execute(protocol, client->schedule, 0, 0);
}
/* This function can be called to unbind the hostname and the port for
SilcClientConnection conn,
SilcClientEntry client_entry)
{
- assert(client_entry);
+ if (!client_entry)
+ return;
if (client_entry->ke) {
+ SilcClientKeyAgreement ke;
+
if (client_entry->ke->sock) {
silc_client_del_socket(client_entry->ke->client, client_entry->ke->sock);
silc_socket_free(client_entry->ke->sock);
}
- client_entry->ke = NULL;
- silc_task_unregister_by_fd(client->io_queue, client_entry->ke->fd);
+ silc_schedule_task_del_by_fd(client->schedule, client_entry->ke->fd);
if (client_entry->ke->timeout)
- silc_task_unregister(client->timeout_queue,
- client_entry->ke->timeout);
- silc_free(client_entry->ke);
+ silc_schedule_task_del(client->schedule,
+ client_entry->ke->timeout);
+ ke = client_entry->ke;
+ client_entry->ke = NULL;
+ ke->completion(client, conn, client_entry,
+ SILC_KEY_AGREEMENT_ABORTED, NULL, ke->context);
+ silc_free(ke);
}
}
silc_client_key_agreement_resolve_cb(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
- uint32 clients_count,
+ SilcUInt32 clients_count,
void *context)
{
SilcPacketContext *packet = (SilcPacketContext *)context;
goto out;
/* Parse the key agreement payload */
- payload = silc_key_agreement_payload_parse(packet->buffer);
+ payload = silc_key_agreement_payload_parse(packet->buffer->data,
+ packet->buffer->len);
if (!payload)
goto out;
/* Call the key_agreement client operation */
- ret = client->ops->key_agreement(client, conn, clients[0],
+ ret = client->internal->ops->key_agreement(
+ client, conn, clients[0],
silc_key_agreement_get_hostname(payload),
silc_key_agreement_get_port(payload),
&completion, &completion_context);
return;
silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
+ NULL,
silc_client_key_agreement_resolve_cb,
silc_packet_context_dup(packet));
silc_free(remote_id);