if (dst_sock)
/* Relay the packet */
silc_server_relay_packet(server, dst_sock, idata->send_key,
- idata->hmac, packet, TRUE);
+ idata->hmac_receive, packet, TRUE);
}
/* If we are router and this packet is not already broadcast packet
if (tmp_len > 128)
tmp = NULL;
- /* Remove the client from all channels */
- silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
+ /* Remove the client from all channels. */
+ silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
client->data.registered = FALSE;
cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
-
-#if 0
- /* Remove the client entry */
- if (!silc_idlist_del_client(server->global_list, client))
- silc_idlist_del_client(server->local_list, client);
-#endif
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
/* Send the private message */
silc_server_send_private_message(server, dst_sock, idata->send_key,
- idata->hmac, packet);
+ idata->hmac_send, packet);
}
/* Received private message key packet.. This packet is never for us. It is to
/* Relay the packet */
silc_server_relay_packet(server, dst_sock, idata->send_key,
- idata->hmac, packet, FALSE);
+ idata->hmac_send, packet, FALSE);
}
/* Processes incoming command reply packet. The command reply packet may
idata = (SilcIDListData)client;
/* Encrypt packet */
- silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
+ silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
buffer->len);
/* Send the packet */
SilcChannelClientEntry chl;
SilcChannelID *id = NULL;
void *sender = NULL;
+ void *sender_entry = NULL;
SILC_LOG_DEBUG(("Processing channel message"));
packet->src_id_type);
if (!sender)
goto out;
- if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
- packet->src_id_type == SILC_ID_CLIENT) {
+ if (packet->src_id_type == SILC_ID_CLIENT) {
silc_list_start(channel->user_list);
while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
+ if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender)) {
+ sender_entry = chl->client;
break;
+ }
}
if (chl == SILC_LIST_END) {
SILC_LOG_DEBUG(("Client not on channel"));
}
}
- /* If we are router and the packet came from router and private key
- has not been set for the channel then we must encrypt the packet
- as it was decrypted with the session key shared between us and the
- router which sent it. This is so, because cells does not share the
- same channel key */
- if (server->server_type == SILC_ROUTER &&
- sock->type == SILC_SOCKET_TYPE_ROUTER &&
- !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
- SilcBuffer chp;
- uint32 iv_len, i;
- uint16 data_len, flags;
-
- iv_len = silc_cipher_get_block_len(channel->channel_key);
- if (channel->iv[0] == '\0')
- for (i = 0; i < iv_len; i++) channel->iv[i] =
- silc_rng_get_byte(server->rng);
- else
- silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
-
- /* Encode new payload. This encrypts it also. */
- SILC_GET16_MSB(flags, packet->buffer->data);
- SILC_GET16_MSB(data_len, packet->buffer->data + 2);
- chp = silc_channel_message_payload_encode(flags, data_len,
- packet->buffer->data + 4,
- iv_len, channel->iv,
- channel->channel_key,
- channel->hmac);
- silc_buffer_put(packet->buffer, chp->data, chp->len);
- silc_buffer_free(chp);
- }
-
/* Distribute the packet to our local clients. This will send the
packet for further routing as well, if needed. */
silc_server_packet_relay_to_channel(server, sock, channel, sender,
- packet->src_id_type,
+ packet->src_id_type, sender_entry,
packet->buffer->data,
packet->buffer->len, FALSE);
else
id_list = server->global_list;
- router_sock = sock;
- router = sock->user_data;
+ /* 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) {
+ router_sock = sock;
+ router = sock->user_data;
+ } else {
+ void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
+ packet->src_id_type);
+ router = silc_idlist_find_server_by_id(server->global_list,
+ sender_id, NULL);
+ if (!router)
+ router = silc_idlist_find_server_by_id(server->local_list,
+ sender_id, NULL);
+ silc_free(sender_id);
+ if (!router)
+ goto out;
+ router_sock = sock;
+ }
switch(id_type) {
case SILC_ID_CLIENT:
break;
case SILC_ID_SERVER:
+ /* If the ID is mine, ignore it. */
+ if (!SILC_ID_SERVER_COMPARE(id, server->id)) {
+ SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
+ break;
+ }
+
SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
silc_id_render(id, SILC_ID_SERVER),
sock->type == SILC_SOCKET_TYPE_SERVER ?
"Server" : "Router", sock->hostname));
-
+
/* As a router we keep information of all global information in our global
list. Cell wide information however is kept in the local list. */
silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
/* Relay the packet */
silc_server_relay_packet(server, dst_sock, idata->send_key,
- idata->hmac, packet, FALSE);
+ idata->hmac_send, packet, FALSE);
}
/* Received connection auth request packet that is used during connection
if (proto_ctx->pfs == FALSE)
/* Run the protocol */
- protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 1);
+ protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);
}