SILC_TASK_CALLBACK(silc_server_rehash_close_connection);
SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
SILC_TASK_CALLBACK(silc_server_connect_router);
-SILC_TASK_CALLBACK(silc_server_connect_to_router);
SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
SILC_TASK_CALLBACK(silc_server_accept_new_connection);
SILC_TASK_CALLBACK(silc_server_free_client_data_timeout);
SILC_TASK_CALLBACK(silc_server_timeout_remote);
SILC_TASK_CALLBACK(silc_server_channel_key_rekey);
-SILC_TASK_CALLBACK(silc_server_failure_callback);
-SILC_TASK_CALLBACK(silc_server_rekey_callback);
SILC_TASK_CALLBACK(silc_server_get_stats);
/* Allocates a new SILC server object. This has to be done before the server
#ifdef SILC_SIM
{
SilcSim sim;
-
+ silc_dlist_start(server->sim);
while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
silc_dlist_del(server->sim, sim);
+ silc_sim_close(sim);
silc_sim_free(sim);
}
silc_dlist_uninit(server->sim);
/* If we are normal server we'll retrieve network statisticial information
once in a while from the router. */
- if (server->server_type == SILC_SERVER)
+ if (server->server_type != SILC_ROUTER)
silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
server, 10, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_LOW);
silc_server_connect_to_router_retry,
context, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
- else
+ else {
silc_server_config_unref(&sconn->conn);
+ silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
+ silc_free(sconn);
+ }
return;
}
server to do authentication and key exchange with our router - called
from schedule. */
-SILC_TASK_CALLBACK(silc_server_connect_to_router)
+SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router)
{
SilcServer server = (SilcServer)context;
SilcServerConnection sconn;
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
silc_free(sconn->remote_host);
silc_free(sconn->backup_replace_ip);
silc_free(sconn);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
return;
if (conn && conn->param)
param = conn->param;
- /* Perform keepalive. The `hb_context' will be freed automatically
- when finally calling the silc_socket_free function. */
+ /* Perform keepalive. */
silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
silc_server_perform_heartbeat,
server->schedule);
/* If we are backup router then this primary router is whom we are
backing up. */
if (server->server_type == SILC_BACKUP_ROUTER)
- silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
+ silc_server_backup_add(server, server->id_entry, sock->ip,
+ sconn->remote_port, TRUE);
}
} else {
/* Add this server to be our backup router */
silc_server_config_unref(&ctx->sconfig);
silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
NULL);
silc_server_config_unref(&ctx->sconfig);
silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
server->stat.auth_failures++;
SilcSocketConnection sock = ctx->sock;
SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
void *id_entry;
- SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
+ SilcServerConfigConnParams *param = &server->config->param;
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
silc_server_config_unref(&ctx->sconfig);
silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
NULL);
server->stat.auth_failures++;
/* Get connection parameters */
if (conn->param) {
- if (conn->param->keepalive_secs)
- hearbeat_timeout = conn->param->keepalive_secs;
+ param = conn->param;
+
+ if (!param->keepalive_secs)
+ param->keepalive_secs = server->config->param.keepalive_secs;
+
+ if (!param->qos && server->config->param.qos) {
+ param->qos = server->config->param.qos;
+ param->qos_rate_limit = server->config->param.qos_rate_limit;
+ param->qos_bytes_limit = server->config->param.qos_bytes_limit;
+ param->qos_limit_sec = server->config->param.qos_limit_sec;
+ param->qos_limit_usec = server->config->param.qos_limit_usec;
+ }
/* Check if to be anonymous connection */
- if (conn->param->anonymous)
+ if (param->anonymous)
client->mode |= SILC_UMODE_ANONYMOUS;
}
if (rconn) {
if (rconn->param) {
- if (rconn->param->keepalive_secs)
- hearbeat_timeout = rconn->param->keepalive_secs;
+ param = rconn->param;
+
+ if (!param->keepalive_secs)
+ param->keepalive_secs = server->config->param.keepalive_secs;
+
+ if (!param->qos && server->config->param.qos) {
+ param->qos = server->config->param.qos;
+ param->qos_rate_limit = server->config->param.qos_rate_limit;
+ param->qos_bytes_limit = server->config->param.qos_bytes_limit;
+ param->qos_limit_sec = server->config->param.qos_limit_sec;
+ param->qos_limit_usec = server->config->param.qos_limit_usec;
+ }
}
initiator = rconn->initiator;
}
if (sconn) {
if (sconn->param) {
- if (sconn->param->keepalive_secs)
- hearbeat_timeout = sconn->param->keepalive_secs;
+ param = sconn->param;
+
+ if (!param->keepalive_secs)
+ param->keepalive_secs = server->config->param.keepalive_secs;
+
+ if (!param->qos && server->config->param.qos) {
+ param->qos = server->config->param.qos;
+ param->qos_rate_limit = server->config->param.qos_rate_limit;
+ param->qos_bytes_limit = server->config->param.qos_bytes_limit;
+ param->qos_limit_sec = server->config->param.qos_limit_sec;
+ param->qos_limit_usec = server->config->param.qos_limit_usec;
+ }
}
backup_router = sconn->backup_router;
ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
new_server->server_type = SILC_BACKUP_ROUTER;
+ SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
+ ("Backup router %s is now online",
+ sock->hostname));
+
/* Remove the backup waiting with timeout */
silc_schedule_task_add(server->schedule, 0,
silc_server_backup_router_wait,
/* Connection has been fully established now. Everything is ok. */
SILC_LOG_DEBUG(("New connection authenticated"));
- /* Perform keepalive. The `hb_context' will be freed automatically
- when finally calling the silc_socket_free function. */
- silc_socket_set_heartbeat(sock, hearbeat_timeout, server,
- silc_server_perform_heartbeat,
- server->schedule);
+ /* Perform keepalive. */
+ if (param->keepalive_secs)
+ silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
+ silc_server_perform_heartbeat,
+ server->schedule);
+
+ /* Perform Quality of Service */
+ if (param->qos)
+ silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
+ param->qos_limit_sec, param->qos_limit_usec,
+ server->schedule);
out:
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
silc_protocol_free(protocol);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
SilcCipher cipher = NULL;
SilcHmac hmac = NULL;
SilcUInt32 sequence = 0;
+ bool local_is_router;
int ret;
if (!sock) {
if (ret == -2)
return;
+ /* The packet has been sent and now it is time to set the connection
+ 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_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
+ SILC_UNSET_OUTBUF_PENDING(sock);
+ silc_buffer_clear(sock->outbuf);
+
if (ret == -1) {
SILC_LOG_ERROR(("Error sending packet to connection "
"%s:%d [%s]", sock->hostname, sock->port,
sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
"Router")));
- return;
- }
-
- /* The packet has been sent and now it is time to set the connection
- 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_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
- SILC_UNSET_OUTBUF_PENDING(sock);
- silc_buffer_clear(sock->outbuf);
+ SILC_SET_DISCONNECTING(sock);
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_server_close_connection(server, sock);
+ }
return;
}
ret = silc_packet_receive(sock);
if (ret < 0) {
- if (ret == -1)
+ if (ret == -1) {
SILC_LOG_ERROR(("Error receiving packet from connection "
"%s:%d [%s] %s", sock->hostname, sock->port,
(sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
"Router"), strerror(errno)));
+
+ SILC_SET_DISCONNECTING(sock);
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_server_close_connection(server, sock);
+ }
return;
}
else
silc_server_free_sock_user_data(server, sock, NULL);
} else if (server->router_conn && server->router_conn->sock == sock &&
- !server->router && server->standalone)
+ !server->router && server->standalone)
silc_schedule_task_add(server->schedule, 0,
silc_server_connect_to_router,
server, 1, 0,
sequence = idata->psn_receive;
}
- /* Process the packet. This will call the parser that will then
+ /* Then, process the packet. This will call the parser that will then
decrypt and parse the packet. */
- ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, cipher, hmac, sequence,
+
+ local_is_router = (server->server_type == SILC_ROUTER);
+
+ /* If socket connection is our primary, we are backup and we are doing
+ backup resuming, we won't process the packet as being a router
+ (affects channel message decryption). */
+ if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+ SILC_PRIMARY_ROUTE(server) == sock)
+ local_is_router = FALSE;
+
+ ret = silc_packet_receive_process(sock, local_is_router,
+ cipher, hmac, sequence,
silc_server_packet_parse, server);
- /* If this socket connection is not authenticated yet and the packet
- processing failed we will drop the connection since it can be
- a malicious flooder. */
- if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
- (!sock->protocol || sock->protocol->protocol->type ==
- SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
- SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
- SILC_SET_DISCONNECTING(sock);
+ /* If processing failed the connection is closed. */
+ if (!ret) {
+ /* On packet processing errors we may close our primary router
+ connection but won't become primary router if we are the backup
+ since this is local error condition. */
+ if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
+ server->backup_noswitch = TRUE;
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
SilcServer server = (SilcServer)context;
SilcSocketConnection sock = parser_context->sock;
SilcIDListData idata = (SilcIDListData)sock->user_data;
+ bool ret;
if (idata)
idata->psn_receive = parser_context->packet->sequence + 1;
the idata->receive_key might have become valid in the last packet
and we want to call this processor with valid cipher. */
if (idata)
- silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, idata->receive_key,
+ ret = silc_packet_receive_process(
+ sock, server->server_type == SILC_ROUTER,
+ idata->receive_key,
idata->hmac_receive, idata->psn_receive,
silc_server_packet_parse, server);
else
- silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, NULL, NULL, 0,
+ ret = silc_packet_receive_process(
+ sock, server->server_type == SILC_ROUTER,
+ NULL, NULL, 0,
silc_server_packet_parse, server);
+
+ if (!ret) {
+ /* On packet processing errors we may close our primary router
+ connection but won't become primary router if we are the backup
+ since this is local error condition. */
+ if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
+ server->backup_noswitch = TRUE;
+
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_server_close_connection(server, sock);
+ }
+
return FALSE;
}
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
if (sock->protocol) {
- SilcServerFailureContext f;
- f = silc_calloc(1, sizeof(*f));
- f->sock = silc_socket_dup(sock);
-
- /* We will wait 5 seconds to process this failure packet */
- silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_failure_callback, (void *)f, 5, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+ sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
+ silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
}
break;
char tmp[128];
if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) {
- silc_schedule_task_add(server->schedule, 0,
+ silc_schedule_unset_listen_fd(server->schedule, sock->sock);
+ silc_schedule_task_del_by_fd(server->schedule, sock->sock);
+ silc_schedule_task_add(server->schedule, sock->sock,
silc_server_close_connection_final,
(void *)sock, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
"Router"), tmp[0] ? tmp : ""));
- /* We won't listen for this connection anymore */
- silc_schedule_unset_listen_fd(server->schedule, sock->sock);
-
/* Unregister all tasks */
silc_schedule_task_del_by_fd(server->schedule, sock->sock);
if (!sock->user_data) {
/* If any protocol is active cancel its execution. It will call
the final callback which will finalize the disconnection. */
- if (sock->protocol) {
+ if (sock->protocol && sock->protocol->protocol &&
+ sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
silc_protocol_cancel(sock->protocol, server->schedule);
sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
}
}
- silc_schedule_task_add(server->schedule, 0,
+ /* We won't listen for this connection anymore */
+ silc_schedule_unset_listen_fd(server->schedule, sock->sock);
+
+ silc_schedule_task_add(server->schedule, sock->sock,
silc_server_close_connection_final,
(void *)sock, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
char *cp;
int len;
- if (!sock)
+ if (!sock || SILC_IS_DISCONNECTED(sock))
return;
memset(buf, 0, sizeof(buf));
/* Remove client from all channels */
if (notify)
silc_server_remove_from_channels(server, NULL, client,
- TRUE, (char *)signoff, TRUE);
+ TRUE, (char *)signoff, TRUE, FALSE);
else
silc_server_remove_from_channels(server, NULL, client,
- FALSE, NULL, FALSE);
+ FALSE, NULL, FALSE, FALSE);
/* Remove this client from watcher list if it is */
silc_server_del_from_watcher_list(server, client);
sock->type != SILC_SOCKET_TYPE_ROUTER)
backup_router = NULL;
- if (server->server_shutdown)
+ if (server->server_shutdown || server->backup_noswitch)
backup_router = NULL;
/* If this was our primary router connection then we're lost to
server->id_entry->router = NULL;
server->router = NULL;
server->standalone = TRUE;
+ server->backup_primary = FALSE;
backup_router = NULL;
} else {
if (server->id_entry != backup_router) {
} else if (backup_router) {
SILC_LOG_INFO(("Enabling the use of backup router %s",
backup_router->server_name));
- SILC_LOG_DEBUG(("Enabling the use of backup router %s",
- backup_router->server_name));
/* Mark this connection as replaced */
silc_server_backup_replaced_add(server, user_data->id,
backup_router);
+ } else if (server->server_type == SILC_SERVER &&
+ sock->type == SILC_SOCKET_TYPE_ROUTER) {
+ /* Reconnect to the router (backup) */
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_connect_to_router,
+ server, 1, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
+ SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
+ ("Server %s signoff", user_data->server_name));
+
if (!backup_router) {
/* Remove all servers that are originated from this server, and
remove the clients of those servers too. */
silc_server_remove_servers_by_server(server, user_data, TRUE);
+#if 0
/* Remove the clients that this server owns as they will become
invalid now too. For backup router the server is actually
coming from the primary router, so mark that as the owner
silc_server_remove_clients_by_server(server, server->router,
user_data, TRUE);
else
+#endif
silc_server_remove_clients_by_server(server, user_data,
user_data, TRUE);
server->server_name,
server->router->server_name));
}
+ server->backup_noswitch = FALSE;
/* Free the server entry */
silc_server_backup_del(server, user_data);
}
/* If any protocol is active cancel its execution */
- if (sock->protocol) {
+ if (sock->protocol && sock->protocol->protocol &&
+ sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
silc_protocol_cancel(sock->protocol, server->schedule);
sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
SilcClientEntry client,
bool notify,
const char *signoff_message,
- bool keygen)
+ bool keygen,
+ bool killed)
{
SilcChannelEntry channel;
SilcChannelClientEntry chl;
}
silc_hash_table_del(client->channels, channel);
- silc_hash_table_del(channel->user_list, chl->client);
+ silc_hash_table_del(channel->user_list, client);
channel->user_count--;
/* If there is no global users on the channel anymore mark the channel
chl->client->router && !silc_server_channel_has_global(channel))
channel->global_users = FALSE;
+ memset(chl, 'A', sizeof(*chl));
silc_free(chl);
/* Update statistics */
signoff_message, signoff_message ?
strlen(signoff_message) : 0);
+ if (killed && clidp) {
+ /* Remove the client from channel's invite list */
+ if (channel->invite_list &&
+ silc_hash_table_count(channel->invite_list)) {
+ SilcBuffer ab;
+ SilcArgumentPayload iargs;
+ ab = silc_argument_payload_encode_one(NULL, clidp->data,
+ clidp->len, 3);
+ iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
+ silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
+ silc_buffer_free(ab);
+ silc_argument_payload_free(iargs);
+ }
+ }
+
/* Don't create keys if we are shutting down */
if (server->server_shutdown)
continue;
return FALSE;
}
- silc_hash_table_del(client->channels, chl->channel);
- silc_hash_table_del(channel->user_list, chl->client);
+ silc_hash_table_del(client->channels, channel);
+ silc_hash_table_del(channel->user_list, client);
channel->user_count--;
/* If there is no global users on the channel anymore mark the channel
chl->client->router && !silc_server_channel_has_global(channel))
channel->global_users = FALSE;
+ memset(chl, 'O', sizeof(*chl));
silc_free(chl);
/* Update statistics */
/* If we have protocol active we must assure that we call the protocol's
final callback so that all the memory is freed. */
- if (sock->protocol) {
+ if (sock->protocol && sock->protocol->protocol &&
+ sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
protocol = sock->protocol->protocol->type;
silc_protocol_cancel(sock->protocol, server->schedule);
sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
return;
}
- if (sock->user_data)
- silc_server_free_sock_user_data(server, sock, NULL);
-
silc_server_disconnect_remote(server, sock,
protocol ==
SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
SILC_STATUS_ERR_AUTH_FAILED :
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
"Connection timeout");
+
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
}
/* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
SilcChannelClientEntry chl;
SilcHashTableList htl;
SilcBuffer chidp, clidp, csidp;
- SilcBuffer tmp;
+ SilcBuffer tmp, fkey = NULL;
int len;
- unsigned char mode[4], *fkey = NULL;
- SilcUInt32 fkey_len = 0;
+ unsigned char mode[4];
char *hmac;
SILC_LOG_DEBUG(("Start"));
SILC_PUT32_MSB(channel->mode, mode);
hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
if (channel->founder_key)
- fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+ fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
tmp =
silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
6, csidp->data, csidp->len,
channel->passphrase,
channel->passphrase ?
strlen(channel->passphrase) : 0,
- fkey, fkey_len);
+ fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
len = tmp->len;
*channel_modes =
silc_buffer_realloc(*channel_modes,
silc_buffer_put(*channel_modes, tmp->data, tmp->len);
silc_buffer_pull(*channel_modes, len);
silc_buffer_free(tmp);
- silc_free(fkey);
+ silc_buffer_free(fkey);
fkey = NULL;
- fkey_len = 0;
/* Now find all users on the channel */
silc_hash_table_list(channel->user_list, &htl);
/* CUMODE notify for mode change on the channel */
SILC_PUT32_MSB(chl->mode, mode);
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
- fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+ fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4, csidp->data, csidp->len,
mode, sizeof(mode),
clidp->data, clidp->len,
- fkey, fkey_len);
+ fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
len = tmp->len;
*channel_users_modes =
silc_buffer_realloc(*channel_users_modes,
silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
silc_buffer_pull(*channel_users_modes, len);
silc_buffer_free(tmp);
- silc_free(fkey);
+ silc_buffer_free(fkey);
fkey = NULL;
- fkey_len = 0;
silc_buffer_free(clidp);
}
silc_hash_table_list_reset(&htl);
silc_server_announce_get_channel_topic(server, channel,
&(*channel_topics)[i]);
(*channel_users_modes_c)++;
+
+ silc_free(cid);
+
i++;
}
silc_free(channel_ids);
}
-/* Failure timeout callback. If this is called then we will immediately
- process the received failure. We always process the failure with timeout
- since we do not want to blindly trust to received failure packets.
- This won't be called (the timeout is cancelled) if the failure was
- bogus (it is bogus if remote does not close the connection after sending
- the failure). */
-
-SILC_TASK_CALLBACK(silc_server_failure_callback)
-{
- SilcServer server = app_context;
- SilcServerFailureContext f = (SilcServerFailureContext)context;
-
- if (f->sock->protocol) {
- f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
- silc_protocol_execute(f->sock->protocol, server->schedule, 0, 0);
- }
-
- silc_socket_free(f->sock);
- silc_free(f);
-}
-
/* Assembles user list and users mode list from the `channel'. */
bool silc_server_get_users_on_channel(SilcServer server,
/* A timeout callback for the re-key. We will be the initiator of the
re-key protocol. */
-SILC_TASK_CALLBACK(silc_server_rekey_callback)
+SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback)
{
SilcServer server = app_context;
SilcSocketConnection sock = (SilcSocketConnection)context;
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
/* Error occured during protocol */
- SILC_LOG_ERROR(("Error occurred during rekey protocol"));
+ SILC_LOG_ERROR(("Error occurred during rekey protocol with
+ %s (%s)", sock->hostname, sock->ip));
silc_protocol_cancel(protocol, server->schedule);
silc_protocol_free(protocol);
sock->protocol = NULL;