client = (SilcClientEntry)id_cache->context;
/* If client is not registered, is not originated from `router'
- or is not owned by `entry', skip it. */
+ and is not owned by `entry', skip it. */
if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
client->router != router ||
(router != entry && !SILC_ID_COMPARE(client->id, entry->id,
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
} else {
+ silc_idlist_del_data(client);
silc_idlist_del_client(server->local_list, client);
}
client = (SilcClientEntry)id_cache->context;
/* If client is not registered, is not originated from `router'
- or is not owned by `entry', skip it. */
+ and is not owned by `entry', skip it. */
if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
client->router != router ||
(router != entry && !SILC_ID_COMPARE(client->id, entry->id,
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
} else {
+ silc_idlist_del_data(client);
silc_idlist_del_client(server->global_list, client);
}
silc_idcache_list_free(list);
}
+ /* Return now if we are shutting down */
+ if (server->server_shutdown) {
+ silc_hash_table_free(channels);
+
+ if (server_signoff) {
+ for (i = 0; i < argc; i++)
+ silc_free(argv[i]);
+ silc_free(argv);
+ silc_free(argv_lens);
+ silc_free(argv_types);
+ silc_hash_table_free(clients);
+ }
+ return TRUE;
+ }
+
/* Send the SERVER_SIGNOFF notify */
if (server_signoff) {
SilcBuffer args, not;
SILC_PACKET_NOTIFY, 0, FALSE,
not->data, not->len, FALSE);
+ /* Send notify also to local backup routers */
+ silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
+ not->data, not->len, FALSE, TRUE);
+
silc_buffer_free(args);
silc_buffer_free(not);
for (i = 0; i < argc; i++)
silc_hash_table_free(clients);
}
- /* Return now if we are shutting down */
- if (server->server_shutdown) {
- silc_hash_table_free(channels);
- return TRUE;
- }
-
/* We must now re-generate the channel key for all channels that had
this server's client(s) on the channel. As they left the channel we
must re-generate the channel key. */
}
/* Do not send the channel key if private channel key mode is set */
- if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
+ if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->channel_key)
continue;
silc_server_send_channel_key(server, NULL, channel,
static SilcServerEntry
silc_server_update_clients_by_real_server(SilcServer server,
SilcServerEntry from,
+ SilcServerEntry to,
SilcClientEntry client,
bool local,
SilcIDCacheEntry client_cache)
SilcServerEntry server_entry;
SilcIDCacheEntry id_cache = NULL;
SilcIDCacheList list;
+ bool tolocal = (to == server->id_entry);
if (!silc_idcache_get_all(server->local_list->servers, &list))
return NULL;
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
if (server_entry != from &&
+ (tolocal || server_entry != server->id_entry) &&
SILC_ID_COMPARE(server_entry->id, client->id,
client->id->ip.data_len)) {
SILC_LOG_DEBUG(("Found (local) %s",
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (server_entry != from &&
+ if (server_entry != from && server_entry != server->id_entry &&
+ (tolocal || server_entry != server->id_entry) &&
SILC_ID_COMPARE(server_entry->id, client->id,
client->id->ip.data_len)) {
SILC_LOG_DEBUG(("Found (global) %s",
if (local) {
SILC_LOG_DEBUG(("Moving client to global list"));
silc_idcache_add(server->global_list->clients, client_cache->name,
- client_cache->id, client_cache->context,
- client_cache->expire, NULL);
+ client_cache->id, client_cache->context, 0, NULL);
silc_idcache_del_by_context(server->local_list->clients, client);
}
server_entry = server_entry->router;
if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
SILC_LOG_DEBUG(("Moving client to global list"));
silc_idcache_add(server->global_list->clients, client_cache->name,
- client_cache->id, client_cache->context,
- client_cache->expire, NULL);
+ client_cache->id, client_cache->context, 0, NULL);
silc_idcache_del_by_context(server->local_list->clients, client);
}
}
if (client->router == from) {
if (resolve_real_server) {
client->router =
- silc_server_update_clients_by_real_server(server, from, client,
- local, id_cache);
+ silc_server_update_clients_by_real_server(server, from, to,
+ client, local,
+ id_cache);
if (!client->router) {
if (server->server_type == SILC_ROUTER)
client->router = from;
if (client->router)
SILC_LOG_DEBUG(("Client changed to %s",
- silc_id_render(client->router->id, SILC_ID_CLIENT)));
+ silc_id_render(client->router->id, SILC_ID_SERVER)));
if (!silc_idcache_list_next(list, &id_cache))
break;
if (client->router == from) {
if (resolve_real_server) {
client->router =
- silc_server_update_clients_by_real_server(server, from, client,
- local, id_cache);
+ silc_server_update_clients_by_real_server(server, from, to,
+ client, local,
+ id_cache);
if (!client->router)
client->router = from;
} else {
if (client->router)
SILC_LOG_DEBUG(("Client changed to %s",
- silc_id_render(client->router->id, SILC_ID_CLIENT)));
+ silc_id_render(client->router->id, SILC_ID_SERVER)));
if (!silc_idcache_list_next(list, &id_cache))
break;
silc_hash_table_list(channel->user_list, &htl);
while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
- if (!chl->client->router) {
+ if (SILC_IS_LOCAL(chl->client)) {
silc_hash_table_list_reset(&htl);
return TRUE;
}
int i, count;
for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
- if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
+ if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
+ !strcmp(server->sockets[i]->ip, ip) &&
server->sockets[i]->type == type)
count++;
}
return 0;
for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
- if (server->sockets[i] &&
+ if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
((ip && !strcmp(server->sockets[i]->ip, ip)) ||
(hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
server->sockets[i]->port == port &&
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your connection is secured with %s cipher, "
"key length %d bits",
- idata->send_key->cipher->name,
- idata->send_key->cipher->key_len));
+ silc_cipher_get_name(idata->send_key),
+ silc_cipher_get_key_len(idata->send_key)));
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your current nickname is %s",
client->nickname));
}
/* Remove remote client */
+ silc_idlist_del_data(remote_client);
if (!silc_idlist_del_client(server->global_list, remote_client)) {
/* Remove this client from watcher list if it is */
silc_server_del_from_watcher_list(server, remote_client);
SilcClientEntry entry = context;
SilcSocketConnection sock;
+ if (!context)
+ return;
+
if (entry == notify->client)
return;