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