Added preliminary Symbian support.
[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 /* Per scheduler (which usually means per thread) data.  We put per scheduler
29    data here for accessing without locking.  SILC Schedule dictates that
30    tasks are dispatched in one thread, hence the per scheduler context. */
31 typedef struct {
32   SilcSchedule schedule;                 /* The scheduler */
33   SilcPacketEngine engine;               /* Packet engine */
34   SilcBufferStruct inbuf;                /* Data input buffer */
35   SilcUInt32 stream_count;               /* Number of streams using this */
36 } *SilcPacketEngineContext;
37
38 /* Packet engine */
39 struct SilcPacketEngineStruct {
40   SilcMutex lock;                        /* Engine lock */
41   SilcRng rng;                           /* RNG for engine */
42   SilcHashTable contexts;                /* Per scheduler contexts */
43   SilcPacketCallbacks *callbacks;        /* Packet callbacks */
44   void *callback_context;                /* Context for callbacks */
45   SilcList streams;                      /* All streams in engine */
46   SilcList packet_pool;                  /* Free list for received packets */
47   SilcHashTable udp_remote;              /* UDP remote streams, or NULL */
48   unsigned int local_is_router    : 1;
49 };
50
51 /* Packet processor context */
52 typedef struct SilcPacketProcessStruct {
53   SilcPacketType *types;                 /* Packets to process */
54   SilcPacketCallbacks *callbacks;        /* Callbacks or NULL */
55   void *callback_context;
56   SilcInt32 priority;                    /* Priority */
57 } *SilcPacketProcess;
58
59 /* UDP remote stream tuple */
60 typedef struct {
61   char *remote_ip;                       /* Remote IP address */
62   SilcUInt16 remote_port;                /* Remote port */
63 } *SilcPacketRemoteUDP;
64
65 /* Packet stream */
66 struct SilcPacketStreamStruct {
67   struct SilcPacketStreamStruct *next;
68   SilcPacketEngineContext sc;            /* Per scheduler context */
69   SilcStream stream;                     /* Underlaying stream */
70   SilcMutex lock;                        /* Stream lock */
71   SilcDList process;                     /* Packet processors, or NULL */
72   SilcPacketRemoteUDP remote_udp;        /* UDP remote stream tuple, or NULL */
73   void *stream_context;                  /* Stream context */
74   SilcBufferStruct outbuf;               /* Out buffer */
75   SilcCipher send_key[2];                /* Sending key */
76   SilcHmac send_hmac[2];                 /* Sending HMAC */
77   SilcCipher receive_key[2];             /* Receiving key */
78   SilcHmac receive_hmac[2];              /* Receiving HMAC */
79   unsigned char *src_id;                 /* Source ID */
80   unsigned char *dst_id;                 /* Destination ID */
81   SilcUInt32 send_psn;                   /* Sending sequence */
82   SilcUInt32 receive_psn;                /* Receiving sequence */
83   SilcAtomic8 refcnt;                    /* Reference counter */
84   SilcUInt8 sid;                         /* Security ID, set if IV included */
85   unsigned int src_id_len  : 6;
86   unsigned int src_id_type : 2;
87   unsigned int dst_id_len  : 6;
88   unsigned int dst_id_type : 2;
89   unsigned int is_router   : 1;          /* Set if router stream */
90   unsigned int destroyed   : 1;          /* Set if destroyed */
91   unsigned int iv_included : 1;          /* Set if IV included */
92   unsigned int udp         : 1;          /* UDP remote stream */
93 };
94
95 /* Initial size of stream buffers */
96 #define SILC_PACKET_DEFAULT_SIZE  1024
97
98 /* Header length without source and destination ID's. */
99 #define SILC_PACKET_HEADER_LEN 10
100
101 /* Minimum length of SILC Packet Header. */
102 #define SILC_PACKET_MIN_HEADER_LEN 16
103 #define SILC_PACKET_MIN_HEADER_LEN_IV 32 + 1
104
105 /* Maximum padding length */
106 #define SILC_PACKET_MAX_PADLEN 128
107
108 /* Default padding length */
109 #define SILC_PACKET_DEFAULT_PADLEN 16
110
111 /* Minimum packet length */
112 #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1)
113
114 /* Returns true length of the packet. */
115 #define SILC_PACKET_LENGTH(__packetdata, __ret_truelen, __ret_paddedlen) \
116 do {                                                                     \
117   SILC_GET16_MSB((__ret_truelen), (__packetdata));                       \
118   (__ret_paddedlen) = (__ret_truelen) + (SilcUInt8)(__packetdata)[4];    \
119 } while(0)
120
121 /* Calculates the data length with given header length.  This macro
122    can be used to check whether the data_len with header_len exceeds
123    SILC_PACKET_MAX_LEN.  If it does, this returns the new data_len
124    so that the SILC_PACKET_MAX_LEN is not exceeded.  If the data_len
125    plus header_len fits SILC_PACKET_MAX_LEN the returned data length
126    is the data_len given as argument. */
127 #define SILC_PACKET_DATALEN(data_len, header_len)                         \
128   ((data_len + header_len) > SILC_PACKET_MAX_LEN ?                        \
129    data_len - ((data_len + header_len) - SILC_PACKET_MAX_LEN) : data_len)
130
131 /* Calculates the length of the padding in the packet. */
132 #define SILC_PACKET_PADLEN(__packetlen, __blocklen, __padlen)               \
133 do {                                                                        \
134   __padlen = (SILC_PACKET_DEFAULT_PADLEN - (__packetlen) %                  \
135               ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN));  \
136   if (__padlen < 8)                                                         \
137     __padlen += ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN); \
138 } while(0)
139
140 /* Returns the length of the padding up to the maximum length, which
141    is 128 bytes.*/
142 #define SILC_PACKET_PADLEN_MAX(__packetlen, __blocklen, __padlen)          \
143 do {                                                                       \
144   __padlen = (SILC_PACKET_MAX_PADLEN - (__packetlen) %                     \
145               ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN)); \
146 } while(0)
147
148 /* EOS callback */
149 #define SILC_PACKET_CALLBACK_EOS(s)                                     \
150 do {                                                                    \
151   (s)->sc->engine->callbacks->eos((s)->sc->engine, s,                   \
152                                   (s)->sc->engine->callback_context,    \
153                                   (s)->stream_context);                 \
154 } while(0)
155
156 /* Error callback */
157 #define SILC_PACKET_CALLBACK_ERROR(s, err)                              \
158 do {                                                                    \
159   (s)->sc->engine->callbacks->error((s)->sc->engine, s, err,            \
160                                     (s)->sc->engine->callback_context,  \
161                                     (s)->stream_context);               \
162 } while(0)
163
164 static SilcBool silc_packet_dispatch(SilcPacket packet);
165 static void silc_packet_read_process(SilcPacketStream stream);
166 static inline SilcBool silc_packet_send_raw(SilcPacketStream stream,
167                                             SilcPacketType type,
168                                             SilcPacketFlags flags,
169                                             SilcIdType src_id_type,
170                                             unsigned char *src_id,
171                                             SilcUInt32 src_id_len,
172                                             SilcIdType dst_id_type,
173                                             unsigned char *dst_id,
174                                             SilcUInt32 dst_id_len,
175                                             const unsigned char *data,
176                                             SilcUInt32 data_len,
177                                             SilcCipher cipher,
178                                             SilcHmac hmac);
179
180 /************************ Static utility functions **************************/
181
182 /* Injects packet to new stream created with silc_packet_stream_add_remote. */
183
184 SILC_TASK_CALLBACK(silc_packet_stream_inject_packet)
185 {
186   SilcPacket packet = context;
187   SilcPacketStream stream = packet->stream;
188
189   SILC_LOG_DEBUG(("Injecting packet %p to stream %p", packet, packet->stream));
190
191   silc_mutex_lock(stream->lock);
192   if (!stream->destroyed)
193     silc_packet_dispatch(packet);
194   silc_mutex_unlock(stream->lock);
195   silc_packet_stream_unref(stream);
196 }
197
198 /* Write data to the stream.  Must be called with ps->lock locked.  Unlocks
199    the lock inside this function, unless no_unlock is TRUE.  Unlocks always
200    in case it returns FALSE. */
201
202 static inline SilcBool silc_packet_stream_write(SilcPacketStream ps,
203                                                 SilcBool no_unlock)
204 {
205   SilcStream stream;
206   SilcBool connected;
207   int i;
208
209   if (ps->udp)
210     stream = ((SilcPacketStream)ps->stream)->stream;
211   else
212     stream = ps->stream;
213
214   if (ps->udp && silc_socket_stream_is_udp(stream, &connected)) {
215     if (!connected) {
216       /* Connectionless UDP stream */
217       while (silc_buffer_len(&ps->outbuf) > 0) {
218         i = silc_net_udp_send(stream, ps->remote_udp->remote_ip,
219                               ps->remote_udp->remote_port,
220                               ps->outbuf.data, silc_buffer_len(&ps->outbuf));
221         if (silc_unlikely(i == -2)) {
222           /* Error */
223           silc_buffer_reset(&ps->outbuf);
224           SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_WRITE);
225           return FALSE;
226         }
227
228         if (silc_unlikely(i == -1)) {
229           /* Cannot write now, write later. */
230           if (!no_unlock)
231             silc_mutex_unlock(ps->lock);
232           return TRUE;
233         }
234
235         /* Wrote data */
236         silc_buffer_pull(&ps->outbuf, i);
237       }
238
239       silc_buffer_reset(&ps->outbuf);
240       if (!no_unlock)
241         silc_mutex_unlock(ps->lock);
242
243       return TRUE;
244     }
245   }
246
247   /* Write the data to the stream */
248   while (silc_buffer_len(&ps->outbuf) > 0) {
249     i = silc_stream_write(stream, ps->outbuf.data,
250                           silc_buffer_len(&ps->outbuf));
251     if (silc_unlikely(i == 0)) {
252       /* EOS */
253       silc_buffer_reset(&ps->outbuf);
254       silc_mutex_unlock(ps->lock);
255       SILC_PACKET_CALLBACK_EOS(ps);
256       return FALSE;
257     }
258
259     if (silc_unlikely(i == -2)) {
260       /* Error */
261       silc_buffer_reset(&ps->outbuf);
262       silc_mutex_unlock(ps->lock);
263       SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_WRITE);
264       return FALSE;
265     }
266
267     if (silc_unlikely(i == -1)) {
268       /* Cannot write now, write later. */
269       if (!no_unlock)
270         silc_mutex_unlock(ps->lock);
271       return TRUE;
272     }
273
274     /* Wrote data */
275     silc_buffer_pull(&ps->outbuf, i);
276   }
277
278   silc_buffer_reset(&ps->outbuf);
279   if (!no_unlock)
280     silc_mutex_unlock(ps->lock);
281
282   return TRUE;
283 }
284
285 /* Reads data from stream.  Must be called with ps->lock locked.  If this
286    returns FALSE the lock has been unlocked.  If this returns packet stream
287    to `ret_ps' its lock has been acquired and `ps' lock has been unlocked.
288    It is returned if the stream is UDP and remote UDP stream exists for
289    the sender of the packet. */
290
291 static inline SilcBool silc_packet_stream_read(SilcPacketStream ps,
292                                                SilcPacketStream *ret_ps)
293 {
294   SilcStream stream;
295   SilcBuffer inbuf;
296   SilcBool connected;
297   int ret;
298
299   stream = ps->stream;
300   inbuf = &ps->sc->inbuf;
301
302   if (silc_socket_stream_is_udp(stream, &connected)) {
303     if (!connected) {
304       /* Connectionless UDP stream, read one UDP packet */
305       char remote_ip[64], tuple[64];
306       int remote_port;
307       SilcPacketStream remote;
308
309       ret = silc_net_udp_receive(stream, remote_ip, sizeof(remote_ip),
310                                  &remote_port, inbuf->tail,
311                                  silc_buffer_taillen(inbuf));
312
313       if (silc_unlikely(ret < 0)) {
314         silc_mutex_unlock(ps->lock);
315         if (ret == -1) {
316           /* Cannot read now, do it later. */
317           silc_buffer_pull(inbuf, silc_buffer_len(inbuf));
318           return FALSE;
319         }
320
321         /* Error */
322         silc_buffer_reset(inbuf);
323         SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
324         return FALSE;
325       }
326
327       /* See if remote packet stream exist for this sender */
328       silc_snprintf(tuple, sizeof(tuple), "%d%s", remote_port, remote_ip);
329       silc_mutex_lock(ps->sc->engine->lock);
330       if (silc_hash_table_find(ps->sc->engine->udp_remote, tuple, NULL,
331                                (void *)&remote)) {
332         silc_mutex_unlock(ps->sc->engine->lock);
333         SILC_LOG_DEBUG(("UDP packet from %s:%d for stream %p", remote_ip,
334                         remote_port, remote));
335         silc_mutex_unlock(ps->lock);
336         silc_mutex_lock(remote->lock);
337         *ret_ps = remote;
338         return TRUE;
339       }
340       silc_mutex_unlock(ps->sc->engine->lock);
341
342       /* Unknown sender */
343       if (!ps->remote_udp) {
344         ps->remote_udp = silc_calloc(1, sizeof(*ps->remote_udp));
345         if (silc_unlikely(!ps->remote_udp)) {
346           silc_mutex_unlock(ps->lock);
347           SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_NO_MEMORY);
348           return FALSE;
349         }
350       }
351
352       /* Save sender IP and port */
353       silc_free(ps->remote_udp->remote_ip);
354       ps->remote_udp->remote_ip = strdup(remote_ip);
355       ps->remote_udp->remote_port = remote_port;
356
357       silc_buffer_pull_tail(inbuf, ret);
358       return TRUE;
359     }
360   }
361
362   /* Read data from the stream */
363   ret = silc_stream_read(stream, inbuf->tail, silc_buffer_taillen(inbuf));
364   if (silc_unlikely(ret <= 0)) {
365     silc_mutex_unlock(ps->lock);
366     if (ret == 0) {
367       /* EOS */
368       silc_buffer_reset(inbuf);
369       SILC_PACKET_CALLBACK_EOS(ps);
370       return FALSE;
371     }
372
373     if (ret == -1) {
374       /* Cannot read now, do it later. */
375       silc_buffer_pull(inbuf, silc_buffer_len(inbuf));
376       return FALSE;
377     }
378
379     /* Error */
380     silc_buffer_reset(inbuf);
381     SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
382     return FALSE;
383   }
384
385   silc_buffer_pull_tail(inbuf, ret);
386   return TRUE;
387 }
388
389 /* Our stream IO notifier callback. */
390
391 static void silc_packet_stream_io(SilcStream stream, SilcStreamStatus status,
392                                   void *context)
393 {
394   SilcPacketStream remote = NULL, ps = context;
395
396   silc_mutex_lock(ps->lock);
397
398   if (silc_unlikely(ps->destroyed)) {
399     silc_mutex_unlock(ps->lock);
400     return;
401   }
402
403   switch (status) {
404   case SILC_STREAM_CAN_READ:
405     SILC_LOG_DEBUG(("Reading data from stream"));
406
407     /* Read data from stream */
408     if (!silc_packet_stream_read(ps, &remote))
409       return;
410
411     /* Now process the data */
412     silc_packet_stream_ref(ps);
413     if (!remote) {
414       silc_packet_read_process(ps);
415       silc_mutex_unlock(ps->lock);
416     } else {
417       silc_packet_read_process(remote);
418       silc_mutex_unlock(remote->lock);
419     }
420     silc_packet_stream_unref(ps);
421     break;
422
423   case SILC_STREAM_CAN_WRITE:
424     SILC_LOG_DEBUG(("Writing pending data to stream"));
425
426     if (silc_unlikely(!silc_buffer_headlen(&ps->outbuf))) {
427       silc_mutex_unlock(ps->lock);
428       return;
429     }
430
431     /* Write pending data to stream */
432     silc_packet_stream_write(ps, FALSE);
433     break;
434
435   default:
436     silc_mutex_unlock(ps->lock);
437     break;
438   }
439 }
440
441 /* Allocate packet */
442
443 static SilcPacket silc_packet_alloc(SilcPacketEngine engine)
444 {
445   SilcPacket packet;
446
447   SILC_LOG_DEBUG(("Packet pool count %d",
448                   silc_list_count(engine->packet_pool)));
449
450   silc_mutex_lock(engine->lock);
451
452   /* Get packet from freelist or allocate new one. */
453   packet = silc_list_get(engine->packet_pool);
454   if (!packet) {
455     void *tmp;
456
457     silc_mutex_unlock(engine->lock);
458
459     packet = silc_calloc(1, sizeof(*packet));
460     if (silc_unlikely(!packet))
461       return NULL;
462
463     SILC_LOG_DEBUG(("Allocating new packet %p", packet));
464
465     tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
466     if (silc_unlikely(!tmp)) {
467       silc_free(packet);
468       return NULL;
469     }
470     silc_buffer_set(&packet->buffer, tmp, SILC_PACKET_DEFAULT_SIZE);
471     silc_buffer_reset(&packet->buffer);
472
473     return packet;
474   }
475
476   SILC_LOG_DEBUG(("Get packet %p", packet));
477
478   /* Delete from freelist */
479   silc_list_del(engine->packet_pool, packet);
480
481   silc_mutex_unlock(engine->lock);
482
483   return packet;
484 }
485
486 /* UDP remote stream hash table destructor */
487
488 static void silc_packet_engine_hash_destr(void *key, void *context,
489                                           void *user_context)
490 {
491   silc_free(key);
492 }
493
494 /* Per scheduler context hash table destructor */
495
496 static void silc_packet_engine_context_destr(void *key, void *context,
497                                              void *user_context)
498 {
499   SilcPacketEngineContext sc = context;
500   silc_buffer_clear(&sc->inbuf);
501   silc_buffer_purge(&sc->inbuf);
502   silc_free(sc);
503 }
504
505
506 /******************************** Packet API ********************************/
507
508 /* Allocate new packet engine */
509
510 SilcPacketEngine
511 silc_packet_engine_start(SilcRng rng, SilcBool router,
512                          SilcPacketCallbacks *callbacks,
513                          void *callback_context)
514 {
515   SilcPacketEngine engine;
516   SilcPacket packet;
517   int i;
518   void *tmp;
519
520   SILC_LOG_DEBUG(("Starting new packet engine"));
521
522   if (!callbacks)
523     return NULL;
524   if (!callbacks->packet_receive || !callbacks->eos || !callbacks->error)
525     return NULL;
526
527   engine = silc_calloc(1, sizeof(*engine));
528   if (!engine)
529     return NULL;
530
531   engine->contexts = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
532                                            silc_packet_engine_context_destr,
533                                            engine, TRUE);
534   if (!engine->contexts) {
535     silc_free(engine);
536     return NULL;
537   }
538
539   engine->rng = rng;
540   engine->local_is_router = router;
541   engine->callbacks = callbacks;
542   engine->callback_context = callback_context;
543   silc_list_init(engine->streams, struct SilcPacketStreamStruct, next);
544   silc_mutex_alloc(&engine->lock);
545
546   /* Allocate packet free list */
547   silc_list_init(engine->packet_pool, struct SilcPacketStruct, next);
548   for (i = 0; i < 5; i++) {
549     packet = silc_calloc(1, sizeof(*packet));
550     if (!packet) {
551       silc_packet_engine_stop(engine);
552       return NULL;
553     }
554
555     tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
556     if (!tmp) {
557       silc_packet_engine_stop(engine);
558       return NULL;
559     }
560     silc_buffer_set(&packet->buffer, tmp, SILC_PACKET_DEFAULT_SIZE);
561     silc_buffer_reset(&packet->buffer);
562
563     silc_list_add(engine->packet_pool, packet);
564   }
565   silc_list_start(engine->packet_pool);
566
567   return engine;
568 }
569
570 /* Stop packet engine */
571
572 void silc_packet_engine_stop(SilcPacketEngine engine)
573 {
574
575   SILC_LOG_DEBUG(("Stopping packet engine"));
576
577   if (!engine)
578     return;
579
580   /* XXX */
581
582   silc_free(engine);
583 }
584
585 /* Create new packet stream */
586
587 SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine,
588                                            SilcSchedule schedule,
589                                            SilcStream stream)
590 {
591   SilcPacketStream ps;
592   void *tmp;
593
594   SILC_LOG_DEBUG(("Creating new packet stream"));
595
596   if (!engine || !stream)
597     return NULL;
598
599   ps = silc_calloc(1, sizeof(*ps));
600   if (!ps)
601     return NULL;
602
603   ps->stream = stream;
604   silc_atomic_init8(&ps->refcnt, 1);
605   silc_mutex_alloc(&ps->lock);
606
607   /* Allocate out buffer */
608   tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
609   if (!tmp) {
610     silc_packet_stream_destroy(ps);
611     return NULL;
612   }
613   silc_buffer_set(&ps->outbuf, tmp, SILC_PACKET_DEFAULT_SIZE);
614   silc_buffer_reset(&ps->outbuf);
615
616   /* Initialize packet procesors list */
617   ps->process = silc_dlist_init();
618   if (!ps->process) {
619     silc_packet_stream_destroy(ps);
620     return NULL;
621   }
622
623   silc_mutex_lock(engine->lock);
624
625   /* Add per scheduler context */
626   if (!silc_hash_table_find(engine->contexts, schedule, NULL,
627                             (void *)&ps->sc)) {
628     ps->sc = silc_calloc(1, sizeof(*ps->sc));
629     if (!ps->sc) {
630       silc_packet_stream_destroy(ps);
631       silc_mutex_unlock(engine->lock);
632       return NULL;
633     }
634     ps->sc->engine = engine;
635     ps->sc->schedule = schedule;
636
637     /* Allocate data input buffer */
638     tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE * 31);
639     if (!tmp) {
640       silc_free(ps->sc);
641       ps->sc = NULL;
642       silc_packet_stream_destroy(ps);
643       silc_mutex_unlock(engine->lock);
644       return NULL;
645     }
646     silc_buffer_set(&ps->sc->inbuf, tmp, SILC_PACKET_DEFAULT_SIZE * 31);
647     silc_buffer_reset(&ps->sc->inbuf);
648
649     /* Add to per scheduler context hash table */
650     if (!silc_hash_table_add(engine->contexts, schedule, ps->sc)) {
651       silc_buffer_purge(&ps->sc->inbuf);
652       silc_free(ps->sc);
653       ps->sc = NULL;
654       silc_packet_stream_destroy(ps);
655       silc_mutex_unlock(engine->lock);
656       return NULL;
657     }
658   }
659   ps->sc->stream_count++;
660
661   /* Add the packet stream to engine */
662   silc_list_add(engine->streams, ps);
663
664   /* If this is UDP stream, allocate UDP remote stream hash table */
665   if (!engine->udp_remote && silc_socket_stream_is_udp(stream, NULL))
666     engine->udp_remote = silc_hash_table_alloc(0, silc_hash_string, NULL,
667                                                silc_hash_string_compare, NULL,
668                                                silc_packet_engine_hash_destr,
669                                                NULL, TRUE);
670   silc_mutex_unlock(engine->lock);
671
672   /* Set IO notifier callback.  This schedules this stream for I/O. */
673   silc_stream_set_notifier(ps->stream, schedule, silc_packet_stream_io, ps);
674
675   return ps;
676 }
677
678 /* Add new remote packet stream for UDP packet streams */
679
680 SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream,
681                                                const char *remote_ip,
682                                                SilcUInt16 remote_port,
683                                                SilcPacket packet)
684 {
685   SilcPacketEngine engine = stream->sc->engine;
686   SilcPacketStream ps;
687   char *tuple;
688   void *tmp;
689
690   SILC_LOG_DEBUG(("Adding UDP remote %s:%d to packet stream %p",
691                   remote_ip, remote_port, stream));
692
693   if (!stream || !remote_ip || !remote_port)
694     return NULL;
695
696   if (!silc_socket_stream_is_udp(stream->stream, NULL)) {
697     SILC_LOG_ERROR(("Stream is not UDP stream, cannot add remote IP"));
698     return NULL;
699   }
700
701   ps = silc_calloc(1, sizeof(*ps));
702   if (!ps)
703     return NULL;
704   ps->sc = stream->sc;
705
706   silc_atomic_init8(&ps->refcnt, 1);
707   silc_mutex_alloc(&ps->lock);
708
709   /* Set the UDP packet stream as underlaying stream */
710   silc_packet_stream_ref(stream);
711   ps->stream = (SilcStream)stream;
712   ps->udp = TRUE;
713
714   /* Allocate out buffer */
715   tmp = silc_malloc(SILC_PACKET_DEFAULT_SIZE);
716   if (!tmp) {
717     silc_packet_stream_destroy(ps);
718     return NULL;
719   }
720   silc_buffer_set(&ps->outbuf, tmp, SILC_PACKET_DEFAULT_SIZE);
721   silc_buffer_reset(&ps->outbuf);
722
723   /* Initialize packet procesors list */
724   ps->process = silc_dlist_init();
725   if (!ps->process) {
726     silc_packet_stream_destroy(ps);
727     return NULL;
728   }
729
730   /* Add to engine with this IP and port pair */
731   tuple = silc_format("%d%s", remote_port, remote_ip);
732   silc_mutex_lock(engine->lock);
733   if (!tuple || !silc_hash_table_add(engine->udp_remote, tuple, ps)) {
734     silc_mutex_unlock(engine->lock);
735     silc_packet_stream_destroy(ps);
736     return NULL;
737   }
738   silc_mutex_unlock(engine->lock);
739
740   /* Save remote IP and port pair */
741   ps->remote_udp = silc_calloc(1, sizeof(*ps->remote_udp));
742   if (!ps->remote_udp) {
743     silc_packet_stream_destroy(ps);
744     return NULL;
745   }
746   ps->remote_udp->remote_port = remote_port;
747   ps->remote_udp->remote_ip = strdup(remote_ip);
748   if (!ps->remote_udp->remote_ip) {
749     silc_packet_stream_destroy(ps);
750     return NULL;
751   }
752
753   if (packet) {
754     /* Inject packet to the new stream */
755     packet->stream = ps;
756     silc_packet_stream_ref(ps);
757     silc_schedule_task_add_timeout(silc_stream_get_schedule(stream->stream),
758                                    silc_packet_stream_inject_packet, packet,
759                                    0, 0);
760   }
761
762   return ps;
763 }
764
765 /* Destroy packet stream */
766
767 void silc_packet_stream_destroy(SilcPacketStream stream)
768 {
769   if (!stream)
770     return;
771
772   if (silc_atomic_get_int8(&stream->refcnt) > 1) {
773     stream->destroyed = TRUE;
774     return;
775   }
776
777   SILC_LOG_DEBUG(("Destroying packet stream %p", stream));
778
779   if (!stream->udp) {
780     /* Delete from engine */
781     silc_mutex_lock(stream->sc->engine->lock);
782     silc_list_del(stream->sc->engine->streams, stream);
783
784     /* Remove per scheduler context, if it is not used anymore */
785     if (stream->sc) {
786       stream->sc->stream_count--;
787       if (!stream->sc->stream_count)
788         silc_hash_table_del(stream->sc->engine->contexts,
789                             stream->sc->schedule);
790     }
791     silc_mutex_unlock(stream->sc->engine->lock);
792
793     /* Destroy the underlaying stream */
794     if (stream->stream)
795       silc_stream_destroy(stream->stream);
796   } else {
797     /* Delete from UDP remote hash table */
798     char tuple[64];
799     silc_snprintf(tuple, sizeof(tuple), "%d%s", stream->remote_udp->remote_port,
800              stream->remote_udp->remote_ip);
801     silc_mutex_lock(stream->sc->engine->lock);
802     silc_hash_table_del(stream->sc->engine->udp_remote, tuple);
803     silc_mutex_unlock(stream->sc->engine->lock);
804
805     silc_free(stream->remote_udp->remote_ip);
806     silc_free(stream->remote_udp);
807
808     /* Unreference the underlaying packet stream */
809     silc_packet_stream_unref((SilcPacketStream)stream->stream);
810   }
811
812   /* Clear and free buffers */
813   silc_buffer_clear(&stream->outbuf);
814   silc_buffer_purge(&stream->outbuf);
815
816   if (stream->process) {
817     SilcPacketProcess p;
818     silc_dlist_start(stream->process);
819     while ((p = silc_dlist_get(stream->process))) {
820       silc_free(p->types);
821       silc_free(p);
822       silc_dlist_del(stream->process, p);
823     }
824     silc_dlist_uninit(stream->process);
825   }
826
827   /* XXX */
828
829   silc_atomic_uninit8(&stream->refcnt);
830   silc_mutex_free(stream->lock);
831   silc_free(stream);
832 }
833
834 /* Marks as router stream */
835
836 void silc_packet_stream_set_router(SilcPacketStream stream)
837 {
838   stream->is_router = TRUE;
839 }
840
841 /* Mark to include IV in ciphertext */
842
843 void silc_packet_stream_set_iv_included(SilcPacketStream stream)
844 {
845   stream->iv_included = TRUE;
846 }
847
848 /* Links `callbacks' to `stream' for specified packet types */
849
850 static SilcBool silc_packet_stream_link_va(SilcPacketStream stream,
851                                            SilcPacketCallbacks *callbacks,
852                                            void *callback_context,
853                                            int priority, va_list ap)
854 {
855   SilcPacketProcess p, e;
856   SilcInt32 packet_type;
857   int i;
858
859   SILC_LOG_DEBUG(("Linking callbacks %p to stream %p", callbacks, stream));
860
861   if (!callbacks)
862     return FALSE;
863   if (!callbacks->packet_receive)
864     return FALSE;
865
866   p = silc_calloc(1, sizeof(*p));
867   if (!p)
868     return FALSE;
869
870   p->priority = priority;
871   p->callbacks = callbacks;
872   p->callback_context = callback_context;
873
874   silc_mutex_lock(stream->lock);
875
876   if (!stream->process) {
877     stream->process = silc_dlist_init();
878     if (!stream->process) {
879       silc_mutex_unlock(stream->lock);
880       return FALSE;
881     }
882   }
883
884   /* According to priority set the procesor to correct position.  First
885      entry has the highest priority */
886   silc_dlist_start(stream->process);
887   while ((e = silc_dlist_get(stream->process)) != SILC_LIST_END) {
888     if (p->priority > e->priority) {
889       silc_dlist_insert(stream->process, p);
890       break;
891     }
892   }
893   if (!e)
894     silc_dlist_add(stream->process, p);
895
896   /* Get packet types to process */
897   i = 1;
898   while (1) {
899     packet_type = va_arg(ap, SilcInt32);
900
901     if (packet_type == SILC_PACKET_ANY)
902       break;
903
904     if (packet_type == -1)
905       break;
906
907     p->types = silc_realloc(p->types, sizeof(*p->types) * (i + 1));
908     if (!p->types) {
909       silc_mutex_unlock(stream->lock);
910       return FALSE;
911     }
912
913     p->types[i - 1] = (SilcPacketType)packet_type;
914     i++;
915   }
916   if (p->types)
917     p->types[i - 1] = 0;
918
919   silc_mutex_unlock(stream->lock);
920
921   silc_packet_stream_ref(stream);
922
923   return TRUE;
924 }
925
926 /* Links `callbacks' to `stream' for specified packet types */
927
928 SilcBool silc_packet_stream_link(SilcPacketStream stream,
929                                  SilcPacketCallbacks *callbacks,
930                                  void *callback_context,
931                                  int priority, ...)
932 {
933   va_list ap;
934   SilcBool ret;
935
936   va_start(ap, priority);
937   ret = silc_packet_stream_link_va(stream, callbacks, callback_context,
938                                    priority, ap);
939   va_end(ap);
940
941   return ret;
942 }
943
944 /* Unlinks `callbacks' from `stream'. */
945
946 void silc_packet_stream_unlink(SilcPacketStream stream,
947                                SilcPacketCallbacks *callbacks,
948                                void *callback_context)
949 {
950   SilcPacketProcess p;
951
952   SILC_LOG_DEBUG(("Unlinking callbacks %p from stream %p",
953                   callbacks, stream));
954
955   silc_mutex_lock(stream->lock);
956
957   silc_dlist_start(stream->process);
958   while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END)
959     if (p->callbacks == callbacks &&
960         p->callback_context == callback_context) {
961       silc_dlist_del(stream->process, p);
962       silc_free(p->types);
963       silc_free(p);
964       break;
965     }
966
967   if (!silc_dlist_count(stream->process)) {
968     silc_dlist_uninit(stream->process);
969     stream->process = NULL;
970   }
971
972   silc_mutex_unlock(stream->lock);
973
974   silc_packet_stream_unref(stream);
975 }
976
977 /* Returns TRUE if stream is UDP stream */
978
979 SilcBool silc_packet_stream_is_udp(SilcPacketStream stream)
980 {
981   return stream->udp || silc_socket_stream_is_udp(stream->stream, NULL);
982 }
983
984 /* Return packet sender IP and port for UDP packet stream */
985
986 SilcBool silc_packet_get_sender(SilcPacket packet,
987                                 const char **sender_ip,
988                                 SilcUInt16 *sender_port)
989 {
990   if (!packet->stream->remote_udp)
991     return FALSE;
992
993   *sender_ip = packet->stream->remote_udp->remote_ip;
994   *sender_port = packet->stream->remote_udp->remote_port;
995
996   return TRUE;
997 }
998
999 /* Reference packet stream */
1000
1001 void silc_packet_stream_ref(SilcPacketStream stream)
1002 {
1003   silc_atomic_add_int8(&stream->refcnt, 1);
1004 }
1005
1006 /* Unreference packet stream */
1007
1008 void silc_packet_stream_unref(SilcPacketStream stream)
1009 {
1010   if (silc_atomic_sub_int8(&stream->refcnt, 1) == 0)
1011     silc_packet_stream_destroy(stream);
1012 }
1013
1014 /* Return engine */
1015
1016 SilcPacketEngine silc_packet_get_engine(SilcPacketStream stream)
1017 {
1018   return stream->sc->engine;
1019 }
1020
1021 /* Set application context for packet stream */
1022
1023 void silc_packet_set_context(SilcPacketStream stream, void *stream_context)
1024 {
1025   silc_mutex_lock(stream->lock);
1026   stream->stream_context = stream_context;
1027   silc_mutex_unlock(stream->lock);
1028 }
1029
1030 /* Return application context from packet stream */
1031
1032 void *silc_packet_get_context(SilcPacketStream stream)
1033 {
1034   void *context;
1035   silc_mutex_lock(stream->lock);
1036   context = stream->stream_context;
1037   silc_mutex_unlock(stream->lock);
1038   return context;
1039 }
1040
1041 /* Change underlaying stream */
1042
1043 void silc_packet_stream_set_stream(SilcPacketStream ps,
1044                                    SilcStream stream)
1045 {
1046   if (ps->stream)
1047     silc_stream_set_notifier(ps->stream, ps->sc->schedule, NULL, NULL);
1048   ps->stream = stream;
1049   silc_stream_set_notifier(ps->stream, ps->sc->schedule, silc_packet_stream_io,
1050                            ps);
1051 }
1052
1053 /* Return underlaying stream */
1054
1055 SilcStream silc_packet_stream_get_stream(SilcPacketStream stream)
1056 {
1057   return stream->stream;
1058 }
1059
1060 /* Set keys. */
1061
1062 SilcBool silc_packet_set_keys(SilcPacketStream stream, SilcCipher send_key,
1063                               SilcCipher receive_key, SilcHmac send_hmac,
1064                               SilcHmac receive_hmac, SilcBool rekey)
1065 {
1066   SILC_LOG_DEBUG(("Setting new keys to packet stream %p", stream));
1067
1068   /* If doing rekey, send REKEY_DONE packet */
1069   if (rekey) {
1070     /* This will take stream lock. */
1071     if (!silc_packet_send_raw(stream, SILC_PACKET_REKEY_DONE, 0,
1072                               stream->src_id_type, stream->src_id,
1073                               stream->src_id_len, stream->dst_id_type,
1074                               stream->dst_id, stream->dst_id_len,
1075                               NULL, 0, stream->send_key[0],
1076                               stream->send_hmac[0]))
1077       return FALSE;
1078
1079     /* Write the packet to the stream */
1080     if (!silc_packet_stream_write(stream, TRUE))
1081       return FALSE;
1082   } else {
1083     silc_mutex_lock(stream->lock);
1084   }
1085
1086   /* In case IV Included is set, save the old keys */
1087   if (stream->iv_included) {
1088     if (stream->send_key[1] && send_key) {
1089       silc_cipher_free(stream->send_key[1]);
1090       stream->send_key[1] = stream->send_key[0];
1091     }
1092     if (stream->receive_key[1] && receive_key) {
1093       silc_cipher_free(stream->receive_key[1]);
1094       stream->receive_key[1] = stream->receive_key[0];
1095     }
1096     if (stream->send_hmac[1] && send_hmac) {
1097       silc_hmac_free(stream->send_hmac[1]);
1098       stream->send_hmac[1] = stream->send_hmac[0];
1099     }
1100     if (stream->receive_hmac[1] && receive_hmac) {
1101       silc_hmac_free(stream->receive_hmac[1]);
1102       stream->receive_hmac[1] = stream->receive_hmac[0];
1103     }
1104   } else {
1105     if (stream->send_key[0] && send_key)
1106       silc_cipher_free(stream->send_key[0]);
1107     if (stream->send_key[1] && receive_key)
1108       silc_cipher_free(stream->receive_key[0]);
1109     if (stream->send_hmac[0] && send_hmac)
1110       silc_hmac_free(stream->send_hmac[0]);
1111     if (stream->receive_hmac[0] && receive_hmac)
1112       silc_hmac_free(stream->receive_hmac[0]);
1113   }
1114
1115   /* Set keys */
1116   if (send_key)
1117     stream->send_key[0] = send_key;
1118   if (receive_key)
1119     stream->receive_key[0] = receive_key;
1120   if (send_hmac)
1121     stream->send_hmac[0] = send_hmac;
1122   if (receive_hmac)
1123     stream->receive_hmac[0] = receive_hmac;
1124
1125   silc_mutex_unlock(stream->lock);
1126   return TRUE;
1127 }
1128
1129 /* Return current ciphers from packet stream */
1130
1131 SilcBool silc_packet_get_keys(SilcPacketStream stream,
1132                               SilcCipher *send_key,
1133                               SilcCipher *receive_key,
1134                               SilcHmac *send_hmac,
1135                               SilcHmac *receive_hmac)
1136 {
1137   if (!stream->send_key[0] && !stream->receive_key[0] &&
1138       !stream->send_hmac[0] && !stream->receive_hmac[0])
1139     return FALSE;
1140
1141   silc_mutex_lock(stream->lock);
1142
1143   if (send_key)
1144     *send_key = stream->send_key[0];
1145   if (receive_key)
1146     *receive_key = stream->receive_key[0];
1147   if (send_hmac)
1148     *send_hmac = stream->send_hmac[0];
1149   if (receive_hmac)
1150     *receive_hmac = stream->receive_hmac[0];
1151
1152   silc_mutex_unlock(stream->lock);
1153
1154   return TRUE;
1155 }
1156
1157 /* Set SILC IDs to packet stream */
1158
1159 SilcBool silc_packet_set_ids(SilcPacketStream stream,
1160                              SilcIdType src_id_type, const void *src_id,
1161                              SilcIdType dst_id_type, const void *dst_id)
1162 {
1163   SilcUInt32 len;
1164   unsigned char tmp[32];
1165
1166   if (!src_id && !dst_id)
1167     return FALSE;
1168
1169   SILC_LOG_DEBUG(("Setting new IDs to packet stream"));
1170
1171   silc_mutex_lock(stream->lock);
1172
1173   if (src_id) {
1174     silc_free(stream->src_id);
1175     if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) {
1176       silc_mutex_unlock(stream->lock);
1177       return FALSE;
1178     }
1179     stream->src_id = silc_memdup(tmp, len);
1180     if (!stream->src_id) {
1181       silc_mutex_unlock(stream->lock);
1182       return FALSE;
1183     }
1184     stream->src_id_type = src_id_type;
1185     stream->src_id_len = len;
1186   }
1187
1188   if (dst_id) {
1189     silc_free(stream->dst_id);
1190     if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) {
1191       silc_mutex_unlock(stream->lock);
1192       return FALSE;
1193     }
1194     stream->dst_id = silc_memdup(tmp, len);
1195     if (!stream->dst_id) {
1196       silc_mutex_unlock(stream->lock);
1197       return FALSE;
1198     }
1199     stream->dst_id_type = dst_id_type;
1200     stream->dst_id_len = len;
1201   }
1202
1203   silc_mutex_unlock(stream->lock);
1204
1205   return TRUE;
1206 }
1207
1208 /* Adds Security ID (SID) */
1209
1210 SilcBool silc_packet_set_sid(SilcPacketStream stream, SilcUInt8 sid)
1211 {
1212   if (!stream->iv_included)
1213     return FALSE;
1214
1215   SILC_LOG_DEBUG(("Set packet stream %p SID to %d", stream, sid));
1216
1217   stream->sid = sid;
1218   return TRUE;
1219 }
1220
1221 /* Free packet */
1222
1223 void silc_packet_free(SilcPacket packet)
1224 {
1225   SilcPacketStream stream = packet->stream;
1226
1227   SILC_LOG_DEBUG(("Freeing packet %p", packet));
1228
1229   /* Check for double free */
1230   SILC_ASSERT(packet->stream != NULL);
1231
1232   packet->stream = NULL;
1233   packet->src_id = packet->dst_id = NULL;
1234   silc_buffer_reset(&packet->buffer);
1235
1236   silc_mutex_lock(stream->sc->engine->lock);
1237
1238   /* Put the packet back to freelist */
1239   silc_list_add(stream->sc->engine->packet_pool, packet);
1240   if (silc_list_count(stream->sc->engine->packet_pool) == 1)
1241     silc_list_start(stream->sc->engine->packet_pool);
1242
1243   silc_mutex_unlock(stream->sc->engine->lock);
1244 }
1245
1246 /****************************** Packet Sending ******************************/
1247
1248 /* Prepare outgoing data buffer for packet sending.  Returns the
1249    pointer to that buffer into the `packet'. */
1250
1251 static inline SilcBool silc_packet_send_prepare(SilcPacketStream stream,
1252                                                 SilcUInt32 totlen,
1253                                                 SilcHmac hmac,
1254                                                 SilcBuffer packet)
1255 {
1256   unsigned char *oldptr;
1257   unsigned int mac_len = hmac ? silc_hmac_len(hmac) : 0;
1258
1259   totlen += mac_len;
1260
1261   /* Allocate more space if needed */
1262   if (silc_unlikely(silc_buffer_taillen(&stream->outbuf) < totlen)) {
1263     if (!silc_buffer_realloc(&stream->outbuf,
1264                              silc_buffer_truelen(&stream->outbuf) + totlen))
1265       return FALSE;
1266   }
1267
1268   /* Pull data area for the new packet, and return pointer to the start of
1269      the data area and save the pointer in to the `packet'.  MAC is pulled
1270      later after it's computed. */
1271   oldptr = silc_buffer_pull_tail(&stream->outbuf, totlen);
1272   silc_buffer_set(packet, oldptr, totlen);
1273   silc_buffer_push_tail(packet, mac_len);
1274
1275   return TRUE;
1276 }
1277
1278 /* Increments counter when encrypting in counter mode. */
1279
1280 static inline void silc_packet_send_ctr_increment(SilcPacketStream stream,
1281                                                   SilcCipher cipher,
1282                                                   unsigned char *ret_iv)
1283 {
1284   unsigned char *iv = silc_cipher_get_iv(cipher);
1285   SilcUInt32 pc;
1286
1287   /* Increment packet counter */
1288   SILC_GET32_MSB(pc, iv + 8);
1289   pc++;
1290   SILC_PUT32_MSB(pc, iv + 8);
1291
1292   /* Reset block counter */
1293   memset(iv + 12, 0, 4);
1294
1295   /* If IV Included flag, return the 64-bit IV for inclusion in packet */
1296   if (stream->iv_included) {
1297     /* Get new nonce */
1298     ret_iv[0] = silc_rng_get_byte_fast(stream->sc->engine->rng);
1299     ret_iv[1] = ret_iv[0] + iv[4];
1300     ret_iv[2] = ret_iv[0] ^ ret_iv[1];
1301     ret_iv[3] = ret_iv[0] + ret_iv[2];
1302     SILC_PUT32_MSB(pc, ret_iv + 4);
1303     SILC_LOG_HEXDUMP(("IV"), ret_iv, 8);
1304
1305     /* Set new nonce to counter block */
1306     memcpy(iv + 4, ret_iv, 4);
1307   }
1308
1309   SILC_LOG_HEXDUMP(("Counter Block"), iv, 16);
1310 }
1311
1312 /* Internal routine to assemble outgoing packet.  Assembles and encryptes
1313    the packet.  The silc_packet_stream_write needs to be called to send it
1314    after this returns TRUE. */
1315
1316 static inline SilcBool silc_packet_send_raw(SilcPacketStream stream,
1317                                             SilcPacketType type,
1318                                             SilcPacketFlags flags,
1319                                             SilcIdType src_id_type,
1320                                             unsigned char *src_id,
1321                                             SilcUInt32 src_id_len,
1322                                             SilcIdType dst_id_type,
1323                                             unsigned char *dst_id,
1324                                             SilcUInt32 dst_id_len,
1325                                             const unsigned char *data,
1326                                             SilcUInt32 data_len,
1327                                             SilcCipher cipher,
1328                                             SilcHmac hmac)
1329 {
1330   unsigned char tmppad[SILC_PACKET_MAX_PADLEN], iv[33], psn[4];
1331   int block_len = (cipher ? silc_cipher_get_block_len(cipher) : 0);
1332   int i, enclen, truelen, padlen = 0, ivlen = 0, psnlen = 0;
1333   SilcBool ctr;
1334   SilcBufferStruct packet;
1335
1336   SILC_LOG_DEBUG(("Sending packet %s (%d) flags %d, src %d dst %d, "
1337                   "data len %d", silc_get_packet_name(type), stream->send_psn,
1338                   flags, src_id_type, dst_id_type, data_len));
1339
1340   /* Get the true length of the packet. This is saved as payload length
1341      into the packet header.  This does not include the length of the
1342      padding. */
1343   data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
1344                                             src_id_len + dst_id_len));
1345   enclen = truelen = (data_len + SILC_PACKET_HEADER_LEN +
1346                       src_id_len + dst_id_len);
1347
1348   /* If using CTR mode, increment the counter */
1349   ctr = (cipher && silc_cipher_get_mode(cipher) == SILC_CIPHER_MODE_CTR);
1350   if (ctr) {
1351     silc_packet_send_ctr_increment(stream, cipher, iv + 1);
1352
1353     /* If IV is included, the SID, IV and sequence number is added to packet */
1354     if (stream->iv_included && cipher) {
1355       psnlen = sizeof(psn);
1356       ivlen = 8 + 1;
1357       iv[0] = stream->sid;
1358     }
1359   } else {
1360     /* If IV is included, the SID, IV and sequence number is added to packet */
1361     if (stream->iv_included && cipher) {
1362       psnlen = sizeof(psn);
1363       ivlen = block_len + 1;
1364       iv[0] = stream->sid;
1365       memcpy(iv + 1, silc_cipher_get_iv(cipher), block_len);
1366     }
1367   }
1368
1369   /* We automatically figure out the packet structure from the packet
1370      type and flags, and calculate correct length.  Private messages with
1371      private keys and channel messages are special packets as their
1372      payload is encrypted already. */
1373   if ((type == SILC_PACKET_PRIVATE_MESSAGE &&
1374        flags & SILC_PACKET_FLAG_PRIVMSG_KEY) ||
1375       type == SILC_PACKET_CHANNEL_MESSAGE) {
1376
1377     /* Padding is calculated from header + IDs */
1378     if (!ctr)
1379       SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN + src_id_len + dst_id_len +
1380                           psnlen), block_len, padlen);
1381
1382     /* Length to encrypt, header + IDs + padding. */
1383     enclen = (SILC_PACKET_HEADER_LEN + src_id_len + dst_id_len +
1384               padlen + psnlen);
1385   } else {
1386
1387     /* Padding is calculated from true length of the packet */
1388     if (flags & SILC_PACKET_FLAG_LONG_PAD)
1389       SILC_PACKET_PADLEN_MAX(truelen + psnlen, block_len, padlen);
1390     else if (!ctr)
1391       SILC_PACKET_PADLEN(truelen + psnlen, block_len, padlen);
1392
1393     enclen += padlen + psnlen;
1394   }
1395
1396   /* Remove implementation specific flags */
1397   flags &= ~(SILC_PACKET_FLAG_LONG_PAD);
1398
1399   /* Get random padding */
1400   for (i = 0; i < padlen; i++) tmppad[i] =
1401     silc_rng_get_byte_fast(stream->sc->engine->rng);
1402
1403   silc_mutex_lock(stream->lock);
1404
1405   /* Get packet pointer from the outgoing buffer */
1406   if (silc_unlikely(!silc_packet_send_prepare(stream, truelen + padlen + ivlen
1407                                               + psnlen, hmac, &packet))) {
1408     silc_mutex_unlock(stream->lock);
1409     return FALSE;
1410   }
1411
1412   SILC_PUT32_MSB(stream->send_psn, psn);
1413
1414   /* Create the packet.  This creates the SILC header, adds padding, and
1415      the actual packet data. */
1416   i = silc_buffer_format(&packet,
1417                          SILC_STR_DATA(iv, ivlen),
1418                          SILC_STR_DATA(psn, psnlen),
1419                          SILC_STR_UI_SHORT(truelen),
1420                          SILC_STR_UI_CHAR(flags),
1421                          SILC_STR_UI_CHAR(type),
1422                          SILC_STR_UI_CHAR(padlen),
1423                          SILC_STR_UI_CHAR(0),
1424                          SILC_STR_UI_CHAR(src_id_len),
1425                          SILC_STR_UI_CHAR(dst_id_len),
1426                          SILC_STR_UI_CHAR(src_id_type),
1427                          SILC_STR_DATA(src_id, src_id_len),
1428                          SILC_STR_UI_CHAR(dst_id_type),
1429                          SILC_STR_DATA(dst_id, dst_id_len),
1430                          SILC_STR_DATA(tmppad, padlen),
1431                          SILC_STR_DATA(data, data_len),
1432                          SILC_STR_END);
1433   if (silc_unlikely(i < 0)) {
1434     silc_mutex_unlock(stream->lock);
1435     return FALSE;
1436   }
1437
1438   SILC_LOG_HEXDUMP(("Assembled packet, len %d", silc_buffer_len(&packet)),
1439                    silc_buffer_data(&packet), silc_buffer_len(&packet));
1440
1441   /* Encrypt the packet */
1442   if (silc_likely(cipher)) {
1443     SILC_LOG_DEBUG(("Encrypting packet"));
1444     if (silc_unlikely(!silc_cipher_encrypt(cipher, packet.data + ivlen,
1445                                            packet.data + ivlen, enclen,
1446                                            NULL))) {
1447       SILC_LOG_ERROR(("Packet encryption failed"));
1448       silc_mutex_unlock(stream->lock);
1449       return FALSE;
1450     }
1451   }
1452
1453   /* Compute HMAC */
1454   if (silc_likely(hmac)) {
1455     SilcUInt32 mac_len;
1456
1457     /* MAC is computed from the entire encrypted packet data, and put
1458        to the end of the packet. */
1459     silc_hmac_init(hmac);
1460     silc_hmac_update(hmac, psn, sizeof(psn));
1461     silc_hmac_update(hmac, packet.data, silc_buffer_len(&packet));
1462     silc_hmac_final(hmac, packet.tail, &mac_len);
1463     silc_buffer_pull_tail(&packet, mac_len);
1464     stream->send_psn++;
1465   }
1466
1467   return TRUE;
1468 }
1469
1470 /* Sends a packet */
1471
1472 SilcBool silc_packet_send(SilcPacketStream stream,
1473                           SilcPacketType type, SilcPacketFlags flags,
1474                           const unsigned char *data, SilcUInt32 data_len)
1475 {
1476   SilcBool ret;
1477
1478   ret = silc_packet_send_raw(stream, type, flags,
1479                              stream->src_id_type,
1480                              stream->src_id,
1481                              stream->src_id_len,
1482                              stream->dst_id_type,
1483                              stream->dst_id,
1484                              stream->dst_id_len,
1485                              data, data_len,
1486                              stream->send_key[0],
1487                              stream->send_hmac[0]);
1488
1489   /* Write the packet to the stream */
1490   return ret ? silc_packet_stream_write(stream, FALSE) : FALSE;
1491 }
1492
1493 /* Sends a packet, extended routine */
1494
1495 SilcBool silc_packet_send_ext(SilcPacketStream stream,
1496                               SilcPacketType type, SilcPacketFlags flags,
1497                               SilcIdType src_id_type, void *src_id,
1498                               SilcIdType dst_id_type, void *dst_id,
1499                               const unsigned char *data, SilcUInt32 data_len,
1500                               SilcCipher cipher, SilcHmac hmac)
1501 {
1502   unsigned char src_id_data[32], dst_id_data[32];
1503   SilcUInt32 src_id_len, dst_id_len;
1504   SilcBool ret;
1505
1506   if (src_id)
1507     if (!silc_id_id2str(src_id, src_id_type, src_id_data,
1508                         sizeof(src_id_data), &src_id_len))
1509       return FALSE;
1510   if (dst_id)
1511     if (!silc_id_id2str(dst_id, dst_id_type, dst_id_data,
1512                         sizeof(dst_id_data), &dst_id_len))
1513       return FALSE;
1514
1515   ret = silc_packet_send_raw(stream, type, flags,
1516                              src_id ? src_id_type : stream->src_id_type,
1517                              src_id ? src_id_data : stream->src_id,
1518                              src_id ? src_id_len : stream->src_id_len,
1519                              dst_id ? dst_id_type : stream->dst_id_type,
1520                              dst_id ? dst_id_data : stream->dst_id,
1521                              dst_id ? dst_id_len : stream->dst_id_len,
1522                              data, data_len,
1523                              cipher ? cipher : stream->send_key[0],
1524                              hmac ? hmac : stream->send_hmac[0]);
1525
1526   /* Write the packet to the stream */
1527   return ret ? silc_packet_stream_write(stream, FALSE) : FALSE;
1528 }
1529
1530 /* Sends packet after formatting the arguments to buffer */
1531
1532 SilcBool silc_packet_send_va(SilcPacketStream stream,
1533                              SilcPacketType type, SilcPacketFlags flags, ...)
1534 {
1535   SilcBufferStruct buf;
1536   SilcBool ret;
1537   va_list va;
1538
1539   va_start(va, flags);
1540
1541   memset(&buf, 0, sizeof(buf));
1542   if (silc_buffer_format_vp(&buf, va) < 0) {
1543     va_end(va);
1544     return FALSE;
1545   }
1546
1547   ret = silc_packet_send(stream, type, flags, silc_buffer_data(&buf),
1548                          silc_buffer_len(&buf));
1549
1550   silc_buffer_purge(&buf);
1551   va_end(va);
1552
1553   return ret;
1554 }
1555
1556 /* Sends packet after formatting the arguments to buffer, extended routine */
1557
1558 SilcBool silc_packet_send_va_ext(SilcPacketStream stream,
1559                                  SilcPacketType type, SilcPacketFlags flags,
1560                                  SilcIdType src_id_type, void *src_id,
1561                                  SilcIdType dst_id_type, void *dst_id,
1562                                  SilcCipher cipher, SilcHmac hmac, ...)
1563 {
1564   SilcBufferStruct buf;
1565   SilcBool ret;
1566   va_list va;
1567
1568   va_start(va, hmac);
1569
1570   memset(&buf, 0, sizeof(buf));
1571   if (silc_buffer_format_vp(&buf, va) < 0) {
1572     va_end(va);
1573     return FALSE;
1574   }
1575
1576   ret = silc_packet_send_ext(stream, type, flags, src_id_type, src_id,
1577                              dst_id_type, dst_id, silc_buffer_data(&buf),
1578                              silc_buffer_len(&buf), cipher, hmac);
1579
1580   silc_buffer_purge(&buf);
1581   va_end(va);
1582
1583   return TRUE;
1584 }
1585
1586 /***************************** Packet Receiving *****************************/
1587
1588 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. */
1589
1590 static inline SilcBool silc_packet_check_mac(SilcHmac hmac,
1591                                              const unsigned char *data,
1592                                              SilcUInt32 data_len,
1593                                              const unsigned char *packet_mac,
1594                                              const unsigned char *packet_seq,
1595                                              SilcUInt32 sequence)
1596 {
1597   /* Check MAC */
1598   if (silc_likely(hmac)) {
1599     unsigned char mac[32], psn[4];
1600     SilcUInt32 mac_len;
1601
1602     SILC_LOG_DEBUG(("Verifying MAC"));
1603
1604     /* Compute HMAC of packet */
1605     silc_hmac_init(hmac);
1606
1607     if (!packet_seq) {
1608       SILC_PUT32_MSB(sequence, psn);
1609       silc_hmac_update(hmac, psn, 4);
1610     } else
1611       silc_hmac_update(hmac, packet_seq, 4);
1612
1613     silc_hmac_update(hmac, data, data_len);
1614     silc_hmac_final(hmac, mac, &mac_len);
1615
1616     /* Compare the MAC's */
1617     if (silc_unlikely(memcmp(packet_mac, mac, mac_len))) {
1618       SILC_LOG_DEBUG(("MAC failed"));
1619       return FALSE;
1620     }
1621
1622     SILC_LOG_DEBUG(("MAC is Ok"));
1623   }
1624
1625   return TRUE;
1626 }
1627
1628 /* Increments/sets counter when decrypting in counter mode. */
1629
1630 static inline void silc_packet_receive_ctr_increment(SilcPacketStream stream,
1631                                                      unsigned char *iv,
1632                                                      unsigned char *packet_iv)
1633 {
1634   SilcUInt32 pc;
1635
1636   /* If IV Included flag, set the IV from packet to block counter. */
1637   if (stream->iv_included) {
1638     memcpy(iv + 4, packet_iv, 8);
1639   } else {
1640     /* Increment packet counter */
1641     SILC_GET32_MSB(pc, iv + 8);
1642     pc++;
1643     SILC_PUT32_MSB(pc, iv + 8);
1644   }
1645
1646   /* Reset block counter */
1647   memset(iv + 12, 0, 4);
1648
1649   SILC_LOG_HEXDUMP(("Counter Block"), iv, 16);
1650 }
1651
1652 /* Decrypts SILC packet.  Handles both normal and special packet decryption.
1653    Return 0 when packet is normal and 1 when it it special, -1 on error. */
1654
1655 static inline int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
1656                                       SilcUInt32 sequence, SilcBuffer buffer,
1657                                       SilcBool normal)
1658 {
1659   if (normal == TRUE) {
1660     if (silc_likely(cipher)) {
1661       /* Decrypt rest of the packet */
1662       SILC_LOG_DEBUG(("Decrypting the packet"));
1663       if (silc_unlikely(!silc_cipher_decrypt(cipher, buffer->data,
1664                                              buffer->data,
1665                                              silc_buffer_len(buffer), NULL)))
1666         return -1;
1667     }
1668     return 0;
1669
1670   } else {
1671     /* Decrypt rest of the header plus padding */
1672     if (silc_likely(cipher)) {
1673       SilcUInt16 len;
1674       SilcUInt32 block_len = silc_cipher_get_block_len(cipher);
1675
1676       SILC_LOG_DEBUG(("Decrypting the header"));
1677
1678       /* Padding length + src id len + dst id len + header length - 16
1679          bytes already decrypted, gives the rest of the encrypted packet */
1680       silc_buffer_push(buffer, block_len);
1681       len = (((SilcUInt8)buffer->data[4] + (SilcUInt8)buffer->data[6] +
1682               (SilcUInt8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
1683              block_len);
1684       silc_buffer_pull(buffer, block_len);
1685
1686       if (silc_unlikely(len > silc_buffer_len(buffer))) {
1687         SILC_LOG_ERROR(("Garbage in header of packet, bad packet length, "
1688                         "packet dropped"));
1689         return -1;
1690       }
1691       if (silc_unlikely(!silc_cipher_decrypt(cipher, buffer->data,
1692                                              buffer->data, len, NULL)))
1693         return -1;
1694     }
1695
1696     return 1;
1697   }
1698 }
1699
1700 /* Parses the packet. This is called when a whole packet is ready to be
1701    parsed. The buffer sent must be already decrypted before calling this
1702    function. */
1703
1704 static inline SilcBool silc_packet_parse(SilcPacket packet)
1705 {
1706   SilcBuffer buffer = &packet->buffer;
1707   SilcUInt8 padlen = (SilcUInt8)buffer->data[4];
1708   SilcUInt8 src_id_len, dst_id_len, src_id_type, dst_id_type;
1709   int ret;
1710
1711   SILC_LOG_DEBUG(("Parsing incoming packet"));
1712
1713   /* Parse the buffer.  This parses the SILC header of the packet. */
1714   ret = silc_buffer_unformat(buffer,
1715                              SILC_STR_ADVANCE,
1716                              SILC_STR_OFFSET(6),
1717                              SILC_STR_UI_CHAR(&src_id_len),
1718                              SILC_STR_UI_CHAR(&dst_id_len),
1719                              SILC_STR_UI_CHAR(&src_id_type),
1720                              SILC_STR_END);
1721   if (silc_unlikely(ret == -1)) {
1722     if (!packet->stream->udp &&
1723         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1724       SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1725     return FALSE;
1726   }
1727
1728   if (silc_unlikely(src_id_len > SILC_PACKET_MAX_ID_LEN ||
1729                     dst_id_len > SILC_PACKET_MAX_ID_LEN)) {
1730     if (!packet->stream->udp &&
1731         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1732       SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
1733                       packet->src_id_len, packet->dst_id_len));
1734     return FALSE;
1735   }
1736
1737   ret = silc_buffer_unformat(buffer,
1738                              SILC_STR_ADVANCE,
1739                              SILC_STR_DATA(&packet->src_id, src_id_len),
1740                              SILC_STR_UI_CHAR(&dst_id_type),
1741                              SILC_STR_DATA(&packet->dst_id, dst_id_len),
1742                              SILC_STR_OFFSET(padlen),
1743                              SILC_STR_END);
1744   if (silc_unlikely(ret == -1)) {
1745     if (!packet->stream->udp &&
1746         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1747       SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1748     return FALSE;
1749   }
1750
1751   if (silc_unlikely(src_id_type > SILC_ID_CHANNEL ||
1752                     dst_id_type > SILC_ID_CHANNEL)) {
1753     if (!packet->stream->udp &&
1754         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1755       SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
1756                       src_id_type, dst_id_type));
1757     return FALSE;
1758   }
1759
1760   packet->src_id_len = src_id_len;
1761   packet->dst_id_len = dst_id_len;
1762   packet->src_id_type = src_id_type;
1763   packet->dst_id_type = dst_id_type;
1764
1765   SILC_LOG_HEXDUMP(("Parsed packet, len %d", silc_buffer_headlen(buffer) +
1766                    silc_buffer_len(buffer)), buffer->head,
1767                    silc_buffer_headlen(buffer) + silc_buffer_len(buffer));
1768
1769   SILC_LOG_DEBUG(("Incoming packet type: %d (%s)", packet->type,
1770                   silc_get_packet_name(packet->type)));
1771
1772   return TRUE;
1773 }
1774
1775 /* Dispatch packet to application.  Called with stream->lock locked.
1776    Returns FALSE if the stream was destroyed while dispatching a packet. */
1777
1778 static SilcBool silc_packet_dispatch(SilcPacket packet)
1779 {
1780   SilcPacketStream stream = packet->stream;
1781   SilcPacketProcess p;
1782   SilcBool default_sent = FALSE;
1783   SilcPacketType *pt;
1784
1785   /* Dispatch packet to all packet processors that want it */
1786
1787   if (silc_likely(!stream->process)) {
1788     /* Send to default processor as no others exist */
1789     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1790     silc_mutex_unlock(stream->lock);
1791     if (silc_unlikely(!stream->sc->engine->callbacks->
1792                       packet_receive(stream->sc->engine, stream, packet,
1793                                      stream->sc->engine->callback_context,
1794                                      stream->stream_context)))
1795       silc_packet_free(packet);
1796     silc_mutex_lock(stream->lock);
1797     return stream->destroyed == FALSE;
1798   }
1799
1800   silc_dlist_start(stream->process);
1801   while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END) {
1802
1803     /* If priority is 0 or less, we send to default processor first
1804        because default processor has 0 priority */
1805     if (!default_sent && p->priority <= 0) {
1806       SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1807       default_sent = TRUE;
1808       silc_mutex_unlock(stream->lock);
1809       if (stream->sc->engine->callbacks->
1810           packet_receive(stream->sc->engine, stream, packet,
1811                          stream->sc->engine->callback_context,
1812                          stream->stream_context)) {
1813         silc_mutex_lock(stream->lock);
1814         return stream->destroyed == FALSE;
1815       }
1816       silc_mutex_lock(stream->lock);
1817     }
1818
1819     /* Send to processor */
1820     if (!p->types) {
1821       /* Send all packet types */
1822       SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1823       silc_mutex_unlock(stream->lock);
1824       if (p->callbacks->packet_receive(stream->sc->engine, stream, packet,
1825                                        p->callback_context,
1826                                        stream->stream_context)) {
1827         silc_mutex_lock(stream->lock);
1828         return stream->destroyed == FALSE;
1829       }
1830       silc_mutex_lock(stream->lock);
1831     } else {
1832       /* Send specific types */
1833       for (pt = p->types; *pt; pt++) {
1834         if (*pt != packet->type)
1835           continue;
1836         SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1837         silc_mutex_unlock(stream->lock);
1838         if (p->callbacks->packet_receive(stream->sc->engine, stream, packet,
1839                                          p->callback_context,
1840                                          stream->stream_context)) {
1841           silc_mutex_lock(stream->lock);
1842           return stream->destroyed == FALSE;
1843         }
1844         silc_mutex_lock(stream->lock);
1845         break;
1846       }
1847     }
1848   }
1849
1850   if (!default_sent) {
1851     /* Send to default processor as it has not been sent yet */
1852     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1853     silc_mutex_unlock(stream->lock);
1854     if (stream->sc->engine->callbacks->
1855         packet_receive(stream->sc->engine, stream, packet,
1856                        stream->sc->engine->callback_context,
1857                        stream->stream_context)) {
1858       silc_mutex_lock(stream->lock);
1859       return stream->destroyed == FALSE;
1860     }
1861     silc_mutex_lock(stream->lock);
1862   }
1863
1864   /* If we got here, no one wanted the packet, so drop it */
1865   silc_packet_free(packet);
1866   return stream->destroyed == FALSE;
1867 }
1868
1869 /* Process incoming data and parse packets.  Called with stream->lock
1870    locked. */
1871
1872 static void silc_packet_read_process(SilcPacketStream stream)
1873 {
1874   SilcBuffer inbuf = &stream->sc->inbuf;
1875   SilcCipher cipher;
1876   SilcHmac hmac;
1877   SilcPacket packet;
1878   SilcUInt8 sid;
1879   SilcUInt16 packetlen;
1880   SilcUInt32 paddedlen, mac_len, block_len, ivlen, psnlen;
1881   unsigned char tmp[SILC_PACKET_MIN_HEADER_LEN], *header;
1882   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE], *packet_seq = NULL;
1883   SilcBool normal;
1884   int ret;
1885
1886   /* Parse the packets from the data */
1887   while (silc_buffer_len(inbuf) > 0) {
1888     ivlen = psnlen = 0;
1889     cipher = stream->receive_key[0];
1890     hmac = stream->receive_hmac[0];
1891     normal = FALSE;
1892
1893     if (silc_unlikely(silc_buffer_len(inbuf) <
1894                       (stream->iv_included ? SILC_PACKET_MIN_HEADER_LEN_IV :
1895                        SILC_PACKET_MIN_HEADER_LEN))) {
1896       SILC_LOG_DEBUG(("Partial packet in queue, waiting for the rest"));
1897       return;
1898     }
1899
1900     if (silc_likely(hmac))
1901       mac_len = silc_hmac_len(hmac);
1902     else
1903       mac_len = 0;
1904
1905     /* Decrypt first block of the packet to get the length field out */
1906     if (silc_likely(cipher)) {
1907       block_len = silc_cipher_get_block_len(cipher);
1908
1909       if (stream->iv_included) {
1910         /* SID, IV and sequence number is included in the ciphertext */
1911         sid = (SilcUInt8)inbuf->data[0];
1912
1913         if (silc_cipher_get_mode(cipher) == SILC_CIPHER_MODE_CTR) {
1914           /* Set the CTR mode IV from packet to counter block */
1915           memcpy(iv, silc_cipher_get_iv(cipher), block_len);
1916           silc_packet_receive_ctr_increment(stream, iv, inbuf->data + 1);
1917           ivlen = 8 + 1;
1918         } else {
1919           /* Get IV from packet */
1920           memcpy(iv, inbuf->data + 1, block_len);
1921           ivlen = block_len + 1;
1922         }
1923         psnlen = 4;
1924
1925         /* Check SID, and get correct decryption key */
1926         if (sid != stream->sid) {
1927           /* If SID is recent get the previous key and use it */
1928           if (sid > 0 && stream->sid > 0 && stream->sid - 1 == sid &&
1929               stream->receive_key[1] && !stream->receive_hmac[1]) {
1930             cipher = stream->receive_key[1];
1931             hmac = stream->receive_hmac[1];
1932           } else {
1933             /* The SID is unknown, drop rest of the data in buffer */
1934             SILC_LOG_DEBUG(("Unknown Security ID %d in packet, expected %d",
1935                             sid, stream->sid));
1936             silc_mutex_unlock(stream->lock);
1937             SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_UNKNOWN_SID);
1938             silc_mutex_lock(stream->lock);
1939             silc_buffer_reset(inbuf);
1940             return;
1941           }
1942         }
1943       } else {
1944         memcpy(iv, silc_cipher_get_iv(cipher), block_len);
1945
1946         /* If using CTR mode, increment the counter */
1947         if (silc_cipher_get_mode(cipher) == SILC_CIPHER_MODE_CTR)
1948           silc_packet_receive_ctr_increment(stream, iv, NULL);
1949       }
1950
1951       silc_cipher_decrypt(cipher, inbuf->data + ivlen, tmp,
1952                           block_len, iv);
1953
1954       header = tmp;
1955       if (stream->iv_included) {
1956         /* Take sequence number from packet */
1957         packet_seq = header;
1958         header += 4;
1959       }
1960     } else {
1961       /* Unencrypted packet */
1962       block_len = SILC_PACKET_MIN_HEADER_LEN;
1963       header = inbuf->data;
1964     }
1965
1966     /* Get packet length and full packet length with padding */
1967     SILC_PACKET_LENGTH(header, packetlen, paddedlen);
1968
1969     /* Sanity checks */
1970     if (silc_unlikely(packetlen < SILC_PACKET_MIN_LEN)) {
1971       if (!stream->udp && !silc_socket_stream_is_udp(stream->stream, NULL))
1972         SILC_LOG_ERROR(("Received too short packet"));
1973       silc_mutex_unlock(stream->lock);
1974       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
1975       silc_mutex_lock(stream->lock);
1976       memset(tmp, 0, sizeof(tmp));
1977       silc_buffer_reset(inbuf);
1978       return;
1979     }
1980
1981     if (silc_buffer_len(inbuf) < paddedlen + ivlen + mac_len) {
1982       SILC_LOG_DEBUG(("Received partial packet, waiting for the rest "
1983                       "(%d bytes)",
1984                       paddedlen + mac_len - silc_buffer_len(inbuf)));
1985       memset(tmp, 0, sizeof(tmp));
1986       return;
1987     }
1988
1989     /* Check MAC of the packet */
1990     if (silc_unlikely(!silc_packet_check_mac(hmac, inbuf->data,
1991                                              paddedlen + ivlen,
1992                                              inbuf->data + ivlen +
1993                                              paddedlen, packet_seq,
1994                                              stream->receive_psn))) {
1995       silc_mutex_unlock(stream->lock);
1996       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MAC_FAILED);
1997       silc_mutex_lock(stream->lock);
1998       memset(tmp, 0, sizeof(tmp));
1999       silc_buffer_reset(inbuf);
2000       return;
2001     }
2002
2003     /* Get packet */
2004     packet = silc_packet_alloc(stream->sc->engine);
2005     if (silc_unlikely(!packet)) {
2006       silc_mutex_unlock(stream->lock);
2007       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
2008       silc_mutex_lock(stream->lock);
2009       memset(tmp, 0, sizeof(tmp));
2010       silc_buffer_reset(inbuf);
2011       return;
2012     }
2013     packet->stream = stream;
2014
2015     /* Allocate more space to packet buffer, if needed */
2016     if (silc_unlikely(silc_buffer_truelen(&packet->buffer) < paddedlen)) {
2017       if (!silc_buffer_realloc(&packet->buffer,
2018                                silc_buffer_truelen(&packet->buffer) +
2019                                (paddedlen -
2020                                 silc_buffer_truelen(&packet->buffer)))) {
2021         silc_mutex_unlock(stream->lock);
2022         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
2023         silc_mutex_lock(stream->lock);
2024         silc_packet_free(packet);
2025         memset(tmp, 0, sizeof(tmp));
2026         silc_buffer_reset(inbuf);
2027         return;
2028       }
2029     }
2030
2031     /* Parse packet header */
2032     packet->flags = (SilcPacketFlags)header[2];
2033     packet->type = (SilcPacketType)header[3];
2034
2035     if (stream->sc->engine->local_is_router) {
2036       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
2037           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
2038         normal = FALSE;
2039       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE ||
2040                (packet->type == SILC_PACKET_CHANNEL_MESSAGE &&
2041                 stream->is_router == TRUE))
2042         normal = TRUE;
2043     } else {
2044       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
2045           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
2046         normal = FALSE;
2047       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE)
2048         normal = TRUE;
2049     }
2050
2051     SILC_LOG_HEXDUMP(("Incoming packet (%d) len %d",
2052                       stream->receive_psn, paddedlen + ivlen + mac_len),
2053                      inbuf->data, paddedlen + ivlen + mac_len);
2054
2055     /* Put the decrypted part, and rest of the encrypted data, and decrypt */
2056     silc_buffer_pull_tail(&packet->buffer, paddedlen);
2057     silc_buffer_put(&packet->buffer, header, block_len - psnlen);
2058     silc_buffer_pull(&packet->buffer, block_len - psnlen);
2059     silc_buffer_put(&packet->buffer, (inbuf->data + ivlen +
2060                                       psnlen + (block_len - psnlen)),
2061                     paddedlen - ivlen - psnlen - (block_len - psnlen));
2062     if (silc_likely(cipher)) {
2063       silc_cipher_set_iv(cipher, iv);
2064       ret = silc_packet_decrypt(cipher, hmac, stream->receive_psn,
2065                                 &packet->buffer, normal);
2066       if (silc_unlikely(ret < 0)) {
2067         silc_mutex_unlock(stream->lock);
2068         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_DECRYPTION_FAILED);
2069         silc_mutex_lock(stream->lock);
2070         silc_packet_free(packet);
2071         memset(tmp, 0, sizeof(tmp));
2072         return;
2073       }
2074
2075       stream->receive_psn++;
2076     }
2077     silc_buffer_push(&packet->buffer, block_len);
2078
2079     /* Pull the packet from inbuf thus we'll get the next one in the inbuf. */
2080     silc_buffer_pull(inbuf, paddedlen + mac_len);
2081
2082     /* Parse the packet */
2083     if (silc_unlikely(!silc_packet_parse(packet))) {
2084       silc_mutex_unlock(stream->lock);
2085       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
2086       silc_mutex_lock(stream->lock);
2087       silc_packet_free(packet);
2088       memset(tmp, 0, sizeof(tmp));
2089       return;
2090     }
2091
2092     /* Dispatch the packet to application */
2093     if (!silc_packet_dispatch(packet))
2094       break;
2095   }
2096
2097   silc_buffer_reset(inbuf);
2098 }
2099
2100
2101 /****************************** Packet Waiting ******************************/
2102
2103 /* Packet wait receive callback */
2104 static SilcBool
2105 silc_packet_wait_packet_receive(SilcPacketEngine engine,
2106                                 SilcPacketStream stream,
2107                                 SilcPacket packet,
2108                                 void *callback_context,
2109                                 void *stream_context);
2110
2111 /* Packet waiting callbacks */
2112 static SilcPacketCallbacks silc_packet_wait_cbs =
2113 {
2114   silc_packet_wait_packet_receive, NULL, NULL
2115 };
2116
2117 /* Packet waiting context */
2118 typedef struct {
2119   SilcMutex wait_lock;
2120   SilcCond wait_cond;
2121   SilcList packet_queue;
2122   unsigned int stopped     : 1;
2123 } *SilcPacketWait;
2124
2125 /* Packet wait receive callback */
2126
2127 static SilcBool
2128 silc_packet_wait_packet_receive(SilcPacketEngine engine,
2129                                 SilcPacketStream stream,
2130                                 SilcPacket packet,
2131                                 void *callback_context,
2132                                 void *stream_context)
2133 {
2134   SilcPacketWait pw = callback_context;
2135
2136   /* Signal the waiting thread for a new packet */
2137   silc_mutex_lock(pw->wait_lock);
2138
2139   if (silc_unlikely(pw->stopped)) {
2140     silc_mutex_unlock(pw->wait_lock);
2141     return FALSE;
2142   }
2143
2144   silc_list_add(pw->packet_queue, packet);
2145   silc_cond_broadcast(pw->wait_cond);
2146
2147   silc_mutex_unlock(pw->wait_lock);
2148
2149   return TRUE;
2150 }
2151
2152 /* Initialize packet waiting */
2153
2154 void *silc_packet_wait_init(SilcPacketStream stream, ...)
2155 {
2156   SilcPacketWait pw;
2157   SilcBool ret;
2158   va_list ap;
2159
2160   pw = silc_calloc(1, sizeof(*pw));
2161   if (!pw)
2162     return NULL;
2163
2164   /* Allocate mutex and conditional variable */
2165   if (!silc_mutex_alloc(&pw->wait_lock)) {
2166     silc_free(pw);
2167     return NULL;
2168   }
2169   if (!silc_cond_alloc(&pw->wait_cond)) {
2170     silc_mutex_free(pw->wait_lock);
2171     silc_free(pw);
2172     return NULL;
2173   }
2174
2175   /* Link to the packet stream for the requested packet types */
2176   va_start(ap, stream);
2177   ret = silc_packet_stream_link_va(stream, &silc_packet_wait_cbs, pw,
2178                                    10000000, ap);
2179   va_end(ap);
2180   if (!ret) {
2181     silc_cond_free(pw->wait_cond);
2182     silc_mutex_free(pw->wait_lock);
2183     silc_free(pw);
2184     return NULL;
2185   }
2186
2187   /* Initialize packet queue */
2188   silc_list_init(pw->packet_queue, struct SilcPacketStruct, next);
2189
2190   return (void *)pw;
2191 }
2192
2193 /* Uninitialize packet waiting */
2194
2195 void silc_packet_wait_uninit(void *waiter, SilcPacketStream stream)
2196 {
2197   SilcPacketWait pw = waiter;
2198   SilcPacket packet;
2199
2200   /* Signal any threads to stop waiting */
2201   silc_mutex_lock(pw->wait_lock);
2202   pw->stopped = TRUE;
2203   silc_cond_broadcast(pw->wait_cond);
2204   silc_mutex_unlock(pw->wait_lock);
2205
2206   /* Re-acquire lock and free resources */
2207   silc_mutex_lock(pw->wait_lock);
2208   silc_packet_stream_unlink(stream, &silc_packet_wait_cbs, pw);
2209
2210   /* Free any remaining packets */
2211   silc_list_start(pw->packet_queue);
2212   while ((packet = silc_list_get(pw->packet_queue)) != SILC_LIST_END)
2213     silc_packet_free(packet);
2214
2215   silc_mutex_unlock(pw->wait_lock);
2216   silc_cond_free(pw->wait_cond);
2217   silc_mutex_free(pw->wait_lock);
2218   silc_free(pw);
2219 }
2220
2221 /* Blocks thread until a packet has been received. */
2222
2223 int silc_packet_wait(void *waiter, int timeout, SilcPacket *return_packet)
2224 {
2225   SilcPacketWait pw = waiter;
2226   SilcBool ret = FALSE;
2227
2228   silc_mutex_lock(pw->wait_lock);
2229
2230   /* Wait here until packet has arrived */
2231   while (silc_list_count(pw->packet_queue) == 0) {
2232     if (silc_unlikely(pw->stopped)) {
2233       silc_mutex_unlock(pw->wait_lock);
2234       return -1;
2235     }
2236     ret = silc_cond_timedwait(pw->wait_cond, pw->wait_lock, timeout);
2237   }
2238
2239   /* Return packet */
2240   silc_list_start(pw->packet_queue);
2241   *return_packet = silc_list_get(pw->packet_queue);
2242   silc_list_del(pw->packet_queue, *return_packet);
2243
2244   silc_mutex_unlock(pw->wait_lock);
2245
2246   return ret == TRUE ? 1 : 0;
2247 }