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