Added reference count to SilcPacketContext and added two new
[silc.git] / lib / silccore / silcpacket.c
index d01e1baaad08ecd7f22ca1d2fcd4e0ef5060e5bd..7054f600f6764145d6c3e6ab1ce2d2d4dcd19dfe 100644 (file)
@@ -204,8 +204,7 @@ void silc_packet_assemble(SilcPacketContext *ctx)
 
   /* Get random padding */
 #if 1
-  for (i = 0; i < ctx->padlen; i++)
-    tmppad[i] = silc_rng_get_byte(ctx->rng);
+  for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_get_byte(ctx->rng);
 #else
   /* XXX: For testing - to be removed */
   memset(tmppad, 65, sizeof(tmppad));
@@ -368,12 +367,17 @@ void silc_packet_receive_process(SilcSocketConnection sock,
   SilcPacketParserContext *parse_ctx;
   int packetlen, paddedlen, count, mac_len = 0;
 
+  /* We need at least 2 bytes of data to be able to start processing
+     the packet. */
+  if (sock->inbuf->len < 2)
+    return;
+
   if (hmac)
     mac_len = hmac->hash->hash->hash_len;
 
   /* Parse the packets from the data */
   count = 0;
-  while (sock->inbuf->len > 2) {
+  while (sock->inbuf->len > 0) {
     SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
     paddedlen += 2;
     count++;
@@ -389,7 +393,7 @@ void silc_packet_receive_process(SilcSocketConnection sock,
     }
 
     parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
-    parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
+    parse_ctx->packet = silc_packet_context_alloc();
     parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
     parse_ctx->sock = sock;
     parse_ctx->cipher = cipher;
@@ -727,3 +731,38 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
 
   return ctx->type;
 }
+
+/* Allocate packet context */
+
+SilcPacketContext *silc_packet_context_alloc()
+{
+  SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
+  ctx->users++;
+  return ctx;
+}
+
+/* Increse the reference count of the packet context. */
+
+SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
+{
+  ctx->users++;
+  return ctx;
+}
+
+/* Decrese the reference count of the packet context and free it only if
+   it is zero. */
+
+void silc_packet_context_free(SilcPacketContext *ctx)
+{
+  ctx->users--;
+  if (ctx->users < 1)
+    {
+      if (ctx->buffer)
+       silc_buffer_free(ctx->buffer);
+      if (ctx->src_id)
+       silc_free(ctx->src_id);
+      if (ctx->dst_id)
+       silc_free(ctx->dst_id);
+      silc_free(ctx);
+    }
+}