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