Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
unsigned char *dst_id; /* Destination ID */
SilcUInt32 send_psn; /* Sending sequence */
SilcUInt32 receive_psn; /* Receiving sequence */
- SilcAtomic8 refcnt; /* Reference counter */
+ SilcAtomic32 refcnt; /* Reference counter */
SilcUInt8 sid; /* Security ID, set if IV included */
unsigned int src_id_len : 6;
unsigned int src_id_type : 2;
silc_mutex_unlock(ps->lock);
if (ret == -1) {
/* Cannot read now, do it later. */
- silc_buffer_pull(inbuf, silc_buffer_len(inbuf));
return FALSE;
}
if (ret == -1) {
/* Cannot read now, do it later. */
- silc_buffer_pull(inbuf, silc_buffer_len(inbuf));
return FALSE;
}
silc_free(engine);
}
-static const char *packet_error[] = {
+static const char * const packet_error[] = {
"Cannot read from stream",
"Cannot write to stream",
"Packet MAC failed",
return NULL;
ps->stream = stream;
- silc_atomic_init8(&ps->refcnt, 1);
+ silc_atomic_init32(&ps->refcnt, 1);
silc_mutex_alloc(&ps->lock);
/* Allocate out buffer */
(void *)&ps->sc)) {
ps->sc = silc_calloc(1, sizeof(*ps->sc));
if (!ps->sc) {
- silc_packet_stream_destroy(ps);
silc_mutex_unlock(engine->lock);
+ silc_packet_stream_destroy(ps);
return NULL;
}
ps->sc->engine = engine;
if (!inbuf) {
silc_free(ps->sc);
ps->sc = NULL;
- silc_packet_stream_destroy(ps);
silc_mutex_unlock(engine->lock);
+ silc_packet_stream_destroy(ps);
return NULL;
}
silc_buffer_reset(inbuf);
silc_buffer_free(inbuf);
silc_free(ps->sc);
ps->sc = NULL;
- silc_packet_stream_destroy(ps);
silc_mutex_unlock(engine->lock);
+ silc_packet_stream_destroy(ps);
return NULL;
}
silc_dlist_add(ps->sc->inbufs, inbuf);
silc_dlist_del(ps->sc->inbufs, inbuf);
silc_free(ps->sc);
ps->sc = NULL;
- silc_packet_stream_destroy(ps);
silc_mutex_unlock(engine->lock);
+ silc_packet_stream_destroy(ps);
return NULL;
}
}
return NULL;
}
+ SILC_LOG_DEBUG(("Created packet stream %p", ps));
+
return ps;
}
return NULL;
ps->sc = stream->sc;
- silc_atomic_init8(&ps->refcnt, 1);
+ silc_atomic_init32(&ps->refcnt, 1);
silc_mutex_alloc(&ps->lock);
/* Set the UDP packet stream as underlaying stream */
if (!stream)
return;
- if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0) {
+ if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0) {
+ if (stream->destroyed)
+ return;
stream->destroyed = TRUE;
+ SILC_LOG_DEBUG(("Marking packet stream %p destroyed", stream));
+
/* Close the underlaying stream */
if (!stream->udp && stream->stream)
silc_stream_close(stream->stream);
if (!stream->udp) {
/* Delete from engine */
- engine = stream->sc->engine;
- silc_mutex_lock(engine->lock);
- silc_list_del(engine->streams, stream);
-
- /* Remove per scheduler context, if it is not used anymore */
if (stream->sc) {
+ engine = stream->sc->engine;
+ silc_mutex_lock(engine->lock);
+ silc_list_del(engine->streams, stream);
+
+ /* Remove per scheduler context, if it is not used anymore */
stream->sc->stream_count--;
if (!stream->sc->stream_count)
silc_hash_table_del(engine->contexts, stream->sc->schedule);
+
+ silc_mutex_unlock(engine->lock);
}
- silc_mutex_unlock(engine->lock);
/* Destroy the underlaying stream */
if (stream->stream)
silc_free(stream->src_id);
silc_free(stream->dst_id);
- silc_atomic_uninit8(&stream->refcnt);
+ silc_atomic_uninit32(&stream->refcnt);
silc_mutex_free(stream->lock);
silc_free(stream);
}
stream->process = silc_dlist_init();
if (!stream->process) {
silc_mutex_unlock(stream->lock);
+ silc_free(p);
return FALSE;
}
}
void silc_packet_stream_ref(SilcPacketStream stream)
{
- silc_atomic_add_int8(&stream->refcnt, 1);
+ silc_atomic_add_int32(&stream->refcnt, 1);
SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream,
- silc_atomic_get_int8(&stream->refcnt) - 1,
- silc_atomic_get_int8(&stream->refcnt)));
+ silc_atomic_get_int32(&stream->refcnt) - 1,
+ silc_atomic_get_int32(&stream->refcnt)));
}
/* Unreference packet stream */
void silc_packet_stream_unref(SilcPacketStream stream)
{
SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream,
- silc_atomic_get_int8(&stream->refcnt),
- silc_atomic_get_int8(&stream->refcnt) - 1));
- if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0)
+ silc_atomic_get_int32(&stream->refcnt),
+ silc_atomic_get_int32(&stream->refcnt) - 1));
+ if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0)
return;
- silc_atomic_add_int8(&stream->refcnt, 1);
+ silc_atomic_add_int32(&stream->refcnt, 1);
silc_packet_stream_destroy(stream);
}
SILC_LOG_DEBUG(("Setting source ID to packet stream %p", stream));
silc_free(stream->src_id);
+ stream->src_id = NULL;
if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) {
silc_mutex_unlock(stream->lock);
return FALSE;
SILC_LOG_DEBUG(("Setting destination ID to packet stream %p", stream));
silc_free(stream->dst_id);
+ stream->dst_id = NULL;
if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) {
silc_mutex_unlock(stream->lock);
return FALSE;
unsigned char *iv = silc_cipher_get_iv(cipher);
SilcUInt32 pc1, pc2;
- /* Increment 64-bit packet counter */
- SILC_GET32_MSB(pc1, iv + 4);
- SILC_GET32_MSB(pc2, iv + 8);
- if (++pc2 == 0)
- ++pc1;
- SILC_PUT32_MSB(pc1, iv + 4);
- SILC_PUT32_MSB(pc2, iv + 8);
-
/* Reset block counter */
memset(iv + 12, 0, 4);
ret_iv[1] = ret_iv[0] + iv[4];
ret_iv[2] = ret_iv[0] ^ ret_iv[1];
ret_iv[3] = ret_iv[0] + ret_iv[2];
- SILC_PUT32_MSB(pc2, ret_iv + 4);
+
+ /* Increment 32-bit packet counter */
+ SILC_GET32_MSB(pc1, iv + 8);
+ pc1++;
+ SILC_PUT32_MSB(pc1, ret_iv + 4);
+
SILC_LOG_HEXDUMP(("IV"), ret_iv, 8);
/* Set new nonce to counter block */
- memcpy(iv + 4, ret_iv, 4);
+ memcpy(iv + 4, ret_iv, 8);
+ } else {
+ /* Increment 64-bit packet counter */
+ SILC_GET32_MSB(pc1, iv + 4);
+ SILC_GET32_MSB(pc2, iv + 8);
+ if (++pc2 == 0)
+ ++pc1;
+ SILC_PUT32_MSB(pc1, iv + 4);
+ SILC_PUT32_MSB(pc2, iv + 8);
}
SILC_LOG_HEXDUMP(("Counter Block"), iv, 16);
silc_buffer_len(buffer)), buffer->head,
silc_buffer_headlen(buffer) + silc_buffer_len(buffer));
- SILC_LOG_DEBUG(("Incoming packet type: %d (%s)", packet->type,
- silc_get_packet_name(packet->type)));
+ SILC_LOG_DEBUG(("Incoming packet type: %d (%s), flags %d", packet->type,
+ silc_get_packet_name(packet->type), packet->flags));
return TRUE;
}