From 2f244dd972a02028e72fb8388425ec3326dd30c1 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 18 Dec 2006 14:49:05 +0000 Subject: [PATCH] Handle destroyed stream in packet dispatcher. --- lib/silccore/silcmessage.c | 59 ++++++++++++++++++++------------------ lib/silccore/silcpacket.c | 32 +++++++++++++-------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/lib/silccore/silcmessage.c b/lib/silccore/silcmessage.c index be06879e..19c1959e 100644 --- a/lib/silccore/silcmessage.c +++ b/lib/silccore/silcmessage.c @@ -65,7 +65,7 @@ SilcUInt32 silc_message_payload_datalen(SilcUInt32 data_len, 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; @@ -281,16 +281,16 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, 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; } @@ -306,7 +306,8 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, 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; } @@ -315,13 +316,14 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, 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; } @@ -353,15 +355,15 @@ silc_message_payload_parse(unsigned char *payload, 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 @@ -371,7 +373,7 @@ silc_message_payload_parse(unsigned char *payload, if (!message) { newp = message = silc_calloc(1, sizeof(*newp)); - if (!newp) + if (silc_unlikely(!newp)) return NULL; } memset(message, 0, sizeof(*message)); @@ -394,12 +396,13 @@ silc_message_payload_parse(unsigned char *payload, 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; } @@ -447,7 +450,7 @@ SilcBool silc_message_payload_encrypt(unsigned char *data, 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 */ @@ -470,13 +473,13 @@ static int silc_message_payload_encode_encrypt(SilcBuffer buffer, 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; @@ -498,14 +501,14 @@ static int silc_message_payload_encode_sig(SilcBuffer buffer, 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; } @@ -537,14 +540,14 @@ SilcBuffer silc_message_payload_encode(SilcMessageFlags flags, 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); diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 98e4b72d..a88bbf63 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -151,7 +151,7 @@ do { \ (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, @@ -179,8 +179,10 @@ SILC_TASK_CALLBACK(silc_packet_stream_inject_packet) 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 @@ -436,6 +438,7 @@ static void silc_packet_stream_io(SilcStream stream, SilcStreamStatus status, return; /* Now process the data */ + silc_packet_stream_ref(ps); if (!remote) { silc_packet_read_process(ps); silc_mutex_unlock(ps->lock); @@ -443,6 +446,7 @@ static void silc_packet_stream_io(SilcStream stream, SilcStreamStatus status, silc_packet_read_process(remote); silc_mutex_unlock(remote->lock); } + silc_packet_stream_unref(ps); break; default: @@ -725,6 +729,7 @@ SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream, 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); @@ -1664,9 +1669,10 @@ static inline SilcBool silc_packet_parse(SilcPacket packet) 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; @@ -1685,7 +1691,7 @@ static void silc_packet_dispatch(SilcPacket packet) stream->stream_context))) silc_packet_free(packet); silc_mutex_lock(stream->lock); - return; + return stream->destroyed == FALSE; } silc_dlist_start(stream->process); @@ -1702,7 +1708,7 @@ static void silc_packet_dispatch(SilcPacket packet) stream->engine->callback_context, stream->stream_context)) { silc_mutex_lock(stream->lock); - return; + return stream->destroyed == FALSE; } silc_mutex_lock(stream->lock); } @@ -1716,7 +1722,7 @@ static void silc_packet_dispatch(SilcPacket packet) p->callback_context, stream->stream_context)) { silc_mutex_lock(stream->lock); - return; + return stream->destroyed == FALSE; } silc_mutex_lock(stream->lock); } else { @@ -1730,7 +1736,7 @@ static void silc_packet_dispatch(SilcPacket packet) p->callback_context, stream->stream_context)) { silc_mutex_lock(stream->lock); - return; + return stream->destroyed == FALSE; } silc_mutex_lock(stream->lock); break; @@ -1747,13 +1753,14 @@ static void silc_packet_dispatch(SilcPacket packet) 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 @@ -1965,7 +1972,8 @@ static void silc_packet_read_process(SilcPacketStream stream) } /* Dispatch the packet to application */ - silc_packet_dispatch(packet); + if (!silc_packet_dispatch(packet)) + break; } silc_buffer_reset(&stream->inbuf); @@ -2010,7 +2018,7 @@ silc_packet_wait_packet_receive(SilcPacketEngine engine, /* 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; } @@ -2103,7 +2111,7 @@ int silc_packet_wait(void *waiter, int timeout, SilcPacket *return_packet) /* 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; } -- 2.24.0