Don't delete packet stream
[silc.git] / lib / silccore / silcpacket.c
index df195f678075c20fb495b276977965221cebfbd0..2f491acb5f0997f2e5c30455be8a9eb638954eb9 100644 (file)
@@ -40,7 +40,7 @@ struct SilcPacketEngineStruct {
   SilcMutex lock;                       /* Engine lock */
   SilcRng rng;                          /* RNG for engine */
   SilcHashTable contexts;               /* Per scheduler contexts */
-  SilcPacketCallbacks *callbacks;       /* Packet callbacks */
+  const SilcPacketCallbacks *callbacks;         /* Packet callbacks */
   void *callback_context;               /* Context for callbacks */
   SilcList streams;                     /* All streams in engine */
   SilcList packet_pool;                 /* Free list for received packets */
@@ -51,7 +51,7 @@ struct SilcPacketEngineStruct {
 /* Packet processor context */
 typedef struct SilcPacketProcessStruct {
   SilcPacketType *types;                /* Packets to process */
-  SilcPacketCallbacks *callbacks;       /* Callbacks or NULL */
+  const SilcPacketCallbacks *callbacks;         /* Callbacks or NULL */
   void *callback_context;
   SilcInt32 priority;                   /* Priority */
 } *SilcPacketProcess;
@@ -81,7 +81,7 @@ struct SilcPacketStreamStruct {
   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;
@@ -540,7 +540,7 @@ static void silc_packet_engine_context_destr(void *key, void *context,
 
 SilcPacketEngine
 silc_packet_engine_start(SilcRng rng, SilcBool router,
-                        SilcPacketCallbacks *callbacks,
+                        const SilcPacketCallbacks *callbacks,
                         void *callback_context)
 {
   SilcPacketEngine engine;
@@ -695,7 +695,7 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine,
     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 */
@@ -816,7 +816,7 @@ SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream,
     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 */
@@ -884,7 +884,7 @@ void silc_packet_stream_destroy(SilcPacketStream 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;
@@ -972,7 +972,7 @@ void silc_packet_stream_destroy(SilcPacketStream 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);
 }
@@ -1001,7 +1001,7 @@ void silc_packet_stream_set_iv_included(SilcPacketStream stream)
 /* Links `callbacks' to `stream' for specified packet types */
 
 static SilcBool silc_packet_stream_link_va(SilcPacketStream stream,
-                                          SilcPacketCallbacks *callbacks,
+                                          const SilcPacketCallbacks *callbacks,
                                           void *callback_context,
                                           int priority, va_list ap)
 {
@@ -1080,7 +1080,7 @@ static SilcBool silc_packet_stream_link_va(SilcPacketStream stream,
 /* Links `callbacks' to `stream' for specified packet types */
 
 SilcBool silc_packet_stream_link(SilcPacketStream stream,
-                                SilcPacketCallbacks *callbacks,
+                                const SilcPacketCallbacks *callbacks,
                                 void *callback_context,
                                 int priority, ...)
 {
@@ -1098,7 +1098,7 @@ SilcBool silc_packet_stream_link(SilcPacketStream stream,
 /* Unlinks `callbacks' from `stream'. */
 
 void silc_packet_stream_unlink(SilcPacketStream stream,
-                              SilcPacketCallbacks *callbacks,
+                              const SilcPacketCallbacks *callbacks,
                               void *callback_context)
 {
   SilcPacketProcess p;
@@ -1108,19 +1108,21 @@ void silc_packet_stream_unlink(SilcPacketStream stream,
 
   silc_mutex_lock(stream->lock);
 
-  silc_dlist_start(stream->process);
-  while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END)
-    if (p->callbacks == callbacks &&
-       p->callback_context == callback_context) {
-      silc_dlist_del(stream->process, p);
-      silc_free(p->types);
-      silc_free(p);
-      break;
-    }
+  if (stream->process) {
+    silc_dlist_start(stream->process);
+    while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END)
+      if (p->callbacks == callbacks &&
+         p->callback_context == callback_context) {
+        silc_dlist_del(stream->process, p);
+        silc_free(p->types);
+        silc_free(p);
+        break;
+      }
 
-  if (!silc_dlist_count(stream->process)) {
-    silc_dlist_uninit(stream->process);
-    stream->process = NULL;
+    if (!silc_dlist_count(stream->process)) {
+      silc_dlist_uninit(stream->process);
+      stream->process = NULL;
+    }
   }
 
   silc_mutex_unlock(stream->lock);
@@ -1154,10 +1156,10 @@ SilcBool silc_packet_get_sender(SilcPacket packet,
 
 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 */
@@ -1165,11 +1167,11 @@ void silc_packet_stream_ref(SilcPacketStream 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);
 }
 
@@ -1324,6 +1326,7 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream,
 {
   SilcUInt32 len;
   unsigned char tmp[32];
+  void *tmp_id;
 
   if (!src_id && !dst_id)
     return FALSE;
@@ -1333,16 +1336,17 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream,
   if (src_id) {
     SILC_LOG_DEBUG(("Setting source ID to packet stream %p", stream));
 
-    silc_free(stream->src_id);
     if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) {
       silc_mutex_unlock(stream->lock);
       return FALSE;
     }
-    stream->src_id = silc_memdup(tmp, len);
-    if (!stream->src_id) {
+    tmp_id = silc_memdup(tmp, len);
+    if (!tmp_id) {
       silc_mutex_unlock(stream->lock);
       return FALSE;
     }
+    silc_free(stream->src_id);
+    stream->src_id = tmp_id;
     stream->src_id_type = src_id_type;
     stream->src_id_len = len;
   }
@@ -1350,16 +1354,17 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream,
   if (dst_id) {
     SILC_LOG_DEBUG(("Setting destination ID to packet stream %p", stream));
 
-    silc_free(stream->dst_id);
     if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) {
       silc_mutex_unlock(stream->lock);
       return FALSE;
     }
-    stream->dst_id = silc_memdup(tmp, len);
-    if (!stream->dst_id) {
+    tmp_id = silc_memdup(tmp, len);
+    if (!tmp_id) {
       silc_mutex_unlock(stream->lock);
       return FALSE;
     }
+    silc_free(stream->dst_id);
+    stream->dst_id = tmp_id;
     stream->dst_id_type = dst_id_type;
     stream->dst_id_len = len;
   }
@@ -2341,7 +2346,7 @@ silc_packet_wait_packet_receive(SilcPacketEngine engine,
                                void *stream_context);
 
 /* Packet waiting callbacks */
-static SilcPacketCallbacks silc_packet_wait_cbs =
+static const SilcPacketCallbacks silc_packet_wait_cbs =
 {
   silc_packet_wait_packet_receive, NULL, NULL
 };
@@ -2530,7 +2535,7 @@ typedef struct {
 } *SilcPacketWrapperStream;
 
 /* Packet wrapper callbacks */
-static SilcPacketCallbacks silc_packet_wrap_cbs =
+static const SilcPacketCallbacks silc_packet_wrap_cbs =
 {
   silc_packet_wrap_packet_receive, NULL, NULL
 };