Packet engine: moved packet sanity checks after MAC check
[silc.git] / lib / silccore / silcpacket.c
index 85d8b4e635dd73e24c585ff6f3d7f91e6bb48c85..8b68c5ed17d00ddca0bb61f4456d9b0e33cc0d5b 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;
@@ -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;
@@ -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;
@@ -1324,6 +1324,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,17 +1334,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);
-    stream->src_id = NULL;
     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;
   }
@@ -1351,17 +1352,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);
-    stream->dst_id = NULL;
     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;
   }
@@ -2196,17 +2197,6 @@ static void silc_packet_read_process(SilcPacketStream stream)
     /* Get packet length and full packet length with padding */
     SILC_PACKET_LENGTH(header, packetlen, paddedlen);
 
-    /* Sanity checks */
-    if (silc_unlikely(packetlen < SILC_PACKET_MIN_LEN)) {
-      if (!stream->udp && !silc_socket_stream_is_udp(stream->stream, NULL))
-       SILC_LOG_ERROR(("Received too short packet"));
-      silc_mutex_unlock(stream->lock);
-      SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
-      silc_mutex_lock(stream->lock);
-      memset(tmp, 0, sizeof(tmp));
-      goto out;
-    }
-
     if (silc_buffer_len(inbuf) < paddedlen + ivlen + mac_len) {
       SILC_LOG_DEBUG(("Received partial packet, waiting for the rest "
                      "(%d bytes)",
@@ -2230,6 +2220,17 @@ static void silc_packet_read_process(SilcPacketStream stream)
       goto out;
     }
 
+    /* Sanity checks */
+    if (silc_unlikely(packetlen < SILC_PACKET_MIN_LEN)) {
+      if (!stream->udp && !silc_socket_stream_is_udp(stream->stream, NULL))
+       SILC_LOG_ERROR(("Received too short packet"));
+      silc_mutex_unlock(stream->lock);
+      SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
+      silc_mutex_lock(stream->lock);
+      memset(tmp, 0, sizeof(tmp));
+      goto out;
+    }
+
     /* Get packet */
     packet = silc_packet_alloc(stream->sc->engine);
     if (silc_unlikely(!packet)) {
@@ -2343,7 +2344,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
 };
@@ -2532,7 +2533,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
 };