Added per scheduler context for streams. The input buffer is now
[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   SilcInt32 priority;                    /* Priority */
54   SilcPacketType *types;                 /* Packets to process */
55   SilcPacketCallbacks *callbacks;        /* Callbacks or NULL */
56   void *callback_context;
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       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     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                                                      SilcCipher cipher,
1632                                                      unsigned char *ret_iv)
1633 {
1634   unsigned char *iv = silc_cipher_get_iv(cipher);
1635   SilcUInt32 pc;
1636
1637   /* Increment packet counter */
1638   SILC_GET32_MSB(pc, iv + 8);
1639   pc++;
1640   SILC_PUT32_MSB(pc, iv + 8);
1641
1642   /* Reset block counter */
1643   memset(iv + 12, 0, 4);
1644
1645   /* If IV Included flag, return the 64-bit IV for inclusion in packet */
1646   if (stream->iv_included) {
1647     /* Get new nonce */
1648     ret_iv[0] = silc_rng_get_byte_fast(stream->sc->engine->rng);
1649     ret_iv[1] = ret_iv[0] + iv[4];
1650     ret_iv[2] = ret_iv[0] ^ ret_iv[1];
1651     ret_iv[3] = ret_iv[0] + ret_iv[2];
1652     SILC_PUT32_MSB(pc, ret_iv + 4);
1653     SILC_LOG_HEXDUMP(("IV"), ret_iv, 8);
1654
1655     /* Set new nonce to counter block */
1656     memcpy(iv + 4, ret_iv, 4);
1657   }
1658
1659   SILC_LOG_HEXDUMP(("Counter Block"), iv, 16);
1660 }
1661
1662 /* Decrypts SILC packet.  Handles both normal and special packet decryption.
1663    Return 0 when packet is normal and 1 when it it special, -1 on error. */
1664
1665 static inline int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
1666                                       SilcUInt32 sequence, SilcBuffer buffer,
1667                                       SilcBool normal)
1668 {
1669   if (normal == TRUE) {
1670     if (silc_likely(cipher)) {
1671       /* Decrypt rest of the packet */
1672       SILC_LOG_DEBUG(("Decrypting the packet"));
1673       if (silc_unlikely(!silc_cipher_decrypt(cipher, buffer->data,
1674                                              buffer->data,
1675                                              silc_buffer_len(buffer), NULL)))
1676         return -1;
1677     }
1678     return 0;
1679
1680   } else {
1681     /* Decrypt rest of the header plus padding */
1682     if (silc_likely(cipher)) {
1683       SilcUInt16 len;
1684       SilcUInt32 block_len = silc_cipher_get_block_len(cipher);
1685
1686       SILC_LOG_DEBUG(("Decrypting the header"));
1687
1688       /* Padding length + src id len + dst id len + header length - 16
1689          bytes already decrypted, gives the rest of the encrypted packet */
1690       silc_buffer_push(buffer, block_len);
1691       len = (((SilcUInt8)buffer->data[4] + (SilcUInt8)buffer->data[6] +
1692               (SilcUInt8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
1693              block_len);
1694       silc_buffer_pull(buffer, block_len);
1695
1696       if (silc_unlikely(len > silc_buffer_len(buffer))) {
1697         SILC_LOG_ERROR(("Garbage in header of packet, bad packet length, "
1698                         "packet dropped"));
1699         return -1;
1700       }
1701       if (silc_unlikely(!silc_cipher_decrypt(cipher, buffer->data,
1702                                              buffer->data, len, NULL)))
1703         return -1;
1704     }
1705
1706     return 1;
1707   }
1708 }
1709
1710 /* Parses the packet. This is called when a whole packet is ready to be
1711    parsed. The buffer sent must be already decrypted before calling this
1712    function. */
1713
1714 static inline SilcBool silc_packet_parse(SilcPacket packet)
1715 {
1716   SilcBuffer buffer = &packet->buffer;
1717   SilcUInt8 padlen = (SilcUInt8)buffer->data[4];
1718   SilcUInt8 src_id_len, dst_id_len, src_id_type, dst_id_type;
1719   int ret;
1720
1721   SILC_LOG_DEBUG(("Parsing incoming packet"));
1722
1723   /* Parse the buffer.  This parses the SILC header of the packet. */
1724   ret = silc_buffer_unformat(buffer,
1725                              SILC_STR_ADVANCE,
1726                              SILC_STR_OFFSET(6),
1727                              SILC_STR_UI_CHAR(&src_id_len),
1728                              SILC_STR_UI_CHAR(&dst_id_len),
1729                              SILC_STR_UI_CHAR(&src_id_type),
1730                              SILC_STR_END);
1731   if (silc_unlikely(ret == -1)) {
1732     if (!packet->stream->udp &&
1733         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1734       SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1735     return FALSE;
1736   }
1737
1738   if (silc_unlikely(src_id_len > SILC_PACKET_MAX_ID_LEN ||
1739                     dst_id_len > SILC_PACKET_MAX_ID_LEN)) {
1740     if (!packet->stream->udp &&
1741         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1742       SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
1743                       packet->src_id_len, packet->dst_id_len));
1744     return FALSE;
1745   }
1746
1747   ret = silc_buffer_unformat(buffer,
1748                              SILC_STR_ADVANCE,
1749                              SILC_STR_DATA(&packet->src_id, src_id_len),
1750                              SILC_STR_UI_CHAR(&dst_id_type),
1751                              SILC_STR_DATA(&packet->dst_id, dst_id_len),
1752                              SILC_STR_OFFSET(padlen),
1753                              SILC_STR_END);
1754   if (silc_unlikely(ret == -1)) {
1755     if (!packet->stream->udp &&
1756         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1757       SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
1758     return FALSE;
1759   }
1760
1761   if (silc_unlikely(src_id_type > SILC_ID_CHANNEL ||
1762                     dst_id_type > SILC_ID_CHANNEL)) {
1763     if (!packet->stream->udp &&
1764         !silc_socket_stream_is_udp(packet->stream->stream, NULL))
1765       SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
1766                       src_id_type, dst_id_type));
1767     return FALSE;
1768   }
1769
1770   packet->src_id_len = src_id_len;
1771   packet->dst_id_len = dst_id_len;
1772   packet->src_id_type = src_id_type;
1773   packet->dst_id_type = dst_id_type;
1774
1775   SILC_LOG_HEXDUMP(("Parsed packet, len %d", silc_buffer_headlen(buffer) +
1776                    silc_buffer_len(buffer)), buffer->head,
1777                    silc_buffer_headlen(buffer) + silc_buffer_len(buffer));
1778
1779   SILC_LOG_DEBUG(("Incoming packet type: %d (%s)", packet->type,
1780                   silc_get_packet_name(packet->type)));
1781
1782   return TRUE;
1783 }
1784
1785 /* Dispatch packet to application.  Called with stream->lock locked.
1786    Returns FALSE if the stream was destroyed while dispatching a packet. */
1787
1788 static SilcBool silc_packet_dispatch(SilcPacket packet)
1789 {
1790   SilcPacketStream stream = packet->stream;
1791   SilcPacketProcess p;
1792   SilcBool default_sent = FALSE;
1793   SilcPacketType *pt;
1794
1795   /* Dispatch packet to all packet processors that want it */
1796
1797   if (silc_likely(!stream->process)) {
1798     /* Send to default processor as no others exist */
1799     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1800     silc_mutex_unlock(stream->lock);
1801     if (silc_unlikely(!stream->sc->engine->callbacks->
1802                       packet_receive(stream->sc->engine, stream, packet,
1803                                      stream->sc->engine->callback_context,
1804                                      stream->stream_context)))
1805       silc_packet_free(packet);
1806     silc_mutex_lock(stream->lock);
1807     return stream->destroyed == FALSE;
1808   }
1809
1810   silc_dlist_start(stream->process);
1811   while ((p = silc_dlist_get(stream->process)) != SILC_LIST_END) {
1812
1813     /* If priority is 0 or less, we send to default processor first
1814        because default processor has 0 priority */
1815     if (!default_sent && p->priority <= 0) {
1816       SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1817       default_sent = TRUE;
1818       silc_mutex_unlock(stream->lock);
1819       if (stream->sc->engine->callbacks->
1820           packet_receive(stream->sc->engine, stream, packet,
1821                          stream->sc->engine->callback_context,
1822                          stream->stream_context)) {
1823         silc_mutex_lock(stream->lock);
1824         return stream->destroyed == FALSE;
1825       }
1826       silc_mutex_lock(stream->lock);
1827     }
1828
1829     /* Send to processor */
1830     if (!p->types) {
1831       /* Send all packet types */
1832       SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1833       silc_mutex_unlock(stream->lock);
1834       if (p->callbacks->packet_receive(stream->sc->engine, stream, packet,
1835                                        p->callback_context,
1836                                        stream->stream_context)) {
1837         silc_mutex_lock(stream->lock);
1838         return stream->destroyed == FALSE;
1839       }
1840       silc_mutex_lock(stream->lock);
1841     } else {
1842       /* Send specific types */
1843       for (pt = p->types; *pt; pt++) {
1844         if (*pt != packet->type)
1845           continue;
1846         SILC_LOG_DEBUG(("Dispatching packet to %p callbacks", p->callbacks));
1847         silc_mutex_unlock(stream->lock);
1848         if (p->callbacks->packet_receive(stream->sc->engine, stream, packet,
1849                                          p->callback_context,
1850                                          stream->stream_context)) {
1851           silc_mutex_lock(stream->lock);
1852           return stream->destroyed == FALSE;
1853         }
1854         silc_mutex_lock(stream->lock);
1855         break;
1856       }
1857     }
1858   }
1859
1860   if (!default_sent) {
1861     /* Send to default processor as it has not been sent yet */
1862     SILC_LOG_DEBUG(("Dispatching packet to default callbacks"));
1863     silc_mutex_unlock(stream->lock);
1864     if (stream->sc->engine->callbacks->
1865         packet_receive(stream->sc->engine, stream, packet,
1866                        stream->sc->engine->callback_context,
1867                        stream->stream_context)) {
1868       silc_mutex_lock(stream->lock);
1869       return stream->destroyed == FALSE;
1870     }
1871     silc_mutex_lock(stream->lock);
1872   }
1873
1874   /* If we got here, no one wanted the packet, so drop it */
1875   silc_packet_free(packet);
1876   return stream->destroyed == FALSE;
1877 }
1878
1879 /* Process incoming data and parse packets.  Called with stream->lock
1880    locked. */
1881
1882 static void silc_packet_read_process(SilcPacketStream stream)
1883 {
1884   SilcBuffer inbuf = &stream->sc->inbuf;
1885   SilcCipher cipher;
1886   SilcHmac hmac;
1887   SilcPacket packet;
1888   SilcUInt8 sid;
1889   SilcUInt16 packetlen;
1890   SilcUInt32 paddedlen, mac_len, block_len, ivlen, psnlen;
1891   unsigned char tmp[SILC_PACKET_MIN_HEADER_LEN], *header;
1892   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE], *packet_seq = NULL;
1893   SilcBool normal;
1894   int ret;
1895
1896   /* Parse the packets from the data */
1897   while (silc_buffer_len(inbuf) > 0) {
1898     ivlen = psnlen = 0;
1899     cipher = stream->receive_key[0];
1900     hmac = stream->receive_hmac[0];
1901     normal = FALSE;
1902
1903     if (silc_unlikely(silc_buffer_len(inbuf) <
1904                       (stream->iv_included ? SILC_PACKET_MIN_HEADER_LEN_IV :
1905                        SILC_PACKET_MIN_HEADER_LEN))) {
1906       SILC_LOG_DEBUG(("Partial packet in queue, waiting for the rest"));
1907       return;
1908     }
1909
1910     if (silc_likely(hmac))
1911       mac_len = silc_hmac_len(hmac);
1912     else
1913       mac_len = 0;
1914
1915     /* Decrypt first block of the packet to get the length field out */
1916     if (silc_likely(cipher)) {
1917       block_len = silc_cipher_get_block_len(cipher);
1918
1919       if (stream->iv_included) {
1920         /* SID, IV and sequence number is included in the ciphertext */
1921         sid = (SilcUInt8)inbuf->data[0];
1922         memcpy(iv, inbuf->data + 1, block_len);
1923         ivlen = block_len + 1;
1924         psnlen = 4;
1925
1926         /* Check SID, and get correct decryption key */
1927         if (sid != stream->sid) {
1928           /* If SID is recent get the previous key and use it */
1929           if (sid > 0 && stream->sid > 0 && stream->sid - 1 == sid &&
1930               stream->receive_key[1] && !stream->receive_hmac[1]) {
1931             cipher = stream->receive_key[1];
1932             hmac = stream->receive_hmac[1];
1933           } else {
1934             /* The SID is unknown, drop rest of the data in buffer */
1935             SILC_LOG_DEBUG(("Unknown Security ID %d in packet, expected %d",
1936                             sid, stream->sid));
1937             silc_mutex_unlock(stream->lock);
1938             SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_UNKNOWN_SID);
1939             silc_mutex_lock(stream->lock);
1940             silc_buffer_reset(inbuf);
1941             return;
1942           }
1943         }
1944       } else {
1945         memcpy(iv, silc_cipher_get_iv(cipher), block_len);
1946       }
1947
1948       silc_cipher_decrypt(cipher, inbuf->data + ivlen, tmp,
1949                           block_len, iv);
1950
1951       header = tmp;
1952       if (stream->iv_included) {
1953         /* Take sequence number from packet */
1954         packet_seq = header;
1955         header += 4;
1956       }
1957     } else {
1958       block_len = SILC_PACKET_MIN_HEADER_LEN;
1959       header = inbuf->data;
1960     }
1961
1962     /* Get packet length and full packet length with padding */
1963     SILC_PACKET_LENGTH(header, packetlen, paddedlen);
1964
1965     /* Sanity checks */
1966     if (silc_unlikely(packetlen < SILC_PACKET_MIN_LEN)) {
1967       if (!stream->udp && !silc_socket_stream_is_udp(stream->stream, NULL))
1968         SILC_LOG_ERROR(("Received too short packet"));
1969       silc_mutex_unlock(stream->lock);
1970       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
1971       silc_mutex_lock(stream->lock);
1972       memset(tmp, 0, sizeof(tmp));
1973       silc_buffer_reset(inbuf);
1974       return;
1975     }
1976
1977     if (silc_buffer_len(inbuf) < paddedlen + ivlen + mac_len) {
1978       SILC_LOG_DEBUG(("Received partial packet, waiting for the rest "
1979                       "(%d bytes)",
1980                       paddedlen + mac_len - silc_buffer_len(inbuf)));
1981       memset(tmp, 0, sizeof(tmp));
1982       return;
1983     }
1984
1985     /* Check MAC of the packet */
1986     if (silc_unlikely(!silc_packet_check_mac(hmac, inbuf->data,
1987                                              paddedlen + ivlen,
1988                                              inbuf->data + ivlen +
1989                                              paddedlen, packet_seq,
1990                                              stream->receive_psn))) {
1991       silc_mutex_unlock(stream->lock);
1992       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MAC_FAILED);
1993       silc_mutex_lock(stream->lock);
1994       memset(tmp, 0, sizeof(tmp));
1995       silc_buffer_reset(inbuf);
1996       return;
1997     }
1998
1999     /* Get packet */
2000     packet = silc_packet_alloc(stream->sc->engine);
2001     if (silc_unlikely(!packet)) {
2002       silc_mutex_unlock(stream->lock);
2003       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
2004       silc_mutex_lock(stream->lock);
2005       memset(tmp, 0, sizeof(tmp));
2006       silc_buffer_reset(inbuf);
2007       return;
2008     }
2009     packet->stream = stream;
2010
2011     /* Allocate more space to packet buffer, if needed */
2012     if (silc_unlikely(silc_buffer_truelen(&packet->buffer) < paddedlen)) {
2013       if (!silc_buffer_realloc(&packet->buffer,
2014                                silc_buffer_truelen(&packet->buffer) +
2015                                (paddedlen -
2016                                 silc_buffer_truelen(&packet->buffer)))) {
2017         silc_mutex_unlock(stream->lock);
2018         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_NO_MEMORY);
2019         silc_mutex_lock(stream->lock);
2020         silc_packet_free(packet);
2021         memset(tmp, 0, sizeof(tmp));
2022         silc_buffer_reset(inbuf);
2023         return;
2024       }
2025     }
2026
2027     /* Parse packet header */
2028     packet->flags = (SilcPacketFlags)header[2];
2029     packet->type = (SilcPacketType)header[3];
2030
2031     if (stream->sc->engine->local_is_router) {
2032       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
2033           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
2034         normal = FALSE;
2035       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE ||
2036                (packet->type == SILC_PACKET_CHANNEL_MESSAGE &&
2037                 stream->is_router == TRUE))
2038         normal = TRUE;
2039     } else {
2040       if (packet->type == SILC_PACKET_PRIVATE_MESSAGE &&
2041           (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY))
2042         normal = FALSE;
2043       else if (packet->type != SILC_PACKET_CHANNEL_MESSAGE)
2044         normal = TRUE;
2045     }
2046
2047     SILC_LOG_HEXDUMP(("Incoming packet (%d) len %d",
2048                       stream->receive_psn, paddedlen + ivlen + mac_len),
2049                      inbuf->data, paddedlen + ivlen + mac_len);
2050
2051     /* Put the decrypted part, and rest of the encrypted data, and decrypt */
2052     silc_buffer_pull_tail(&packet->buffer, paddedlen);
2053     silc_buffer_put(&packet->buffer, header, block_len - psnlen);
2054     silc_buffer_pull(&packet->buffer, block_len - psnlen);
2055     silc_buffer_put(&packet->buffer, (inbuf->data + ivlen +
2056                                       psnlen + (block_len - psnlen)),
2057                     paddedlen - ivlen - psnlen - (block_len - psnlen));
2058     if (silc_likely(cipher)) {
2059       silc_cipher_set_iv(cipher, iv);
2060       ret = silc_packet_decrypt(cipher, hmac, stream->receive_psn,
2061                                 &packet->buffer, normal);
2062       if (silc_unlikely(ret < 0)) {
2063         silc_mutex_unlock(stream->lock);
2064         SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_DECRYPTION_FAILED);
2065         silc_mutex_lock(stream->lock);
2066         silc_packet_free(packet);
2067         memset(tmp, 0, sizeof(tmp));
2068         return;
2069       }
2070
2071       stream->receive_psn++;
2072     }
2073     silc_buffer_push(&packet->buffer, block_len);
2074
2075     /* Pull the packet from inbuf thus we'll get the next one in the inbuf. */
2076     silc_buffer_pull(inbuf, paddedlen + mac_len);
2077
2078     /* Parse the packet */
2079     if (silc_unlikely(!silc_packet_parse(packet))) {
2080       silc_mutex_unlock(stream->lock);
2081       SILC_PACKET_CALLBACK_ERROR(stream, SILC_PACKET_ERR_MALFORMED);
2082       silc_mutex_lock(stream->lock);
2083       silc_packet_free(packet);
2084       memset(tmp, 0, sizeof(tmp));
2085       return;
2086     }
2087
2088     /* Dispatch the packet to application */
2089     if (!silc_packet_dispatch(packet))
2090       break;
2091   }
2092
2093   silc_buffer_reset(inbuf);
2094 }
2095
2096
2097 /****************************** Packet Waiting ******************************/
2098
2099 /* Packet wait receive callback */
2100 static SilcBool
2101 silc_packet_wait_packet_receive(SilcPacketEngine engine,
2102                                 SilcPacketStream stream,
2103                                 SilcPacket packet,
2104                                 void *callback_context,
2105                                 void *stream_context);
2106
2107 /* Packet waiting callbacks */
2108 static SilcPacketCallbacks silc_packet_wait_cbs =
2109 {
2110   silc_packet_wait_packet_receive, NULL, NULL
2111 };
2112
2113 /* Packet waiting context */
2114 typedef struct {
2115   SilcMutex wait_lock;
2116   SilcCond wait_cond;
2117   SilcList packet_queue;
2118   unsigned int stopped     : 1;
2119 } *SilcPacketWait;
2120
2121 /* Packet wait receive callback */
2122
2123 static SilcBool
2124 silc_packet_wait_packet_receive(SilcPacketEngine engine,
2125                                 SilcPacketStream stream,
2126                                 SilcPacket packet,
2127                                 void *callback_context,
2128                                 void *stream_context)
2129 {
2130   SilcPacketWait pw = callback_context;
2131
2132   /* Signal the waiting thread for a new packet */
2133   silc_mutex_lock(pw->wait_lock);
2134
2135   if (silc_unlikely(pw->stopped)) {
2136     silc_mutex_unlock(pw->wait_lock);
2137     return FALSE;
2138   }
2139
2140   silc_list_add(pw->packet_queue, packet);
2141   silc_cond_broadcast(pw->wait_cond);
2142
2143   silc_mutex_unlock(pw->wait_lock);
2144
2145   return TRUE;
2146 }
2147
2148 /* Initialize packet waiting */
2149
2150 void *silc_packet_wait_init(SilcPacketStream stream, ...)
2151 {
2152   SilcPacketWait pw;
2153   SilcBool ret;
2154   va_list ap;
2155
2156   pw = silc_calloc(1, sizeof(*pw));
2157   if (!pw)
2158     return NULL;
2159
2160   /* Allocate mutex and conditional variable */
2161   if (!silc_mutex_alloc(&pw->wait_lock)) {
2162     silc_free(pw);
2163     return NULL;
2164   }
2165   if (!silc_cond_alloc(&pw->wait_cond)) {
2166     silc_mutex_free(pw->wait_lock);
2167     silc_free(pw);
2168     return NULL;
2169   }
2170
2171   /* Link to the packet stream for the requested packet types */
2172   va_start(ap, stream);
2173   ret = silc_packet_stream_link_va(stream, &silc_packet_wait_cbs, pw,
2174                                    10000000, ap);
2175   va_end(ap);
2176   if (!ret) {
2177     silc_cond_free(pw->wait_cond);
2178     silc_mutex_free(pw->wait_lock);
2179     silc_free(pw);
2180     return NULL;
2181   }
2182
2183   /* Initialize packet queue */
2184   silc_list_init(pw->packet_queue, struct SilcPacketStruct, next);
2185
2186   return (void *)pw;
2187 }
2188
2189 /* Uninitialize packet waiting */
2190
2191 void silc_packet_wait_uninit(void *waiter, SilcPacketStream stream)
2192 {
2193   SilcPacketWait pw = waiter;
2194   SilcPacket packet;
2195
2196   /* Signal any threads to stop waiting */
2197   silc_mutex_lock(pw->wait_lock);
2198   pw->stopped = TRUE;
2199   silc_cond_broadcast(pw->wait_cond);
2200   silc_mutex_unlock(pw->wait_lock);
2201
2202   /* Re-acquire lock and free resources */
2203   silc_mutex_lock(pw->wait_lock);
2204   silc_packet_stream_unlink(stream, &silc_packet_wait_cbs, pw);
2205
2206   /* Free any remaining packets */
2207   silc_list_start(pw->packet_queue);
2208   while ((packet = silc_list_get(pw->packet_queue)) != SILC_LIST_END)
2209     silc_packet_free(packet);
2210
2211   silc_mutex_unlock(pw->wait_lock);
2212   silc_cond_free(pw->wait_cond);
2213   silc_mutex_free(pw->wait_lock);
2214   silc_free(pw);
2215 }
2216
2217 /* Blocks thread until a packet has been received. */
2218
2219 int silc_packet_wait(void *waiter, int timeout, SilcPacket *return_packet)
2220 {
2221   SilcPacketWait pw = waiter;
2222   SilcBool ret = FALSE;
2223
2224   silc_mutex_lock(pw->wait_lock);
2225
2226   /* Wait here until packet has arrived */
2227   while (silc_list_count(pw->packet_queue) == 0) {
2228     if (silc_unlikely(pw->stopped)) {
2229       silc_mutex_unlock(pw->wait_lock);
2230       return -1;
2231     }
2232     ret = silc_cond_timedwait(pw->wait_cond, pw->wait_lock, timeout);
2233   }
2234
2235   /* Return packet */
2236   silc_list_start(pw->packet_queue);
2237   *return_packet = silc_list_get(pw->packet_queue);
2238   silc_list_del(pw->packet_queue, *return_packet);
2239
2240   silc_mutex_unlock(pw->wait_lock);
2241
2242   return ret == TRUE ? 1 : 0;
2243 }