Added IV Included support to allow packet send/receive on UDP.
[silc.git] / lib / silccore / silcpacket.c
1 /*
2
3   silcpacket.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2006 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /*
20  * Created: Fri Jul 25 18:52:14 1997
21  */
22 /* $Id$ */
23
24 #include "silc.h"
25
26 /************************** Types and definitions ***************************/
27
28 /* Packet engine */
29 struct SilcPacketEngineStruct {
30   SilcRng rng;                           /* RNG for engine */
31   SilcPacketCallbacks *callbacks;        /* Packet callbacks */
32   void *callback_context;                /* Context for callbacks */
33   SilcList streams;                      /* All streams in engine */
34   SilcList packet_pool;                  /* Free list for received packets */
35   SilcMutex lock;                        /* Engine lock */
36   SilcBool local_is_router;
37 };
38
39 /* Packet procesor context */
40 typedef struct SilcPacketProcessStruct {
41   SilcInt32 priority;                    /* Priority */
42   SilcPacketType *types;                 /* Packets to process */
43   SilcPacketCallbacks *callbacks;        /* Callbacks or NULL */
44   void *callback_context;
45 } *SilcPacketProcess;
46
47 /* Packet stream */
48 struct SilcPacketStreamStruct {
49   struct SilcPacketStreamStruct *next;
50   SilcPacketEngine engine;               /* Packet engine */
51   SilcStream stream;                     /* Underlaying stream */
52   SilcMutex lock;                        /* Stream lock */
53   SilcDList process;                     /* Packet processors, it set */
54   void *stream_context;                  /* Stream context */
55   SilcBufferStruct inbuf;                /* In buffer */
56   SilcBufferStruct outbuf;               /* Out buffer */
57   SilcUInt32 send_psn;                   /* Sending sequence */
58   SilcCipher send_key;                   /* Sending key */
59   SilcHmac send_hmac;                    /* Sending HMAC */
60   SilcUInt32 receive_psn;                /* Receiving sequence */
61   SilcCipher receive_key;                /* Receiving key */
62   SilcHmac receive_hmac;                 /* Receiving HMAC */
63   unsigned char *src_id;                 /* Source ID */
64   unsigned char *dst_id;                 /* Destination ID */
65   unsigned int src_id_len  : 6;
66   unsigned int src_id_type : 2;
67   unsigned int dst_id_len  : 6;
68   unsigned int dst_id_type : 2;
69   SilcUInt8 refcnt;                      /* Reference counter */
70   unsigned int is_router   : 1;          /* Set if router stream */
71   unsigned int destroyed   : 1;          /* Set if destroyed */
72   unsigned int iv_included : 1;          /* Set if IV included */
73 };
74
75 /* Initial size of stream buffers */
76 #define SILC_PACKET_DEFAULT_SIZE  1024
77
78 /* Header length without source and destination ID's. */
79 #define SILC_PACKET_HEADER_LEN 10
80
81 /* Minimum length of SILC Packet Header. */
82 #define SILC_PACKET_MIN_HEADER_LEN 16
83 #define SILC_PACKET_MIN_HEADER_LEN_IV 32
84
85 /* Maximum padding length */
86 #define SILC_PACKET_MAX_PADLEN 128
87
88 /* Default padding length */
89 #define SILC_PACKET_DEFAULT_PADLEN 16
90
91 /* Minimum packet length */
92 #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1)
93
94 /* Returns true length of the packet. */
95 #define SILC_PACKET_LENGTH(__packetdata, __ret_truelen, __ret_paddedlen) \
96 do {                                                                     \
97   SILC_GET16_MSB((__ret_truelen), (__packetdata));                       \
98   (__ret_paddedlen) = (__ret_truelen) + (SilcUInt8)(__packetdata)[4];    \
99 } while(0)
100
101 /* Calculates the data length with given header length.  This macro
102    can be used to check whether the data_len with header_len exceeds
103    SILC_PACKET_MAX_LEN.  If it does, this returns the new data_len
104    so that the SILC_PACKET_MAX_LEN is not exceeded.  If the data_len
105    plus header_len fits SILC_PACKET_MAX_LEN the returned data length
106    is the data_len given as argument. */
107 #define SILC_PACKET_DATALEN(data_len, header_len)                         \
108   ((data_len + header_len) > SILC_PACKET_MAX_LEN ?                        \
109    data_len - ((data_len + header_len) - SILC_PACKET_MAX_LEN) : data_len)
110
111 /* Calculates the length of the padding in the packet. */
112 #define SILC_PACKET_PADLEN(__packetlen, __blocklen, __padlen)               \
113 do {                                                                        \
114   __padlen = (SILC_PACKET_DEFAULT_PADLEN - (__packetlen) %                  \
115               ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN));  \
116   if (__padlen < 8)                                                         \
117     __padlen += ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN); \
118 } while(0)
119
120 /* Returns the length of the padding up to the maximum length, which
121    is 128 bytes.*/
122 #define SILC_PACKET_PADLEN_MAX(__packetlen, __blocklen, __padlen)          \
123 do {                                                                       \
124   __padlen = (SILC_PACKET_MAX_PADLEN - (__packetlen) %                     \
125               ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN)); \
126 } while(0)
127
128 /* EOS callback */
129 #define SILC_PACKET_CALLBACK_EOS(s)                                     \
130 do {                                                                    \
131   (s)->engine->callbacks->eos((s)->engine, s,                           \
132                               (s)->engine->callback_context,            \
133                               (s)->stream_context);                     \
134 } while(0)
135
136 /* Error callback */
137 #define SILC_PACKET_CALLBACK_ERROR(s, err)                              \
138 do {                                                                    \
139   (s)->engine->callbacks->error((s)->engine, s, err,                    \
140                                 (s)->engine->callback_context,          \
141                                 (s)->stream_context);                   \
142 } while(0)
143
144
145 /************************ Static utility functions **************************/
146
147 static void silc_packet_read_process(SilcPacketStream stream);
148
149 /* Our stream IO notifier callback. */
150
151 static void silc_packet_stream_io(SilcStream stream, SilcStreamStatus status,
152                                   void *context)
153 {
154   SilcPacketStream ps = context;
155   int ret;
156
157   silc_mutex_lock(ps->lock);
158
159   if (ps->destroyed) {
160     silc_mutex_unlock(ps->lock);
161     return;
162   }
163
164   switch (status) {
165
166   case SILC_STREAM_CAN_WRITE:
167     if (!silc_buffer_headlen(&ps->outbuf)) {
168       silc_mutex_unlock(ps->lock);
169       return;
170     }
171
172     SILC_LOG_DEBUG(("Writing pending data to stream"));
173
174     /* Write pending data to stream */
175     while (silc_buffer_len(&ps->outbuf) > 0) {
176       ret = silc_stream_write(ps->stream, ps->outbuf.data,
177                               silc_buffer_len(&ps->outbuf));
178       if (ret == 0) {
179         /* EOS */
180         silc_buffer_reset(&ps->outbuf);
181         silc_mutex_unlock(ps->lock);
182         SILC_PACKET_CALLBACK_EOS(ps);
183         return;
184       }
185
186       if (ret == -2) {
187         /* Error */
188         silc_buffer_reset(&ps->outbuf);
189         silc_mutex_unlock(ps->lock);
190         SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_WRITE);
191         return;
192       }
193
194       if (ret == -1) {
195         /* Cannot write now, write later. */
196         silc_mutex_unlock(ps->lock);
197         return;
198       }
199
200       /* Wrote data */
201       silc_buffer_pull(&ps->outbuf, ret);
202     }
203
204     silc_buffer_reset(&ps->outbuf);
205
206     silc_mutex_unlock(ps->lock);
207     break;
208
209   case SILC_STREAM_CAN_READ:
210     SILC_LOG_DEBUG(("Reading data from stream"));
211
212     /* Make sure we have fair amount of free space in inbuf */
213     if (silc_buffer_taillen(&ps->inbuf) < SILC_PACKET_DEFAULT_SIZE)
214       if (!silc_buffer_realloc(&ps->inbuf, silc_buffer_truelen(&ps->inbuf) +
215                                SILC_PACKET_DEFAULT_SIZE * 2)) {
216         silc_mutex_unlock(ps->lock);
217         return;
218       }
219
220     /* Read data from stream */
221     ret = silc_stream_read(ps->stream, ps->inbuf.tail,
222                            silc_buffer_taillen(&ps->inbuf));
223
224     if (ret == 0) {
225       /* EOS */
226       silc_buffer_reset(&ps->inbuf);
227       silc_mutex_unlock(ps->lock);
228       SILC_PACKET_CALLBACK_EOS(ps);
229       return;
230     }
231
232     if (ret == -2) {
233       /* Error */
234       silc_buffer_reset(&ps->inbuf);
235       silc_mutex_unlock(ps->lock);
236       SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
237       return;
238     }
239
240     if (ret == -1) {
241       /* Cannot read now, do it later. */
242       silc_buffer_pull(&ps->inbuf, silc_buffer_len(&ps->inbuf));
243       silc_mutex_unlock(ps->lock);
244       return;
245     }
246
247     /* Now process the data */
248     silc_buffer_pull_tail(&ps->inbuf, ret);
249     silc_packet_read_process(ps);
250
251     silc_mutex_unlock(ps->lock);
252     break;
253
254   default:
255     silc_mutex_unlock(ps->lock);
256     break;
257   }
258 }
259
260 /* Allocate packet */
261
262 static SilcPacket silc_packet_alloc(SilcPacketEngine engine)
263 {
264   SilcPacket packet;
265
266   SILC_LOG_DEBUG(("Packet pool count %d",
267                   silc_list_count(engine->packet_pool)));
268
269   silc_mutex_lock(engine->lock);
270
271   /* Get packet from freelist or allocate new one. */
272   packet = silc_list_get(engine->packet_pool);
273   if (!packet) {
274     void *tmp;
275
276     silc_mutex_unlock(engine->lock);
277
278     packet = silc_calloc(1, sizeof(*packet));
279     if (!packet)
280       return NULL;
281
282     SILC_LOG_DEBUG(("Allocating new packet %p", packet));
283
284     tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
285     if (!tmp) {
286       silc_free(packet);
287       return NULL;
288     }
289     silc_buffer_set(&packet->buffer, tmp, SILC_PACKET_DEFAULT_SIZE);
290     silc_buffer_reset(&packet->buffer);
291
292     return packet;
293   }
294
295   SILC_LOG_DEBUG(("Get packet %p", packet));
296
297   /* Delete from freelist */
298   silc_list_del(engine->packet_pool, packet);
299
300   silc_mutex_unlock(engine->lock);
301
302   return packet;
303 }
304
305
306 /******************************** Packet API ********************************/
307
308 /* Allocate new packet engine */
309
310 SilcPacketEngine
311 silc_packet_engine_start(SilcRng rng, SilcBool router,
312                          SilcPacketCallbacks *callbacks,
313                          void *callback_context)
314 {
315   SilcPacketEngine engine;
316   SilcPacket packet;
317   int i;
318   void *tmp;
319
320   SILC_LOG_DEBUG(("Starting new packet engine"));
321
322   if (!callbacks)
323     return NULL;
324   if (!callbacks->packet_receive || !callbacks->eos || !callbacks->error)
325     return NULL;
326
327   engine = silc_calloc(1, sizeof(*engine));
328   if (!engine)
329     return NULL;
330
331   engine->rng = rng;
332   engine->local_is_router = router;
333   engine->callbacks = callbacks;
334   engine->callback_context = callback_context;
335   silc_list_init(engine->streams, struct SilcPacketStreamStruct, next);
336   silc_mutex_alloc(&engine->lock);
337
338   /* Allocate packet free list */
339   silc_list_init(engine->packet_pool, struct SilcPacketStruct, next);
340   for (i = 0; i < 5; i++) {
341     packet = silc_calloc(1, sizeof(*packet));
342     if (!packet)
343       return NULL;
344
345     tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
346     if (!tmp)
347       return NULL;
348     silc_buffer_set(&packet->buffer, tmp, SILC_PACKET_DEFAULT_SIZE);
349     silc_buffer_reset(&packet->buffer);
350
351     silc_list_add(engine->packet_pool, packet);
352   }
353   silc_list_start(engine->packet_pool);
354
355   return engine;
356 }
357
358 /* Stop packet engine */
359
360 void silc_packet_engine_stop(SilcPacketEngine engine)
361 {
362
363   SILC_LOG_DEBUG(("Stopping packet engine"));
364
365   if (!engine)
366     return;
367
368   /* XXX */
369
370   silc_free(engine);
371 }
372
373 /* Create new packet stream */
374
375 SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine,
376                                            SilcSchedule schedule,
377                                            SilcStream stream)
378 {
379   SilcPacketStream ps;
380   void *tmp;
381
382   SILC_LOG_DEBUG(("Creating new packet stream"));
383
384   if (!engine || !stream)
385     return NULL;
386
387   ps = silc_calloc(1, sizeof(*ps));
388   if (!ps)
389     return NULL;
390
391   ps->engine = engine;
392   ps->stream = stream;
393   ps->refcnt++;
394
395   /* Allocate buffers */
396   tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
397   if (!tmp)
398     return NULL;
399   silc_buffer_set(&ps->inbuf, tmp, SILC_PACKET_DEFAULT_SIZE);
400   silc_buffer_reset(&ps->inbuf);
401   tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
402   if (!tmp)
403     return NULL;
404   silc_buffer_set(&ps->outbuf, tmp, SILC_PACKET_DEFAULT_SIZE);
405   silc_buffer_reset(&ps->outbuf);
406
407   /* Initialize packet procesors list */
408   ps->process = silc_dlist_init();
409
410   /* Set IO notifier callback */
411   silc_stream_set_notifier(ps->stream, schedule, silc_packet_stream_io, ps);
412
413   silc_mutex_alloc(&ps->lock);
414
415   /* Add to engine */
416   silc_mutex_lock(engine->lock);
417   silc_list_add(engine->streams, ps);
418   silc_mutex_unlock(engine->lock);
419
420   return ps;
421 }
422
423 /* Destroy packet stream */
424
425 void silc_packet_stream_destroy(SilcPacketStream stream)
426 {
427   if (!stream)
428     return;
429
430   if (stream->refcnt > 1) {
431     stream->destroyed = TRUE;
432     return;
433   }
434
435   SILC_LOG_DEBUG(("Destroying packet stream %p", stream));
436
437   /* Delete from engine */
438   silc_mutex_lock(stream->engine->lock);
439   silc_list_del(stream->engine->streams, stream);
440   silc_mutex_unlock(stream->engine->lock);
441
442   /* Clear and free buffers */
443   silc_buffer_clear(&stream->inbuf);
444   silc_buffer_clear(&stream->outbuf);
445   silc_buffer_purge(&stream->inbuf);
446   silc_buffer_purge(&stream->outbuf);
447
448   /* XXX */
449
450   /* Destroy the underlaying stream */
451   silc_stream_destroy(stream->stream);
452
453   silc_dlist_uninit(stream->process);
454   silc_mutex_free(stream->lock);
455   silc_free(stream);
456 }
457
458 /* Marks as router stream */
459
460 void silc_packet_stream_set_router(SilcPacketStream stream)
461 {
462   stream->is_router = TRUE;
463 }
464
465 /* Mark to include IV in ciphertext */
466
467 void silc_packet_stream_set_iv_included(SilcPacketStream stream)
468 {
469   stream->iv_included = TRUE;
470 }
471
472 /* Links `callbacks' to `stream' for specified packet types */
473
474 static SilcBool silc_packet_stream_link_va(SilcPacketStream stream,
475                                            SilcPacketCallbacks *callbacks,
476                                            void *callback_context,
477                                            int priority, va_list ap)
478 {
479   SilcPacketProcess p, e;
480   SilcInt32 packet_type;
481   int i;
482
483   SILC_LOG_DEBUG(("Linking callbacks %p to stream %p", callbacks, stream));
484
485   if (!callbacks)
486     return FALSE;
487   if (!callbacks->packet_receive)
488     return FALSE;
489
490   p = silc_calloc(1, sizeof(*p));
491   if (!p)
492     return FALSE;
493
494   p->priority = priority;
495   p->callbacks = callbacks;
496   p->callback_context = callback_context;
497
498   silc_mutex_lock(stream->lock);
499
500   if (!stream->process) {
501     stream->process = silc_dlist_init();
502     if (!stream->process) {
503       silc_mutex_unlock(stream->lock);
504       return FALSE;
505     }
506   }
507
508   /* According to priority set the procesor to correct position.  First
509      entry has the highest priority */
510   silc_dlist_start(stream->process);
511   while ((e = silc_dlist_get(stream->process)) != SILC_LIST_END) {
512     if (p->priority > e->priority) {
513       silc_dlist_insert(stream->process, p);
514       break;
515     }
516   }
517   if (!e)
518     silc_dlist_add(stream->process, p);
519
520   /* Get packet types to process */
521   i = 1;
522   while (1) {
523     packet_type = va_arg(ap, SilcInt32);
524
525     if (packet_type == SILC_PACKET_ANY)
526       break;
527
528     if (packet_type == -1)
529       break;
530
531     p->types = silc_realloc(p->types, sizeof(*p->types) * (i + 1));
532     if (!p->types) {
533       silc_mutex_unlock(stream->lock);
534       return FALSE;
535     }
536
537     p->types[i - 1] = (SilcPacketType)packet_type;
538     i++;
539   }
540   if (p->types)
541     p->types[i - 1] = 0;
542
543   silc_mutex_unlock(stream->lock);
544
545   silc_packet_stream_ref(stream);
546
547   return TRUE;
548 }
549
550 /* Links `callbacks' to `stream' for specified packet types */
551
552 SilcBool silc_packet_stream_link(SilcPacketStream stream,
553                                  SilcPacketCallbacks *callbacks,
554                                  void *callback_context,
555                                  int priority, ...)
556 {
557   va_list ap;
558   SilcBool ret;
559
560   va_start(ap, priority);
561   ret = silc_packet_stream_link_va(stream, callbacks, callback_context,
562                                    priority, ap);
563   va_end(ap);
564
565   return ret;
566 }
567
568 /* Unlinks `callbacks' from `stream'. */
569
570 void silc_packet_stream_unlink(SilcPacketStream stream,
571                                SilcPacketCallbacks *callbacks,
572                                void *callback_context)
573 {
574   SilcPacketProcess p;
575
576   SILC_LOG_DEBUG(("Unlinking callbacks %p from stream %p",
577                   callbacks, stream));
578
579   silc_mutex_lock(stream->lock);
580
581   silc_dlist_start(stream->process);
582   while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END)
583     if (p->callbacks == callbacks &&
584         p->callback_context == callback_context) {
585       silc_dlist_del(stream->process, p);
586       silc_free(p);
587       break;
588     }
589
590   if (!silc_dlist_count(stream->process)) {
591     silc_dlist_uninit(stream->process);
592     stream->process = NULL;
593   }
594
595   silc_mutex_unlock(stream->lock);
596
597   silc_packet_stream_unref(stream);
598 }
599
600 /* Reference packet stream */
601
602 void silc_packet_stream_ref(SilcPacketStream stream)
603 {
604   silc_mutex_lock(stream->lock);
605   stream->refcnt++;
606   silc_mutex_unlock(stream->lock);
607 }
608
609 /* Unreference packet stream */
610
611 void silc_packet_stream_unref(SilcPacketStream stream)
612 {
613   silc_mutex_lock(stream->lock);
614   stream->refcnt--;
615   silc_mutex_unlock(stream->lock);
616   if (stream->refcnt == 0)
617     silc_packet_stream_destroy(stream);
618 }
619
620 /* Return engine */
621
622 SilcPacketEngine silc_packet_get_engine(SilcPacketStream stream)
623 {
624   return stream->engine;
625 }
626
627 /* Set application context for packet stream */
628
629 void silc_packet_set_context(SilcPacketStream stream, void *stream_context)
630 {
631   silc_mutex_lock(stream->lock);
632   stream->stream_context = stream_context;
633   silc_mutex_unlock(stream->lock);
634 }
635
636 /* Return application context from packet stream */
637
638 void *silc_packet_get_context(SilcPacketStream stream)
639 {
640   void *context;
641   silc_mutex_lock(stream->lock);
642   context = stream->stream_context;
643   silc_mutex_unlock(stream->lock);
644   return context;
645 }
646
647 /* Return underlaying stream */
648
649 SilcStream silc_packet_stream_get_stream(SilcPacketStream stream)
650 {
651   return stream->stream;
652 }
653
654 /* Set ciphers for packet stream */
655
656 void silc_packet_set_ciphers(SilcPacketStream stream, SilcCipher send,
657                              SilcCipher receive)
658 {
659   SILC_LOG_DEBUG(("Setting new ciphers to packet stream"));
660   silc_mutex_lock(stream->lock);
661   stream->send_key = send;
662   stream->receive_key = receive;
663   silc_mutex_unlock(stream->lock);
664 }
665
666 /* Return current ciphers from packet stream */
667
668 SilcBool silc_packet_get_ciphers(SilcPacketStream stream, SilcCipher *send,
669                                  SilcCipher *receive)
670 {
671   if (!stream->send_key && !stream->receive_key)
672     return FALSE;
673
674   silc_mutex_lock(stream->lock);
675
676   if (send)
677     *send = stream->send_key;
678   if (receive)
679     *receive = stream->receive_key;
680
681   silc_mutex_unlock(stream->lock);
682
683   return TRUE;
684 }
685
686 /* Set HMACs for packet stream */
687
688 void silc_packet_set_hmacs(SilcPacketStream stream, SilcHmac send,
689                            SilcHmac receive)
690 {
691   SILC_LOG_DEBUG(("Setting new HMACs to packet stream"));
692   silc_mutex_lock(stream->lock);
693   stream->send_hmac = send;
694   stream->receive_hmac = receive;
695   silc_mutex_unlock(stream->lock);
696 }
697
698 /* Return current HMACs from packet stream */
699
700 SilcBool silc_packet_get_hmacs(SilcPacketStream stream, SilcHmac *send,
701                                SilcHmac *receive)
702 {
703   if (!stream->send_hmac && !stream->receive_hmac)
704     return FALSE;
705
706   silc_mutex_lock(stream->lock);
707
708   if (send)
709     *send = stream->send_hmac;
710   if (receive)
711     *receive = stream->receive_hmac;
712
713   silc_mutex_unlock(stream->lock);
714
715   return TRUE;
716 }
717
718 /* Set SILC IDs to packet stream */
719
720 SilcBool silc_packet_set_ids(SilcPacketStream stream,
721                              SilcIdType src_id_type, const void *src_id,
722                              SilcIdType dst_id_type, const void *dst_id)
723 {
724   SilcUInt32 len;
725   unsigned char tmp[32];
726
727   if (!src_id && !dst_id)
728     return FALSE;
729
730   SILC_LOG_DEBUG(("Setting new IDs to packet stream"));
731
732   silc_mutex_lock(stream->lock);
733
734   if (src_id) {
735     silc_free(stream->src_id);
736     if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) {
737       silc_mutex_unlock(stream->lock);
738       return FALSE;
739     }
740     stream->src_id = silc_memdup(tmp, len);
741     if (!stream->src_id) {
742       silc_mutex_unlock(stream->lock);
743       return FALSE;
744     }
745     stream->src_id_type = src_id_type;
746     stream->src_id_len = len;
747   }
748
749   if (dst_id) {
750     silc_free(stream->dst_id);
751     if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) {
752       silc_mutex_unlock(stream->lock);
753       return FALSE;
754     }
755     stream->dst_id = silc_memdup(tmp, len);
756     if (!stream->dst_id) {
757       silc_mutex_unlock(stream->lock);
758       return FALSE;
759     }
760     stream->dst_id_type = dst_id_type;
761     stream->dst_id_len = len;
762   }
763
764   silc_mutex_unlock(stream->lock);
765
766   return TRUE;
767 }
768
769 /* Free packet */
770
771 void silc_packet_free(SilcPacket packet)
772 {
773   SilcPacketStream stream = packet->stream;
774
775   SILC_LOG_DEBUG(("Freeing packet %p", packet));
776
777 #if defined(SILC_DEBUG)
778   /* Check for double free */
779   assert(packet->stream != NULL);
780 #endif /* SILC_DEBUG */
781
782   silc_mutex_lock(stream->engine->lock);
783
784   packet->stream = NULL;
785   packet->src_id = packet->dst_id = NULL;
786   silc_buffer_reset(&packet->buffer);
787
788   /* Put the packet back to freelist */
789   silc_list_add(stream->engine->packet_pool, packet);
790
791   silc_mutex_unlock(stream->engine->lock);
792 }
793
794 /****************************** Packet Sending ******************************/
795
796 /* Prepare outgoing data buffer for packet sending.  Returns the
797    pointer to that buffer into the `packet'. */
798
799 static SilcBool silc_packet_send_prepare(SilcPacketStream stream,
800                                          SilcUInt32 totlen,
801                                          SilcHmac hmac,
802                                          SilcBuffer packet)
803 {
804   unsigned char *oldptr;
805   unsigned int mac_len = hmac ? silc_hmac_len(hmac) : 0;
806
807   totlen += mac_len;
808
809   /* Allocate more space if needed */
810   if (silc_buffer_taillen(&stream->outbuf) < totlen) {
811     if (!silc_buffer_realloc(&stream->outbuf,
812                              silc_buffer_truelen(&stream->outbuf) + totlen))
813       return FALSE;
814   }
815
816   /* Pull data area for the new packet, and return pointer to the start of
817      the data area and save the pointer in to the `packet'.  MAC is pulled
818      later after it's computed. */
819   oldptr = silc_buffer_pull_tail(&stream->outbuf, totlen);
820   silc_buffer_set(packet, oldptr, totlen);
821   silc_buffer_push_tail(packet, mac_len);
822
823   return TRUE;
824 }
825
826 /* Internal routine to send packet */
827
828 static SilcBool silc_packet_send_raw(SilcPacketStream stream,
829                                      SilcPacketType type,
830                                      SilcPacketFlags flags,
831                                      SilcIdType src_id_type,
832                                      unsigned char *src_id,
833                                      SilcUInt32 src_id_len,
834                                      SilcIdType dst_id_type,
835                                      unsigned char *dst_id,
836                                      SilcUInt32 dst_id_len,
837                                      const unsigned char *data,
838                                      SilcUInt32 data_len,
839                                      SilcCipher cipher,
840                                      SilcHmac hmac)
841 {
842   unsigned char tmppad[SILC_PACKET_MAX_PADLEN], iv[32], psn[4];
843   int block_len = (cipher ? silc_cipher_get_block_len(cipher) : 0);
844   int i, enclen, truelen, padlen, ivlen = 0, psnlen = 0;
845   SilcBufferStruct packet;
846
847   SILC_LOG_DEBUG(("Sending packet %s (%d) flags %d, src %d dst %d,"
848                   "data len %d", silc_get_packet_name(type), stream->send_psn,
849                   flags, src_id_type, dst_id_type, data_len));
850
851   /* Get the true length of the packet. This is saved as payload length
852      into the packet header.  This does not include the length of the
853      padding. */
854   data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
855                                             src_id_len + dst_id_len));
856   enclen = truelen = (data_len + SILC_PACKET_HEADER_LEN +
857                       src_id_len + dst_id_len);
858
859   /* If IV is included, the IV and sequence number is added to packet */
860   if (stream->iv_included && cipher) {
861     ivlen = block_len;
862     psnlen = sizeof(psn);
863     memcpy(iv, silc_cipher_get_iv(cipher), block_len);
864   }
865
866   /* We automatically figure out the packet structure from the packet
867      type and flags, and calculate correct length.  Private messages with
868      private keys and channel messages are special packets as their
869      payload is encrypted already. */
870   if ((type == SILC_PACKET_PRIVATE_MESSAGE &&
871        flags & SILC_PACKET_FLAG_PRIVMSG_KEY) ||
872       type == SILC_PACKET_CHANNEL_MESSAGE) {
873
874     /* Padding is calculated from header + IDs */
875     SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN + src_id_len + dst_id_len +
876                         psnlen), block_len, padlen);
877
878     /* Length to encrypt, header + IDs + padding. */
879     enclen = (SILC_PACKET_HEADER_LEN + src_id_len + dst_id_len +
880               padlen + psnlen);
881   } else {
882
883     /* Padding is calculated from true length of the packet */
884     if (flags & SILC_PACKET_FLAG_LONG_PAD)
885       SILC_PACKET_PADLEN_MAX(truelen + psnlen, block_len, padlen);
886     else
887       SILC_PACKET_PADLEN(truelen + psnlen, block_len, padlen);
888
889     enclen += padlen + psnlen;
890   }
891
892   /* Remove implementation specific flags */
893   flags &= ~(SILC_PACKET_FLAG_LONG_PAD);
894
895   /* Get random padding */
896   for (i = 0; i < padlen; i++) tmppad[i] =
897                                  silc_rng_get_byte_fast(stream->engine->rng);
898
899   silc_mutex_lock(stream->lock);
900
901   /* Get packet pointer from the outgoing buffer */
902   if (!silc_packet_send_prepare(stream, truelen + padlen + ivlen + psnlen,
903                                 hmac, &packet)) {
904     silc_mutex_unlock(stream->lock);
905     return FALSE;
906   }
907
908   SILC_PUT32_MSB(stream->send_psn, psn);
909
910   /* Create the packet.  This creates the SILC header, adds padding, and
911      the actual packet data. */
912   i = silc_buffer_format(&packet,
913                          SILC_STR_UI_XNSTRING(iv, ivlen),
914                          SILC_STR_UI_XNSTRING(psn, psnlen),
915                          SILC_STR_UI_SHORT(truelen),
916                          SILC_STR_UI_CHAR(flags),
917                          SILC_STR_UI_CHAR(type),
918                          SILC_STR_UI_CHAR(padlen),
919                          SILC_STR_UI_CHAR(0),
920                          SILC_STR_UI_CHAR(src_id_len),
921                          SILC_STR_UI_CHAR(dst_id_len),
922                          SILC_STR_UI_CHAR(src_id_type),
923                          SILC_STR_UI_XNSTRING(src_id, src_id_len),
924                          SILC_STR_UI_CHAR(dst_id_type),
925                          SILC_STR_UI_XNSTRING(dst_id, dst_id_len),
926                          SILC_STR_UI_XNSTRING(tmppad, padlen),
927                          SILC_STR_UI_XNSTRING(data, data_len),
928                          SILC_STR_END);
929   if (i < 0) {
930     silc_mutex_unlock(stream->lock);
931     return FALSE;
932   }
933
934   SILC_LOG_HEXDUMP(("Assembled packet, len %d", silc_buffer_len(&packet)),
935                    silc_buffer_data(&packet), silc_buffer_len(&packet));
936
937   /* Encrypt the packet */
938   if (cipher) {
939     SILC_LOG_DEBUG(("Encrypting packet"));
940     if (!silc_cipher_encrypt(cipher, packet.data + ivlen,
941                              packet.data + ivlen, enclen, NULL)) {
942       SILC_LOG_ERROR(("Packet encryption failed"));
943       silc_mutex_unlock(stream->lock);
944       return FALSE;
945     }
946   }
947
948   /* Compute HMAC */
949   if (hmac) {
950     SilcUInt32 mac_len;
951
952     /* MAC is computed from the entire encrypted packet data, and put
953        to the end of the packet. */
954     silc_hmac_init(hmac);
955     silc_hmac_update(hmac, psn, sizeof(psn));
956     silc_hmac_update(hmac, packet.data, silc_buffer_len(&packet));
957     silc_hmac_final(hmac, packet.tail, &mac_len);
958     silc_buffer_pull_tail(&packet, mac_len);
959     stream->send_psn++;
960   }
961
962   /* Write the packet to the stream */
963   while (silc_buffer_len(&stream->outbuf) > 0) {
964     i = silc_stream_write(stream->stream, stream->outbuf.data,
965                           silc_buffer_len(&stream->outbuf));
966     if (i == 0) {
967       /* EOS */
968       silc_buffer_reset(&stream->outbuf);
969       silc_mutex_unlock(stream->lock);
970       SILC_PACKET_CALLBACK_EOS(stream);
971       return FALSE;
972     }
973
974     if (i == -2) {
975       /* Error */
976       silc_buffer_reset(&stream->outbuf);
977       silc_mutex_unlock(stream->lock);
978       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_WRITE);
979       return FALSE;
980     }
981
982     if (i == -1) {
983       /* Cannot write now, write later. */
984       silc_mutex_unlock(stream->lock);
985       return TRUE;
986     }
987
988     /* Wrote data */
989     silc_buffer_pull(&stream->outbuf, i);
990   }
991   silc_buffer_reset(&stream->outbuf);
992
993   silc_mutex_unlock(stream->lock);
994   return TRUE;
995 }
996
997 /* Sends a packet */
998
999 SilcBool silc_packet_send(SilcPacketStream stream,
1000                           SilcPacketType type, SilcPacketFlags flags,
1001                           const unsigned char *data, SilcUInt32 data_len)
1002 {
1003   return silc_packet_send_raw(stream, type, flags,
1004                               stream->src_id_type,
1005                               stream->src_id,
1006                               stream->src_id_len,
1007                               stream->dst_id_type,
1008                               stream->dst_id,
1009                               stream->dst_id_len,
1010                               data, data_len,
1011                               stream->send_key,
1012                               stream->send_hmac);
1013 }
1014
1015 /* Sends a packet, extended routine */
1016
1017 SilcBool silc_packet_send_ext(SilcPacketStream stream,
1018                               SilcPacketType type, SilcPacketFlags flags,
1019                               SilcIdType src_id_type, void *src_id,
1020                               SilcIdType dst_id_type, void *dst_id,
1021                               const unsigned char *data, SilcUInt32 data_len,
1022                               SilcCipher cipher, SilcHmac hmac)
1023 {
1024   unsigned char src_id_data[32], dst_id_data[32];
1025   SilcUInt32 src_id_len, dst_id_len;
1026
1027   if (src_id)
1028     if (!silc_id_id2str(src_id, src_id_type, src_id_data,
1029                         sizeof(src_id_data), &src_id_len))
1030       return FALSE;
1031   if (dst_id)
1032     if (!silc_id_id2str(dst_id, dst_id_type, dst_id_data,
1033                         sizeof(dst_id_data), &dst_id_len))
1034       return FALSE;
1035
1036   return silc_packet_send_raw(stream, type, flags,
1037                               src_id ? src_id_type : stream->src_id_type,
1038                               src_id ? src_id_data : stream->src_id,
1039                               src_id ? src_id_len : stream->src_id_len,
1040                               dst_id ? dst_id_type : stream->dst_id_type,
1041                               dst_id ? dst_id_data : stream->dst_id,
1042                               dst_id ? dst_id_len : stream->dst_id_len,
1043                               data, data_len,
1044                               cipher ? cipher : stream->send_key,
1045                               hmac ? hmac : stream->send_hmac);
1046 }
1047
1048
1049 /***************************** Packet Receiving *****************************/
1050
1051 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. */
1052
1053 static SilcBool silc_packet_check_mac(SilcHmac hmac,
1054                                       const unsigned char *data,
1055                                       SilcUInt32 data_len,
1056                                       const unsigned char *packet_mac,
1057                                       const unsigned char *packet_seq,
1058                                       SilcUInt32 sequence)
1059 {
1060   /* Check MAC */
1061   if (hmac) {
1062     unsigned char mac[32], psn[4];
1063     SilcUInt32 mac_len;
1064
1065     SILC_LOG_DEBUG(("Verifying MAC"));
1066
1067     /* Compute HMAC of packet */
1068     silc_hmac_init(hmac);
1069
1070     if (!packet_seq) {
1071       SILC_PUT32_MSB(sequence, psn);
1072       silc_hmac_update(hmac, psn, 4);
1073     } else
1074       silc_hmac_update(hmac, packet_seq, 4);
1075
1076     silc_hmac_update(hmac, data, data_len);
1077     silc_hmac_final(hmac, mac, &mac_len);
1078
1079     /* Compare the MAC's */
1080     if (memcmp(packet_mac, mac, mac_len)) {
1081       SILC_LOG_DEBUG(("MAC failed"));
1082       return FALSE;
1083     }
1084
1085     SILC_LOG_DEBUG(("MAC is Ok"));
1086   }
1087
1088   return TRUE;
1089 }
1090
1091 /* Decrypts SILC packet.  Handles both normal and special packet decryption.
1092    Return 0 when packet is normal and 1 when it it special, -1 on error. */
1093
1094 static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
1095                                SilcUInt32 sequence, SilcBuffer buffer,
1096                                SilcBool normal)
1097 {
1098   if (normal == TRUE) {
1099     if (cipher) {
1100       /* Decrypt rest of the packet */
1101       SILC_LOG_DEBUG(("Decrypting the packet"));
1102       if (!silc_cipher_decrypt(cipher, buffer->data, buffer->data,
1103                                silc_buffer_len(buffer), NULL))
1104         return -1;
1105     }
1106     return 0;
1107
1108   } else {
1109     /* Decrypt rest of the header plus padding */
1110     if (cipher) {
1111       SilcUInt16 len;
1112       SilcUInt32 block_len = silc_cipher_get_block_len(cipher);
1113
1114       SILC_LOG_DEBUG(("Decrypting the header"));
1115
1116       /* Padding length + src id len + dst id len + header length - 16
1117          bytes already decrypted, gives the rest of the encrypted packet */
1118       silc_buffer_push(buffer, block_len);
1119       len = (((SilcUInt8)buffer->data[4] + (SilcUInt8)buffer->data[6] +
1120               (SilcUInt8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
1121              block_len);
1122       silc_buffer_pull(buffer, block_len);
1123
1124       if (len > silc_buffer_len(buffer)) {
1125         SILC_LOG_ERROR(("Garbage in header of packet, bad packet length, "
1126                         "packet dropped"));
1127         return -1;
1128       }
1129       if (!silc_cipher_decrypt(cipher, buffer->data, buffer->data,
1130                                len, NULL))
1131         return -1;
1132     }
1133
1134     return 1;
1135   }
1136 }
1137
1138 /* Parses the packet. This is called when a whole packet is ready to be
1139    parsed. The buffer sent must be already decrypted before calling this
1140    function. */
1141
1142 static SilcBool silc_packet_parse(SilcPacket packet)
1143 {
1144   SilcBuffer buffer = &packet->buffer;
1145   SilcUInt8 padlen = (SilcUInt8)buffer->data[4];
1146   SilcUInt8 src_id_len, dst_id_len, src_id_type, dst_id_type;
1147   int len, ret;
1148
1149   SILC_LOG_DEBUG(("Parsing incoming packet"));
1150
1151   /* Parse the buffer.  This parses the SILC header of the packet. */
1152   len = silc_buffer_unformat(buffer,
1153                              SILC_STR_OFFSET(6),
1154                              SILC_STR_UI_CHAR(&src_id_len),
1155                              SILC_STR_UI_CHAR(&dst_id_len),
1156                              SILC_STR_UI_CHAR(&src_id_type),
1157                              SILC_STR_END);
1158   if (len == -1) {
1159     SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1160     return FALSE;
1161   }
1162
1163   if (src_id_len > SILC_PACKET_MAX_ID_LEN ||
1164       dst_id_len > SILC_PACKET_MAX_ID_LEN) {
1165     SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
1166                     packet->src_id_len, packet->dst_id_len));
1167     return FALSE;
1168   }
1169
1170   ret = silc_buffer_unformat(buffer,
1171                              SILC_STR_OFFSET(len),
1172                              SILC_STR_UI_XNSTRING(&packet->src_id,
1173                                                   src_id_len),
1174                              SILC_STR_UI_CHAR(&dst_id_type),
1175                              SILC_STR_UI_XNSTRING(&packet->dst_id,
1176                                                   dst_id_len),
1177                              SILC_STR_OFFSET(padlen),
1178                              SILC_STR_END);
1179   if (ret == -1) {
1180     SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1181     return FALSE;
1182   }
1183
1184   if (src_id_type > SILC_ID_CHANNEL ||
1185       dst_id_type > SILC_ID_CHANNEL) {
1186     SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
1187                     src_id_type, dst_id_type));
1188     return FALSE;
1189   }
1190
1191   packet->src_id_len = src_id_len;
1192   packet->dst_id_len = dst_id_len;
1193   packet->src_id_type = src_id_type;
1194   packet->dst_id_type = dst_id_type;
1195
1196   SILC_LOG_HEXDUMP(("Parsed packet, len %d", silc_buffer_len(buffer)),
1197                    buffer->data, silc_buffer_len(buffer));
1198
1199   /* Pull SILC header and padding from packet to get the data payload */
1200   silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
1201                    packet->src_id_len + packet->dst_id_len + padlen);
1202
1203   SILC_LOG_DEBUG(("Incoming packet type: %d (%s)", packet->type,
1204                   silc_get_packet_name(packet->type)));
1205
1206   return TRUE;
1207 }
1208
1209 /* Dispatch packet to application.  Called with stream->lock locked. */
1210
1211 static void silc_packet_dispatch(SilcPacket packet)
1212 {
1213   SilcPacketStream stream = packet->stream;
1214   SilcPacketProcess p;
1215   SilcBool default_sent = FALSE;
1216   SilcPacketType *pt;
1217
1218   /* Parse the packet */
1219   if (!silc_packet_parse(packet)) {
1220     silc_mutex_unlock(packet->stream->lock);
1221     SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
1222     silc_mutex_lock(packet->stream->lock);
1223     silc_packet_free(packet);
1224     return;
1225   }
1226
1227   /* Dispatch packet to all packet processors that want it */
1228
1229   if (!stream->process) {
1230     /* Send to default processor as no others exist */
1231     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1232     silc_mutex_unlock(packet->stream->lock);
1233     if (!stream->engine->callbacks->
1234         packet_receive(stream->engine, stream, packet,
1235                        stream->engine->callback_context,
1236                        stream->stream_context))
1237       silc_packet_free(packet);
1238     silc_mutex_lock(packet->stream->lock);
1239     return;
1240   }
1241
1242   silc_dlist_start(stream->process);
1243   while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END) {
1244
1245     /* If priority is 0 or less, we send to default processor first
1246        because default processor has 0 priority */
1247     if (!default_sent && p->priority <= 0) {
1248       SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1249       default_sent = TRUE;
1250       silc_mutex_unlock(packet->stream->lock);
1251       if (stream->engine->callbacks->
1252           packet_receive(stream->engine, stream, packet,
1253                          stream->engine->callback_context,
1254                          stream->stream_context)) {
1255         silc_mutex_lock(packet->stream->lock);
1256         return;
1257       }
1258       silc_mutex_lock(packet->stream->lock);
1259     }
1260
1261     /* Send to processor */
1262     if (!p->types) {
1263       /* Send all packet types */
1264       SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1265       silc_mutex_unlock(packet->stream->lock);
1266       if (p->callbacks->packet_receive(stream->engine, stream, packet,
1267                                        p->callback_context,
1268                                        stream->stream_context)) {
1269         silc_mutex_lock(packet->stream->lock);
1270         return;
1271       }
1272       silc_mutex_lock(packet->stream->lock);
1273     } else {
1274       /* Send specific types */
1275       for (pt = p->types; *pt; pt++) {
1276         if (*pt != packet->type)
1277           continue;
1278         SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1279         silc_mutex_unlock(packet->stream->lock);
1280         if (p->callbacks->packet_receive(stream->engine, stream, packet,
1281                                          p->callback_context,
1282                                          stream->stream_context)) {
1283           silc_mutex_lock(packet->stream->lock);
1284           return;
1285         }
1286         silc_mutex_lock(packet->stream->lock);
1287         break;
1288       }
1289     }
1290   }
1291
1292   if (!default_sent) {
1293     /* Send to default processor as it has not been sent yet */
1294     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1295     silc_mutex_unlock(packet->stream->lock);
1296     if (stream->engine->callbacks->
1297         packet_receive(stream->engine, stream, packet,
1298                        stream->engine->callback_context,
1299                        stream->stream_context)) {
1300       silc_mutex_lock(packet->stream->lock);
1301       return;
1302     }
1303     silc_mutex_lock(packet->stream->lock);
1304   }
1305
1306   /* If we got here, no one wanted the packet, so drop it */
1307   silc_packet_free(packet);
1308 }
1309
1310 /* Process incoming data and parse packets.  Called with stream->lock
1311    locked. */
1312
1313 static void silc_packet_read_process(SilcPacketStream stream)
1314 {
1315   SilcPacket packet;
1316   SilcUInt16 packetlen;
1317   SilcUInt32 paddedlen, mac_len, block_len, ivlen, psnlen;
1318   unsigned char tmp[SILC_PACKET_MIN_HEADER_LEN], *header;
1319   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE], *packet_seq = NULL;
1320   SilcBool normal = TRUE;
1321   int ret;
1322
1323   /* Parse the packets from the data */
1324   while (silc_buffer_len(&stream->inbuf) > 0) {
1325     ivlen = psnlen = 0;
1326
1327     if (silc_buffer_len(&stream->inbuf) <
1328         stream->iv_included ? SILC_PACKET_MIN_HEADER_LEN :
1329         SILC_PACKET_MIN_HEADER_LEN_IV) {
1330       SILC_LOG_DEBUG(("Partial packet in queue, waiting for the rest"));
1331       return;
1332     }
1333
1334     if (stream->receive_hmac)
1335       mac_len = silc_hmac_len(stream->receive_hmac);
1336     else
1337       mac_len = 0;
1338
1339     /* Decrypt first block of the packet to get the length field out */
1340     if (stream->receive_key) {
1341       block_len = silc_cipher_get_block_len(stream->receive_key);
1342
1343       if (stream->iv_included) {
1344         /* IV is included in the ciphertext */
1345         memcpy(iv, stream->inbuf.data, block_len);
1346         ivlen = block_len;
1347         psnlen = 4;
1348       } else
1349         memcpy(iv, silc_cipher_get_iv(stream->receive_key), block_len);
1350
1351       silc_cipher_decrypt(stream->receive_key, stream->inbuf.data + ivlen,
1352                           tmp, block_len, iv);
1353
1354       header = tmp;
1355       if (stream->iv_included) {
1356         /* Take sequence number from packet */
1357         packet_seq = header;
1358         header += 4;
1359       }
1360     } else {
1361       block_len = SILC_PACKET_MIN_HEADER_LEN;
1362       header = stream->inbuf.data;
1363     }
1364
1365     /* Get packet length and full packet length with padding */
1366     SILC_PACKET_LENGTH(header, packetlen, paddedlen);
1367
1368     /* Sanity checks */
1369     if (packetlen < SILC_PACKET_MIN_LEN) {
1370       SILC_LOG_ERROR(("Received too short packet"));
1371       silc_mutex_unlock(stream->lock);
1372       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
1373       silc_mutex_lock(stream->lock);
1374       memset(tmp, 0, sizeof(tmp));
1375       silc_buffer_reset(&stream->inbuf);
1376       return;
1377     }
1378
1379     if (silc_buffer_len(&stream->inbuf) < paddedlen + ivlen + mac_len) {
1380       SILC_LOG_DEBUG(("Received partial packet, waiting for the rest "
1381                       "(%d bytes)",
1382                       paddedlen + mac_len - silc_buffer_len(&stream->inbuf)));
1383       memset(tmp, 0, sizeof(tmp));
1384       return;
1385     }
1386
1387     /* Check MAC of the packet */
1388     if (!silc_packet_check_mac(stream->receive_hmac, stream->inbuf.data,
1389                                paddedlen + ivlen,
1390                                stream->inbuf.data + ivlen + paddedlen,
1391                                packet_seq, stream->receive_psn)) {
1392       silc_mutex_unlock(stream->lock);
1393       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MAC_FAILED);
1394       silc_mutex_lock(stream->lock);
1395       memset(tmp, 0, sizeof(tmp));
1396       silc_buffer_reset(&stream->inbuf);
1397       return;
1398     }
1399
1400     /* Get packet */
1401     packet = silc_packet_alloc(stream->engine);
1402     if (!packet) {
1403       silc_mutex_unlock(stream->lock);
1404       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
1405       silc_mutex_lock(stream->lock);
1406       memset(tmp, 0, sizeof(tmp));
1407       silc_buffer_reset(&stream->inbuf);
1408       return;
1409     }
1410
1411     /* Allocate more space to packet buffer, if needed */
1412     if (silc_buffer_truelen(&packet->buffer) < paddedlen) {
1413       if (!silc_buffer_realloc(&packet->buffer,
1414                                silc_buffer_truelen(&packet->buffer) +
1415                                (paddedlen -
1416                                 silc_buffer_truelen(&packet->buffer)))) {
1417         silc_mutex_unlock(stream->lock);
1418         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
1419         silc_mutex_lock(stream->lock);
1420         silc_packet_free(packet);
1421         memset(tmp, 0, sizeof(tmp));
1422         silc_buffer_reset(&stream->inbuf);
1423         return;
1424       }
1425     }
1426
1427     /* Parse packet header */
1428     packet->flags = (SilcPacketFlags)header[2];
1429     packet->type = (SilcPacketType)header[3];
1430
1431     if (stream->engine->local_is_router) {
1432       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
1433           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
1434         normal = FALSE;
1435       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE ||
1436                (packet->type == SILC_PACKET_CHANNEL_MESSAGE &&
1437                 stream->is_router == TRUE))
1438         normal = TRUE;
1439     } else {
1440       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
1441           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
1442         normal = FALSE;
1443       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE)
1444         normal = TRUE;
1445     }
1446
1447     SILC_LOG_HEXDUMP(("Incoming packet (%d) len %d",
1448                       stream->receive_psn, paddedlen + ivlen + mac_len),
1449                      stream->inbuf.data, paddedlen + ivlen + mac_len);
1450
1451     /* Put the decrypted part, and rest of the encrypted data, and decrypt */
1452     silc_buffer_pull_tail(&packet->buffer, paddedlen);
1453     silc_buffer_put(&packet->buffer, header, block_len - psnlen);
1454     silc_buffer_pull(&packet->buffer, block_len - psnlen);
1455     silc_buffer_put(&packet->buffer, (stream->inbuf.data + ivlen +
1456                                       psnlen + (block_len - psnlen)),
1457                     paddedlen - ivlen - psnlen - (block_len - psnlen));
1458     if (stream->receive_key) {
1459       silc_cipher_set_iv(stream->receive_key, iv);
1460       ret = silc_packet_decrypt(stream->receive_key, stream->receive_hmac,
1461                                 stream->receive_psn, &packet->buffer, normal);
1462       if (ret < 0) {
1463         silc_mutex_unlock(stream->lock);
1464         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_DECRYPTION_FAILED);
1465         silc_mutex_lock(stream->lock);
1466         silc_packet_free(packet);
1467         memset(tmp, 0, sizeof(tmp));
1468         return;
1469       }
1470
1471       stream->receive_psn++;
1472     }
1473     silc_buffer_push(&packet->buffer, block_len);
1474
1475     /* Pull the packet from inbuf thus we'll get the next one in the inbuf. */
1476     silc_buffer_pull(&stream->inbuf, paddedlen + mac_len);
1477
1478     /* Dispatch the packet to application */
1479     packet->stream = stream;
1480     silc_packet_dispatch(packet);
1481   }
1482
1483   silc_buffer_reset(&stream->inbuf);
1484 }
1485
1486
1487 /****************************** Packet Waiting ******************************/
1488
1489 /* Packet wait receive callback */
1490 static SilcBool
1491 silc_packet_wait_packet_receive(SilcPacketEngine engine,
1492                                 SilcPacketStream stream,
1493                                 SilcPacket packet,
1494                                 void *callback_context,
1495                                 void *stream_context);
1496
1497 /* Packet waiting callbacks */
1498 static SilcPacketCallbacks silc_packet_wait_cbs =
1499 {
1500   silc_packet_wait_packet_receive, NULL, NULL
1501 };
1502
1503 /* Packet waiting context */
1504 typedef struct {
1505   SilcMutex wait_lock;
1506   SilcCond wait_cond;
1507   SilcList packet_queue;
1508   unsigned int stopped     : 1;
1509 } *SilcPacketWait;
1510
1511 /* Packet wait receive callback */
1512
1513 static SilcBool
1514 silc_packet_wait_packet_receive(SilcPacketEngine engine,
1515                                 SilcPacketStream stream,
1516                                 SilcPacket packet,
1517                                 void *callback_context,
1518                                 void *stream_context)
1519 {
1520   SilcPacketWait pw = callback_context;
1521
1522   /* Signal the waiting thread for a new packet */
1523   silc_mutex_lock(pw->wait_lock);
1524
1525   if (pw->stopped) {
1526     silc_mutex_unlock(pw->wait_lock);
1527     return FALSE;
1528   }
1529
1530   silc_list_add(pw->packet_queue, packet);
1531   silc_cond_broadcast(pw->wait_cond);
1532
1533   silc_mutex_unlock(pw->wait_lock);
1534
1535   return TRUE;
1536 }
1537
1538 /* Initialize packet waiting */
1539
1540 void *silc_packet_wait_init(SilcPacketStream stream, ...)
1541 {
1542   SilcPacketWait pw;
1543   SilcBool ret;
1544   va_list ap;
1545
1546   pw = silc_calloc(1, sizeof(*pw));
1547   if (!pw)
1548     return NULL;
1549
1550   /* Allocate mutex and conditional variable */
1551   if (!silc_mutex_alloc(&pw->wait_lock)) {
1552     silc_free(pw);
1553     return NULL;
1554   }
1555   if (!silc_cond_alloc(&pw->wait_cond)) {
1556     silc_mutex_free(pw->wait_lock);
1557     silc_free(pw);
1558     return NULL;
1559   }
1560
1561   /* Link to the packet stream for the requested packet types */
1562   va_start(ap, stream);
1563   ret = silc_packet_stream_link_va(stream, &silc_packet_wait_cbs, pw,
1564                                    10000000, ap);
1565   va_end(ap);
1566   if (!ret) {
1567     silc_cond_free(pw->wait_cond);
1568     silc_mutex_free(pw->wait_lock);
1569     silc_free(pw);
1570     return NULL;
1571   }
1572
1573   /* Initialize packet queue */
1574   silc_list_init(pw->packet_queue, struct SilcPacketStruct, next);
1575
1576   return (void *)pw;
1577 }
1578
1579 /* Uninitialize packet waiting */
1580
1581 void silc_packet_wait_uninit(void *waiter, SilcPacketStream stream)
1582 {
1583   SilcPacketWait pw = waiter;
1584   SilcPacket packet;
1585
1586   /* Signal any threads to stop waiting */
1587   silc_mutex_lock(pw->wait_lock);
1588   pw->stopped = TRUE;
1589   silc_cond_broadcast(pw->wait_cond);
1590   silc_mutex_unlock(pw->wait_lock);
1591
1592   /* Re-acquire lock and free resources */
1593   silc_mutex_lock(pw->wait_lock);
1594   silc_packet_stream_unlink(stream, &silc_packet_wait_cbs, pw);
1595
1596   /* Free any remaining packets */
1597   silc_list_start(pw->packet_queue);
1598   while ((packet = silc_list_get(pw->packet_queue)) != SILC_LIST_END)
1599     silc_packet_free(packet);
1600
1601   silc_mutex_unlock(pw->wait_lock);
1602   silc_cond_free(pw->wait_cond);
1603   silc_mutex_free(pw->wait_lock);
1604   silc_free(pw);
1605 }
1606
1607 /* Blocks thread until a packet has been received. */
1608
1609 int silc_packet_wait(void *waiter, int timeout, SilcPacket *return_packet)
1610 {
1611   SilcPacketWait pw = waiter;
1612   SilcBool ret = FALSE;
1613
1614   silc_mutex_lock(pw->wait_lock);
1615
1616   /* Wait here until packet has arrived */
1617   while (silc_list_count(pw->packet_queue) == 0) {
1618     if (pw->stopped) {
1619       silc_mutex_unlock(pw->wait_lock);
1620       return -1;
1621     }
1622     ret = silc_cond_timedwait(pw->wait_cond, pw->wait_lock, timeout);
1623   }
1624
1625   /* Return packet */
1626   silc_list_start(pw->packet_queue);
1627   *return_packet = silc_list_get(pw->packet_queue);
1628   silc_list_del(pw->packet_queue, *return_packet);
1629
1630   silc_mutex_unlock(pw->wait_lock);
1631
1632   return ret == TRUE ? 1 : 0;
1633 }