static SilcServerEntry
silc_server_update_clients_by_real_server(SilcServer server,
- SilcClientEntry client)
+ SilcServerEntry from,
+ SilcClientEntry client,
+ bool local,
+ SilcIDCacheEntry client_cache)
{
SilcServerEntry server_entry;
SilcIDCacheEntry id_cache = NULL;
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (SILC_ID_COMPARE(server_entry->id, client->id,
+ if (server_entry != from &&
+ SILC_ID_COMPARE(server_entry->id, client->id,
+ client->id->ip.data_len)) {
+ SILC_LOG_DEBUG(("Found (local) %s",
+ silc_id_render(server_entry->id, SILC_ID_SERVER)));
+
+ /* If the client is not marked as local then move it to local list
+ since the server is local. */
+ if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
+ SILC_LOG_DEBUG(("Moving client to local list"));
+ silc_idcache_add(server->local_list->clients, client_cache->name,
+ client_cache->id, client_cache->context,
+ client_cache->expire);
+ silc_idcache_del_by_context(server->global_list->clients, client);
+ }
+
+ silc_idcache_list_free(list);
+ return server_entry;
+ }
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+
+ silc_idcache_list_free(list);
+
+ if (!silc_idcache_get_all(server->global_list->servers, &list))
+ return NULL;
+
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ if (server_entry != from &&
+ SILC_ID_COMPARE(server_entry->id, client->id,
client->id->ip.data_len)) {
- SILC_LOG_DEBUG(("Found"));
+ SILC_LOG_DEBUG(("Found (global) %s",
+ silc_id_render(server_entry->id, SILC_ID_SERVER)));
+
+ /* If the client is marked as local then move it to global list
+ since the server is global. */
+ 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);
+ silc_idcache_del_by_context(server->local_list->clients, client);
+ }
+
silc_idcache_list_free(list);
return server_entry;
}
`from' and which are originated from a server that we have connection
to, when we've acting as backup router. If it is FALSE the `to' will
be the new source. This function also removes the clients that are
- *really* originated from `from'. These are clients that the `from'
- owns, and not just clients that are behind the `from'. */
+ *really* originated from `from' if `remove_from' is TRUE. These are
+ clients that the `from' owns, and not just clients that are behind
+ the `from'. */
void silc_server_update_clients_by_server(SilcServer server,
SilcServerEntry from,
SilcServerEntry to,
- bool resolve_real_server)
+ bool resolve_real_server,
+ bool remove_from)
{
SilcIDCacheList list = NULL;
SilcIDCacheEntry id_cache = NULL;
SilcClientEntry client = NULL;
+ bool local;
SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
+ SILC_ID_SERVER)));
+ SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
+ SILC_ID_SERVER)));
+
+
+ local = TRUE;
if (silc_idcache_get_all(server->local_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
+
if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
if (!silc_idcache_list_next(list, &id_cache))
break;
continue;
}
+ SILC_LOG_DEBUG(("Client (local) %s",
+ silc_id_render(client->id, SILC_ID_CLIENT)));
+
if (client->router == from) {
/* Skip clients that are *really* owned by the `from' */
- if (SILC_ID_COMPARE(from->id, client->id,
- client->id->ip.data_len)) {
- SILC_LOG_DEBUG(("Found really owned client, will remove it"));
+ if (remove_from && SILC_ID_COMPARE(from->id, client->id,
+ client->id->ip.data_len)) {
+ SILC_LOG_DEBUG(("Found really owned client, skip it"));
if (!silc_idcache_list_next(list, &id_cache))
break;
else
if (resolve_real_server) {
client->router =
- silc_server_update_clients_by_real_server(server, client);
+ silc_server_update_clients_by_real_server(server, from, client,
+ local, id_cache);
if (!client->router)
- client->router = to;
+ client->router = from; /* on local list put old from */
} else {
client->router = to;
}
silc_idcache_list_free(list);
}
+ local = FALSE;
if (silc_idcache_get_all(server->global_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
+
+
if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
if (!silc_idcache_list_next(list, &id_cache))
break;
continue;
}
+ SILC_LOG_DEBUG(("Client (global) %s",
+ silc_id_render(client->id, SILC_ID_CLIENT)));
+
if (client->router == from) {
/* Skip clients that are *really* owned by the `from' */
- if (SILC_ID_COMPARE(from->id, client->id,
- client->id->ip.data_len)) {
- SILC_LOG_DEBUG(("Found really owned client, will remove it"));
+ if (remove_from && SILC_ID_COMPARE(from->id, client->id,
+ client->id->ip.data_len)) {
+ SILC_LOG_DEBUG(("Found really owned client, skip it"));
if (!silc_idcache_list_next(list, &id_cache))
break;
else
if (resolve_real_server) {
client->router =
- silc_server_update_clients_by_real_server(server, client);
+ silc_server_update_clients_by_real_server(server, from, client,
+ local, id_cache);
if (!client->router)
client->router = to;
} else {
silc_idcache_list_free(list);
}
- /* Now remove the clients that are still marked as orignated from the
- `from'. These are the clients that really was owned by the `from' and
- not just exist behind the `from'. */
- silc_server_remove_clients_by_server(server, from, TRUE);
+ if (remove_from)
+ /* Now remove the clients that are still marked as orignated from the
+ `from'. These are the clients that really was owned by the `from' and
+ not just exist behind the `from'. */
+ silc_server_remove_clients_by_server(server, from, TRUE);
}
/* Checks whether given channel has global users. If it does this returns