silc_pkcs_private_key_get_len(private_key) / 8 : 0);
SilcUInt32 dlen = data_len + SILC_MESSAGE_HLEN + header_len + pklen + prlen;
- if (dlen > SILC_MESSAGE_MAX_LEN)
+ if (silc_unlikely(dlen > SILC_MESSAGE_MAX_LEN))
data_len -= (dlen - SILC_MESSAGE_MAX_LEN);
return data_len;
if (!private_message || (private_message && static_key))
iv_len = block_len;
- if (data_len < (mac_len + iv_len + block_len))
+ if (silc_unlikely(data_len < (mac_len + iv_len + block_len)))
return FALSE;
- if (check_mac) {
+ if (silc_likely(check_mac)) {
/* Check the MAC of the message */
SILC_LOG_DEBUG(("Checking message MAC"));
silc_hmac_init(hmac);
silc_hmac_update(hmac, data, data_len - mac_len);
silc_hmac_final(hmac, mac, &mac_len);
- if (memcmp(data + (data_len - mac_len), mac, mac_len)) {
+ if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
SILC_LOG_DEBUG(("Message MAC does not match"));
return FALSE;
}
silc_cipher_get_iv(cipher));
/* Decrypt block */
- if (!silc_cipher_decrypt(cipher, data, data, block_len, ivp)) {
+ if (silc_unlikely(!silc_cipher_decrypt(cipher, data, data, block_len,
+ ivp))) {
SILC_ASSERT(FALSE);
return FALSE;
}
totlen = 2;
SILC_GET16_MSB(len, data + totlen);
totlen += 2 + len;
- if (totlen + iv_len + mac_len + 2 > data_len)
+ if (silc_unlikely(totlen + iv_len + mac_len + 2 > data_len))
return FALSE;
totlen += 2;
if (totlen >= block_len)
- if (!silc_cipher_decrypt(cipher, data + block_len, data + block_len,
- (totlen - block_len) + SILC_MESSAGE_PAD(totlen),
- ivp)) {
+ if (silc_unlikely(!silc_cipher_decrypt(cipher, data + block_len,
+ data + block_len,
+ (totlen - block_len) +
+ SILC_MESSAGE_PAD(totlen), ivp))) {
SILC_ASSERT(FALSE);
return FALSE;
}
silc_buffer_set(&buffer, payload, payload_len);
/* Decrypt the payload */
- if (cipher) {
+ if (silc_likely(cipher)) {
ret = silc_message_payload_decrypt(buffer.data, silc_buffer_len(&buffer),
private_message, static_key,
cipher, hmac, TRUE);
- if (ret == FALSE)
+ if (silc_unlikely(ret == FALSE))
return NULL;
}
- if (hmac)
+ if (silc_likely(hmac))
mac_len = silc_hmac_len(hmac);
/* IV is present for all channel messages, and private messages when
if (!message) {
newp = message = silc_calloc(1, sizeof(*newp));
- if (!newp)
+ if (silc_unlikely(!newp))
return NULL;
}
memset(message, 0, sizeof(*message));
SILC_STR_UI16_NSTRING(&message->pad,
&message->pad_len),
SILC_STR_END);
- if (ret == -1)
+ if (silc_unlikely(ret == -1))
goto err;
- if ((message->data_len > silc_buffer_len(&buffer) - 6 - mac_len - iv_len) ||
- (message->pad_len + message->data_len > silc_buffer_len(&buffer) -
- 6 - mac_len - iv_len)) {
+ if (silc_unlikely((message->data_len > silc_buffer_len(&buffer) -
+ 6 - mac_len - iv_len) ||
+ (message->pad_len + message->data_len >
+ silc_buffer_len(&buffer) - 6 - mac_len - iv_len))) {
SILC_LOG_ERROR(("Incorrect Message Payload in packet"));
goto err;
}
SilcHmac hmac)
{
/* Encrypt payload of the packet */
- if (!silc_cipher_encrypt(cipher, data, data, data_len, iv))
+ if (silc_unlikely(!silc_cipher_encrypt(cipher, data, data, data_len, iv)))
return FALSE;
/* Compute the MAC of the encrypted message data */
return 0;
mac_len = silc_hmac_len(e->hmac);
- if (!silc_buffer_enlarge(buffer, mac_len))
+ if (silc_unlikely(!silc_buffer_enlarge(buffer, mac_len)))
return -1;
- if (!silc_message_payload_encrypt(buffer->head,
- e->payload_len,
- silc_buffer_headlen(buffer),
- e->iv, e->cipher, e->hmac))
+ if (silc_unlikely(!silc_message_payload_encrypt(buffer->head,
+ e->payload_len,
+ silc_buffer_headlen(buffer),
+ e->iv, e->cipher, e->hmac)))
return -1;
return mac_len;
silc_buffer_headlen(buffer),
e->public_key, e->private_key,
e->hash);
- if (!sig)
+ if (silc_unlikely(!sig))
return -1;
len = silc_buffer_format(buffer,
SILC_STR_DATA(silc_buffer_data(sig),
silc_buffer_len(sig)),
SILC_STR_END);
- if (len < 0) {
+ if (silc_unlikely(len < 0)) {
silc_buffer_free(sig);
return -1;
}
SILC_LOG_DEBUG(("Encoding Message Payload"));
- if (!data_len)
+ if (silc_unlikely(!data_len))
return NULL;
- if (!private_message && (!cipher || !hmac))
+ if (silc_unlikely(!private_message && (!cipher || !hmac)))
return NULL;
if (!buffer) {
buf = buffer = silc_buffer_alloc(0);
- if (!buf)
+ if (silc_unlikely(!buf))
return NULL;
}
silc_buffer_reset(buffer);
(s)->stream_context); \
} while(0)
-static void silc_packet_dispatch(SilcPacket packet);
+static SilcBool silc_packet_dispatch(SilcPacket packet);
static void silc_packet_read_process(SilcPacketStream stream);
static inline SilcBool silc_packet_send_raw(SilcPacketStream stream,
SilcPacketType type,
SILC_LOG_DEBUG(("Injecting packet %p to stream %p", packet, packet->stream));
silc_mutex_lock(stream->lock);
- silc_packet_dispatch(packet);
+ if (!stream->destroyed)
+ silc_packet_dispatch(packet);
silc_mutex_unlock(stream->lock);
+ silc_packet_stream_unref(stream);
}
/* Write data to the stream. Must be called with ps->lock locked. Unlocks
return;
/* Now process the data */
+ silc_packet_stream_ref(ps);
if (!remote) {
silc_packet_read_process(ps);
silc_mutex_unlock(ps->lock);
silc_packet_read_process(remote);
silc_mutex_unlock(remote->lock);
}
+ silc_packet_stream_unref(ps);
break;
default:
if (packet) {
/* Inject packet to the new stream */
packet->stream = ps;
+ silc_packet_stream_ref(ps);
silc_schedule_task_add_timeout(silc_stream_get_schedule(stream->stream),
silc_packet_stream_inject_packet, packet,
0, 0);
return TRUE;
}
-/* Dispatch packet to application. Called with stream->lock locked. */
+/* Dispatch packet to application. Called with stream->lock locked.
+ Returns FALSE if the stream was destroyed while dispatching a packet. */
-static void silc_packet_dispatch(SilcPacket packet)
+static SilcBool silc_packet_dispatch(SilcPacket packet)
{
SilcPacketStream stream = packet->stream;
SilcPacketProcess p;
stream->stream_context)))
silc_packet_free(packet);
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_dlist_start(stream->process);
stream->engine->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
}
p->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
} else {
p->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
break;
stream->engine->callback_context,
stream->stream_context)) {
silc_mutex_lock(stream->lock);
- return;
+ return stream->destroyed == FALSE;
}
silc_mutex_lock(stream->lock);
}
/* If we got here, no one wanted the packet, so drop it */
silc_packet_free(packet);
+ return stream->destroyed == FALSE;
}
/* Process incoming data and parse packets. Called with stream->lock
}
/* Dispatch the packet to application */
- silc_packet_dispatch(packet);
+ if (!silc_packet_dispatch(packet))
+ break;
}
silc_buffer_reset(&stream->inbuf);
/* Signal the waiting thread for a new packet */
silc_mutex_lock(pw->wait_lock);
- if (pw->stopped) {
+ if (silc_unlikely(pw->stopped)) {
silc_mutex_unlock(pw->wait_lock);
return FALSE;
}
/* Wait here until packet has arrived */
while (silc_list_count(pw->packet_queue) == 0) {
- if (pw->stopped) {
+ if (silc_unlikely(pw->stopped)) {
silc_mutex_unlock(pw->wait_lock);
return -1;
}