unsigned char *data,
unsigned int data_len)
{
+ SilcUInt32 mac_len, iv_len;
+ unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
+
/* 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
same channel key. */
if (server->server_type == SILC_ROUTER &&
sock->type == SILC_SOCKET_TYPE_ROUTER &&
- !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
- channel->channel_key) {
- SilcUInt32 mac_len = silc_hmac_len(channel->hmac);
- SilcUInt32 iv_len = silc_cipher_get_block_len(channel->channel_key);
- unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
+ !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
+
+ /* If we are backup router and remote is our primary router and
+ we are currently doing backup resuming protocol we must not
+ re-encrypt message with session key. */
+ if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+ SILC_PRIMARY_ROUTE(server) == sock)
+ return TRUE;
+
+ mac_len = silc_hmac_len(channel->hmac);
+ iv_len = silc_cipher_get_block_len(channel->channel_key);
if (data_len <= mac_len + iv_len) {
SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
SilcCipher cipher = NULL;
SilcHmac hmac = NULL;
SilcUInt32 sequence = 0;
+ bool local_is_router;
int ret;
if (!sock) {
sequence = idata->psn_receive;
}
- /* Process the packet. This will call the parser that will then
+ /* Then, process the packet. This will call the parser that will then
decrypt and parse the packet. */
- ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, cipher, hmac, sequence,
+
+ local_is_router = (server->server_type == SILC_ROUTER);
+
+ /* If socket connection is our primary, we are backup and we are doing
+ backup resuming, we won't process the packet as being a router
+ (affects channel message decryption). */
+ if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+ SILC_PRIMARY_ROUTE(server) == sock)
+ local_is_router = FALSE;
+
+ ret = silc_packet_receive_process(sock, local_is_router,
+ cipher, hmac, sequence,
silc_server_packet_parse, server);
/* If processing failed the connection is closed. */
and we want to call this processor with valid cipher. */
if (idata)
ret = silc_packet_receive_process(
- sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, idata->receive_key,
+ sock, server->server_type == SILC_ROUTER,
+ idata->receive_key,
idata->hmac_receive, idata->psn_receive,
silc_server_packet_parse, server);
else
ret = silc_packet_receive_process(
- sock, server->server_type == SILC_ROUTER ?
- TRUE : FALSE, NULL, NULL, 0,
+ sock, server->server_type == SILC_ROUTER,
+ NULL, NULL, 0,
silc_server_packet_parse, server);
if (!ret) {
char tmp[128];
if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) {
- silc_schedule_task_add(server->schedule, 0,
+ silc_schedule_task_add(server->schedule, sock->sock,
silc_server_close_connection_final,
(void *)sock, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
}
}
- silc_schedule_task_add(server->schedule, 0,
+ silc_schedule_task_add(server->schedule, sock->sock,
silc_server_close_connection_final,
(void *)sock, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);