}
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;
return ctx->type;
}
-/* Duplicates packet context. Duplicates the entire context and its
- contents. */
+/* Allocate packet context */
-SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
+SilcPacketContext *silc_packet_context_alloc()
{
- SilcPacketContext *new;
-
- new = silc_calloc(1, sizeof(*new));
- new->buffer = silc_buffer_copy(ctx->buffer);
- new->type = ctx->type;
- new->flags = ctx->flags;
-
- new->src_id = silc_calloc(ctx->src_id_len, sizeof(*new->src_id));
- memcpy(new->src_id, ctx->src_id, ctx->src_id_len);
- new->src_id_len = ctx->src_id_len;
- new->src_id_type = ctx->src_id_type;
+ SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
+ ctx->users++;
+ return ctx;
+}
- new->dst_id = silc_calloc(ctx->dst_id_len, sizeof(*new->dst_id));
- memcpy(new->dst_id, ctx->dst_id, ctx->dst_id_len);
- new->dst_id_len = ctx->dst_id_len;
- new->dst_id_type = ctx->dst_id_type;
+/* Increse the reference count of the packet context. */
- new->truelen = ctx->truelen;
- new->padlen = ctx->padlen;
+SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
+{
+ ctx->users++;
+ return ctx;
+}
- new->rng = ctx->rng;
- new->context = ctx->context;
- new->sock = ctx->sock;
+/* Decrese the reference count of the packet context and free it only if
+ it is zero. */
- return new;
+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);
+ }
}
/* Back pointers */
void *context;
SilcSocketConnection sock;
+
+ /* Reference count for this context. The context is free'd only
+ after the reference count is zero. */
+ int users;
} SilcPacketContext;
/*
void *context);
SilcPacketType silc_packet_parse(SilcPacketContext *ctx);
SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx);
+SilcPacketContext *silc_packet_context_alloc();
SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx);
+void silc_packet_context_free(SilcPacketContext *ctx);
#endif