silc_schedule_task_del_by_context(server->schedule, client);
/* Remove the client from all channels. */
- silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
+ silc_server_remove_from_channels(server, NULL, client, TRUE,
+ tmp, FALSE, FALSE);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
goto out;
if (action == 0 && !channel->invite_list)
- channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr,
- NULL, NULL, NULL,
- NULL, NULL, TRUE);
+ channel->invite_list =
+ silc_hash_table_alloc(0, silc_hash_ptr,
+ NULL, NULL, NULL,
+ silc_server_inviteban_destruct, channel, TRUE);
/* Proces the invite action */
silc_server_inviteban_process(server, channel->invite_list, action,
/* Remove the client from all channels. */
silc_server_remove_from_channels(server, NULL, client,
- TRUE, NULL, FALSE);
+ TRUE, NULL, FALSE, FALSE);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
}
silc_free(server_id);
- /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
- if (SILC_IS_LOCAL(server_entry))
+ /* For local entrys SERVER_SIGNOFF is processed only on backup router.
+ It is possible that router sends server signoff for a server. If
+ backup router has it as local connection it will be closed. */
+ if (SILC_IS_LOCAL(server_entry)) {
+ if (server->server_type == SILC_BACKUP_ROUTER) {
+ sock = server_entry->connection;
+ SILC_LOG_DEBUG(("Closing connection %s after SERVER_SIGNOFF",
+ sock->hostname));
+ SILC_SET_DISCONNECTING(sock);
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_server_close_connection(server, sock);
+ }
+
break;
+ }
/* Remove all servers that are originated from this server, and
remove the clients of those servers too. */
/* Remove the client from all channels */
silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
- FALSE);
+ FALSE, TRUE);
/* Check if anyone is watching this nickname */
silc_server_check_watcher_list(server, client, NULL,
goto out;
if (action == 0 && !channel->ban_list)
- channel->ban_list = silc_hash_table_alloc(0, silc_hash_ptr,
- NULL, NULL, NULL,
- NULL, NULL, TRUE);
+ channel->ban_list =
+ silc_hash_table_alloc(0, silc_hash_ptr,
+ NULL, NULL, NULL,
+ silc_server_inviteban_destruct, channel, TRUE);
/* Proces the ban action */
silc_server_inviteban_process(server, channel->ban_list, action,
client_id, FALSE, NULL);
if (client) {
silc_server_remove_from_channels(server, NULL, client, TRUE,
- NULL, TRUE);
+ NULL, TRUE, FALSE);
silc_idlist_del_data(client);
silc_idlist_del_client(server->global_list, client);
}
/* Save the channel key */
channel = silc_server_save_channel_key(server, buffer, NULL);
- if (!channel)
+ if (!channel) {
+ SILC_LOG_ERROR(("Bad channel key from %s (%s)",
+ sock->hostname, sock->ip));
return;
-
+ }
+
/* Distribute the key to everybody who is on the channel. If we are router
we will also send it to locally connected servers. */
silc_server_send_channel_key(server, sock, channel, FALSE);
return NULL;
}
+ /* Make sure this client hasn't registered already */
+ if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ "Too many registrations");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ return NULL;
+ }
+
/* Parse incoming packet */
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING_ALLOC(&username,
local = FALSE;
}
+ /* Make sure this server hasn't registered already */
+ if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ "Too many registrations");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ return NULL;
+ }
+
/* Parse the incoming packet */
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
if (server_entry) {
- silc_idcache_del_by_context(server->local_list->servers, server_entry);
+ if (SILC_IS_LOCAL(server_entry)) {
+ silc_server_disconnect_remote(server, server_entry->connection,
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ "Too many registrations");
+ if (((SilcSocketConnection)server_entry->connection)->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ } else {
+ silc_idcache_del_by_context(server->local_list->servers, server_entry);
+ }
} else {
server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
- if (server_entry)
- silc_idcache_del_by_context(server->global_list->servers, server_entry);
+ if (server_entry) {
+ if (SILC_IS_LOCAL(server_entry)) {
+ silc_server_disconnect_remote(server, server_entry->connection,
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ "Too many registrations");
+ if (((SilcSocketConnection)server_entry->connection)->user_data)
+ silc_server_free_sock_user_data(server, server_entry->connection,
+ NULL);
+ } else {
+ silc_idcache_del_by_context(server->global_list->servers,
+ server_entry);
+ }
+ }
}
/* Update server entry */
idata->status |= SILC_IDLIST_STATUS_REGISTERED;
new_server->server_name = server_name;
new_server->id = server_id;
-
+
SILC_LOG_DEBUG(("New server id(%s)",
silc_id_render(server_id, SILC_ID_SERVER)));
server->stat.clients--;
if (server->stat.cell_clients)
server->stat.cell_clients--;
- silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
+ silc_server_remove_from_channels(server, NULL, client, FALSE,
+ NULL, FALSE, FALSE);
silc_server_del_from_watcher_list(server, client);
if (!silc_idlist_del_client(server->local_list, client))
silc_idlist_del_client(server->global_list, client);
}
silc_free(client_id);
- silc_idlist_del_data(detached_client);
}