silc_client_protocols_register();
/* Initialize the scheduler */
- silc_schedule_init(&client->io_queue, &client->timeout_queue,
- &client->generic_queue, 5000);
+ client->schedule = silc_schedule_init(&client->io_queue,
+ &client->timeout_queue,
+ &client->generic_queue, 5000);
+ if (!client->schedule)
+ return FALSE;
return TRUE;
}
/* Stop the scheduler, although it might be already stopped. This
doesn't hurt anyone. This removes all the tasks and task queues,
as well. */
- silc_schedule_stop();
- silc_schedule_uninit();
+ silc_schedule_stop(client->schedule);
+ silc_schedule_uninit(client->schedule);
silc_client_protocols_unregister();
/* Start the scheduler, the heart of the SILC client. When this returns
the program will be terminated. */
- silc_schedule();
+ silc_schedule(client->schedule);
}
/* Allocates and adds new connection to the client. This adds the allocated
SILC_TASK_FD,
SILC_TASK_PRI_NORMAL);
silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
- silc_schedule_set_listen_fd(sock, ctx->task->iomask);
+ silc_schedule_set_listen_fd(ctx->client->schedule, sock, ctx->task->iomask);
ctx->sock = sock;
SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
/* Execute the protocol */
- protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
+ silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
return TRUE;
}
ctx->port, ctx->host);
/* Unregister old connection try */
- silc_schedule_unset_listen_fd(fd);
+ silc_schedule_unset_listen_fd(client->schedule, fd);
silc_net_close_connection(fd);
silc_task_unregister(client->io_queue, ctx->task);
/* Connection failed and we won't try anymore */
client->ops->say(client, conn, "Could not connect to server %s: %s",
ctx->host, strerror(opt));
- silc_schedule_unset_listen_fd(fd);
+ silc_schedule_unset_listen_fd(client->schedule, fd);
silc_net_close_connection(fd);
silc_task_unregister(client->io_queue, ctx->task);
silc_free(ctx);
return;
}
- silc_schedule_unset_listen_fd(fd);
+ silc_schedule_unset_listen_fd(client->schedule, fd);
silc_task_unregister(client->io_queue, ctx->task);
silc_free(ctx);
if (!client->ops->get_auth_method(client, sock->user_data, sock->hostname,
sock->port, &proto_ctx->auth_meth,
&proto_ctx->auth_data,
- &proto_ctx->auth_data_len)) {
- client->ops->say(client, ctx->sock->user_data,
- "Could not resolve authentication method to use, "
- "assume no authentication");
+ &proto_ctx->auth_data_len))
proto_ctx->auth_meth = SILC_AUTH_NONE;
- }
/* Free old protocol as it is finished now */
silc_protocol_free(protocol);
silc_client_connect_to_server_final);
/* Execute the protocol */
- sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
}
/* Finalizes the connection to the remote SILC server. This is called
This call sets the connection both for input and output (the input
is set always and this call keeps the input setting, actually).
Actual data sending is performed by silc_client_packet_process. */
- SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
+ SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
/* Mark to socket that data is pending in outgoing buffer. This flag
is needed if new data is added to the buffer before the earlier
back to only for input. When there is again some outgoing data
available for this connection it will be set for output as well.
This call clears the output setting and sets it only for input. */
- SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
+ SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
SILC_UNSET_OUTBUF_PENDING(sock);
silc_buffer_clear(sock->outbuf);
* one protocol for connection executing at once hence this
* success message is for whatever protocol is executing currently.
*/
- if (sock->protocol) {
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
- }
+ if (sock->protocol)
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
break;
case SILC_PACKET_FAILURE:
/*
break;
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
} else {
SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
"protocol active, packet dropped."));
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
} else {
SilcClientKEInternalContext *proto_ctx =
(SilcClientKEInternalContext *)sock->protocol->context;
break;
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
}
} else {
SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
} else {
SilcClientKEInternalContext *proto_ctx =
(SilcClientKEInternalContext *)sock->protocol->context;
break;
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
}
} else {
SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
/* Let the protocol handle the packet */
if (proto_ctx->responder == FALSE)
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, client->timeout_queue, 0, 0);
else
/* Let the protocol handle the packet */
- sock->protocol->execute(client->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 100000);
+ silc_protocol_execute(sock->protocol, client->timeout_queue,
+ 0, 100000);
} else {
SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
"protocol active, packet dropped."));
{
SilcPacketContext packetdata;
+ if (!sock)
+ return;
+
SILC_LOG_DEBUG(("Sending packet, type %d", type));
/* Get data used in the packet sending, keys and stuff */
sock = conn->sock;
/* We won't listen for this connection anymore */
- silc_schedule_unset_listen_fd(sock->sock);
+ silc_schedule_unset_listen_fd(client->schedule, sock->sock);
/* Unregister all tasks */
silc_task_unregister_by_fd(client->io_queue, sock->sock);
/* Close the actual connection */
silc_net_close_connection(sock->sock);
+ /* Cancel any active protocol */
+ if (sock->protocol) {
+ if (sock->protocol->protocol->type ==
+ SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
+ sock->protocol->protocol->type ==
+ SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
+ sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute_final(sock->protocol, client->timeout_queue);
+ sock->protocol = NULL;
+ /* The application will recall this function with these protocols
+ (the ops->connect client operation). */
+ return;
+ } else {
+ sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute_final(sock->protocol, client->timeout_queue);
+ sock->protocol = NULL;
+ }
+ }
+
/* Free everything */
if (del && sock->user_data) {
/* XXX Free all client entries and channel entries. */
- client->ops->say(client, sock->user_data,
- "Closed connection to host %s", sock->hostname);
-
/* Clear ID caches */
- silc_idcache_del_all(conn->client_cache);
- silc_idcache_del_all(conn->channel_cache);
+ if (conn->client_cache)
+ silc_idcache_del_all(conn->client_cache);
+ if (conn->channel_cache)
+ silc_idcache_del_all(conn->channel_cache);
/* Free data */
if (conn->remote_host)
if (conn->rekey)
silc_free(conn->rekey);
- conn->sock = NULL;
- conn->remote_port = 0;
- conn->remote_type = 0;
- conn->send_key = NULL;
- conn->receive_key = NULL;
- conn->hmac_send = NULL;
- conn->hmac_receive = NULL;
- conn->local_id = NULL;
- conn->local_id_data = NULL;
- conn->remote_host = NULL;
- conn->current_channel = NULL;
- conn->pending_commands = NULL;
- conn->rekey = NULL;
-
+ memset(conn, 0, sizeof(*conn));
silc_client_del_connection(client, conn);
}
- if (sock->protocol) {
- silc_protocol_free(sock->protocol);
- sock->protocol = NULL;
- }
silc_socket_free(sock);
}
silc_idcache_list_free(list);
}
-/* Parses mode mask and returns the mode as string. */
-
-char *silc_client_chmode(uint32 mode, SilcChannelEntry channel)
-{
- char string[100];
-
- if (!mode)
- return NULL;
-
- memset(string, 0, sizeof(string));
-
- if (mode & SILC_CHANNEL_MODE_PRIVATE)
- strncat(string, "p", 1);
-
- if (mode & SILC_CHANNEL_MODE_SECRET)
- strncat(string, "s", 1);
-
- if (mode & SILC_CHANNEL_MODE_PRIVKEY)
- strncat(string, "k", 1);
-
- if (mode & SILC_CHANNEL_MODE_INVITE)
- strncat(string, "i", 1);
-
- if (mode & SILC_CHANNEL_MODE_TOPIC)
- strncat(string, "t", 1);
-
- if (mode & SILC_CHANNEL_MODE_ULIMIT)
- strncat(string, "l", 1);
-
- if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
- strncat(string, "a", 1);
-
- if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
- strncat(string, "f", 1);
-
- if (mode & SILC_CHANNEL_MODE_CIPHER) {
- char cipher[30];
- memset(cipher, 0, sizeof(cipher));
- snprintf(cipher, sizeof(cipher), " c (%s)",
- channel->channel_key->cipher->name);
- strncat(string, cipher, strlen(cipher));
- }
-
- if (mode & SILC_CHANNEL_MODE_HMAC) {
- char hmac[30];
- memset(hmac, 0, sizeof(hmac));
- snprintf(hmac, sizeof(hmac), " h (%s)",
- channel->hmac->hmac->name);
- strncat(string, hmac, strlen(hmac));
- }
-
- /* Rest of mode is ignored */
-
- return strdup(string);
-}
-
-/* Parses channel user mode mask and returns te mode as string */
-
-char *silc_client_chumode(uint32 mode)
-{
- char string[4];
-
- if (!mode)
- return NULL;
-
- memset(string, 0, sizeof(string));
-
- if (mode & SILC_CHANNEL_UMODE_CHANFO)
- strncat(string, "f", 1);
-
- if (mode & SILC_CHANNEL_UMODE_CHANOP)
- strncat(string, "o", 1);
-
- return strdup(string);
-}
-
-/* Parses channel user mode and returns it as special mode character. */
-
-char *silc_client_chumode_char(uint32 mode)
-{
- char string[4];
-
- if (!mode)
- return NULL;
-
- memset(string, 0, sizeof(string));
-
- if (mode & SILC_CHANNEL_UMODE_CHANFO)
- strncat(string, "*", 1);
-
- if (mode & SILC_CHANNEL_UMODE_CHANOP)
- strncat(string, "@", 1);
-
- return strdup(string);
-}
-
/* Registers failure timeout to process the received failure packet
with timeout. */
sock->protocol = protocol;
/* Run the protocol */
- protocol->execute(client->timeout_queue, 0, protocol,
- sock->sock, 0, 0);
+ silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
/* Re-register re-key timeout */
silc_task_register(client->timeout_queue, sock->sock,
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
/* Error occured during protocol */
- silc_protocol_cancel(client->timeout_queue, protocol);
+ silc_protocol_cancel(protocol, client->timeout_queue);
silc_protocol_free(protocol);
sock->protocol = NULL;
if (ctx->packet)