SilcHmac hmac;
unsigned char *id_string;
uint32 iv_len;
+ int block_len;
SILC_LOG_DEBUG(("Sending packet to channel"));
if (!cipher || !hmac)
return;
+ block_len = silc_cipher_get_block_len(cipher);
+
/* Generate IV */
iv_len = silc_cipher_get_block_len(cipher);
if (channel->iv[0] == '\0')
packetdata.src_id_len + packetdata.dst_id_len;
packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
packetdata.src_id_len +
- packetdata.dst_id_len));
+ packetdata.dst_id_len), block_len);
/* Prepare outgoing data buffer for packet sending */
silc_packet_send_prepare(sock,
silc_buffer_put(sock->outbuf, payload->data, payload->len);
/* Create the outgoing packet */
- silc_packet_assemble(&packetdata);
+ silc_packet_assemble(&packetdata, cipher);
/* Encrypt the header and padding of the packet. This is encrypted
with normal session key shared with our server. */
- silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
+ silc_packet_encrypt(cipher, hmac, conn->psn_send++,
+ sock->outbuf, SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + packetdata.dst_id_len +
packetdata.padlen);
sock->outbuf->data, sock->outbuf->len);
/* Now actually send the packet */
- silc_client_packet_send_real(client, sock, force_send, FALSE);
+ silc_client_packet_send_real(client, sock, force_send);
silc_buffer_free(payload);
silc_free(id_string);
}
+typedef struct {
+ SilcChannelMessagePayload payload;
+ SilcChannelID *channel_id;
+} *SilcChannelClientResolve;
+
static void silc_client_channel_message_cb(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
uint32 clients_count,
void *context)
{
- SilcPacketContext *packet = (SilcPacketContext *)context;
+ SilcChannelClientResolve res = (SilcChannelClientResolve)context;
+
+ if (clients_count == 1) {
+ SilcIDCacheEntry id_cache = NULL;
+ SilcChannelEntry channel;
+ unsigned char *message;
+
+ if (!silc_idcache_find_by_id_one(conn->channel_cache, res->channel_id,
+ &id_cache))
+ goto out;
- if (clients)
- silc_client_channel_message(client, conn->sock, packet);
- silc_packet_context_free(packet);
+ channel = (SilcChannelEntry)id_cache->context;
+ message = silc_channel_message_get_data(res->payload, NULL);
+
+ /* Pass the message to application */
+ client->ops->channel_message(client, conn, clients[0], channel,
+ silc_channel_message_get_flags(res->payload),
+ message);
+ }
+
+ out:
+ silc_channel_message_payload_free(res->payload);
+ silc_free(res->channel_id);
+ silc_free(res);
}
/* Process received message to a channel (or from a channel, really). This
/* Find client entry */
silc_list_start(channel->clients);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
- if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
+ if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id) &&
+ chu->client->nickname) {
found = TRUE;
break;
}
if (!found) {
/* Resolve the client info */
+ SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
+ res->payload = payload;
+ res->channel_id = id;
silc_client_get_client_by_id_resolve(client, conn, client_id,
silc_client_channel_message_cb,
- silc_packet_context_dup(packet));
+ res);
+ payload = NULL;
+ id = NULL;
goto out;
}
channel = (SilcChannelEntry)id_cache->context;
}
- hmac = channel->hmac ? channel->hmac->hmac->name : SILC_DEFAULT_HMAC;
+ hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
+ SILC_DEFAULT_HMAC);
/* Save the old key for a short period of time so that we can decrypt
channel message even after the rekey if some client would be sending
/* Generate HMAC key from the channel key data and set it */
silc_hmac_alloc(hmac, NULL, &channel->hmac);
- silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
- silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
+ silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
+ silc_hmac_set_key(channel->hmac, hash,
+ silc_hash_len(silc_hmac_get_hash(channel->hmac)));
memset(hash, 0, sizeof(hash));
out:
/* Generate HMAC key from the channel key data and set it */
silc_hmac_alloc(hmac, NULL, &entry->hmac);
- silc_hash_make(entry->hmac->hash, entry->key, entry->key_len, hash);
- silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
+ silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
+ entry->key_len, hash);
+ silc_hmac_set_key(entry->hmac, hash,
+ silc_hash_len(silc_hmac_get_hash(entry->hmac)));
memset(hash, 0, sizeof(hash));
/* Add to the private keys list */