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