/* Set the HMAC key out of current channel key. The client must do
this locally. */
- silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
+ silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
+ channel->key_len / 8,
hash);
silc_hmac_set_key(channel->hmac, hash,
- silc_hash_len(channel->hmac->hash));
+ silc_hash_len(silc_hmac_get_hash(channel->hmac)));
memset(hash, 0, sizeof(hash));
}
SilcChannelID *id = NULL;
void *sender = NULL;
void *sender_entry = NULL;
+ bool local = TRUE;
SILC_LOG_DEBUG(("Processing channel message"));
if (packet->src_id_type == SILC_ID_CLIENT) {
sender_entry = silc_idlist_find_client_by_id(server->local_list,
sender, TRUE, NULL);
- if (!sender_entry)
+ if (!sender_entry) {
+ local = FALSE;
sender_entry = silc_idlist_find_client_by_id(server->global_list,
sender, TRUE, NULL);
+ }
if (!sender_entry || !silc_server_client_on_channel(sender_entry,
channel)) {
SILC_LOG_DEBUG(("Client not on channel"));
goto out;
}
+
+ /* If the packet is coming from router, but the client entry is
+ local entry to us then some router is rerouting this to us and it is
+ not allowed. */
+ if (server->server_type == SILC_ROUTER &&
+ sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
+ SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
+ goto out;
+ }
}
/* Distribute the packet to our local clients. This will send the
SilcPacketContext *packet)
{
SilcBuffer buffer = packet->buffer;
- SilcServerEntry new_server;
+ SilcServerEntry new_server, server_entry;
SilcServerID *server_id;
SilcIDListData idata;
unsigned char *server_name, *id_string;
uint16 id_len, name_len;
int ret;
+ bool local = TRUE;
SILC_LOG_DEBUG(("Creating new server"));
idata = (SilcIDListData)new_server;
/* Remove the old cache entry */
- silc_idcache_del_by_context(server->local_list->servers, new_server);
+ if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
+ silc_idcache_del_by_context(server->global_list->servers, new_server);
+ local = FALSE;
+ }
/* Parse the incoming packet */
ret = silc_buffer_unformat(buffer,
}
silc_free(id_string);
+ /* Check that we do not have this ID already */
+ 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);
+ } 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);
+ }
+
/* 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)));
/* Add again the entry to the ID cache. */
- silc_idcache_add(server->local_list->servers, server_name, server_id,
+ silc_idcache_add(local ? server->local_list->servers :
+ server->global_list->servers, server_name, server_id,
new_server, FALSE);
/* Distribute the information about new server in the SILC network
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
- /* Mark the server disabled. The data sent earlier will go but nothing
+ /* Mark the router disabled. The data sent earlier will go but nothing
after this does not go to this connection. */
idata->status |= SILC_IDLIST_STATUS_DISABLED;
+ } else {
+ /* If it is router announce our stuff to it. */
+ if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
+ server->server_type == SILC_ROUTER) {
+ silc_server_announce_servers(server, FALSE, 0, sock);
+ silc_server_announce_clients(server, 0, sock);
+ silc_server_announce_channels(server, 0, sock);
+ }
}
return new_server;
{
SilcBuffer buffer = packet->buffer;
SilcIDList id_list;
- SilcServerEntry router;
+ SilcServerEntry router, server_entry;
SilcSocketConnection router_sock;
SilcIDPayload idp;
SilcIdType id_type;
id_type = silc_id_payload_get_type(idp);
/* Normal server cannot have other normal server connections */
- if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
+ server_entry = (SilcServerEntry)sock->user_data;
+ if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
+ server_entry->server_type == SILC_SERVER)
goto out;
id = silc_id_payload_get_id(idp);
if (!id)
goto out;
- if (sock->type == SILC_SOCKET_TYPE_SERVER)
- id_list = server->local_list;
- else
- id_list = server->global_list;
-
/* If the packet is coming from server then use the sender as the
origin of the the packet. If it came from router then check the real
sender of the packet and use that as the origin. */
if (sock->type == SILC_SOCKET_TYPE_SERVER) {
+ id_list = server->local_list;
router_sock = sock;
router = sock->user_data;
+
+ /* If the sender is backup router and ID is server (and we are not
+ backup router) then switch the entry to global list. */
+ if (server_entry->server_type == SILC_BACKUP_ROUTER &&
+ id_type == SILC_ID_SERVER &&
+ server->id_entry->server_type != SILC_BACKUP_ROUTER) {
+ id_list = server->global_list;
+ router_sock = server->router ? server->router->connection : sock;
+ }
} else {
void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
if (!router)
goto out;
router_sock = sock;
+ id_list = server->global_list;
}
switch(id_type) {