Merged silc_1_1_branch to trunk.
[silc.git] / lib / silccore / README
1 The SILC Core Library
2
3 This library contains the implementation of various SILC protocol packet
4 payloads and other routines.  It also implements the SILC Packet Engine.
5
6
7 The SILC Packet Engine
8
9 The SILC Packet engine (silcpacket.[ch]) is the heart of sending and
10 receiving SILC packets.  The engine works in single thread but is thread
11 safe and has the notion of per-thread contexts for optimized processing.
12 The per-thread processing is actually per-scheduler, but in reality multiple
13 schedulers are run only when they are used in threads.
14
15 The packet engine has a lock (engine->lock) that protects various engine
16 wide data.  Currently this includes SILC Packet freelist, which could
17 perhaps later be in the per-thread SilcPacketEngineContext context.  The
18 engine also keeps list of all streams (SilcPacketStream) that has been
19 added to the engine.
20
21 The SilcPacketStream contains all stream related data, including encryption
22 and decryption keys, IDs, and outgoing buffer.  The outgoing buffer is
23 per-stream so that data can be sent in multiple pieces from the outbuffer
24 if writing would block.  Incoming buffer is not in stream context unless
25 it is necessary.  The incoming buffer is in the per-thread context which
26 actually has a list of incoming buffers.  If reading blocks for the given
27 stream, that incoming buffer is given to the SilcPacketStream context from
28 the list of buffers.  When data is again available for that stream it is
29 read into the buffer the stream already has.  Other stream will read to
30 the per-thread buffer, unless they would block also.  The stream also
31 has a lock (stream->lock) because application can modify various data in
32 the stream.
33
34 The packet callback has packet callbacks that is used to deliver the read
35 packet to application.  The callbacks also deliver error and end of stream
36 status to application.  It is also possible to attach additional packet
37 callbacks to stream so that there may be multiple receivers for one packet.
38 In the callback application may decide whether it wants to take the packet
39 or whether to pass it for the next receiver.  The callbacks can be added
40 with priority.
41
42
43 Locking in packet engine
44
45 Currently the engine lock is used only when the packet free list is accessed,
46 or new stream is added or removed.  The packet free list, however, is
47 accessed for all incoming packets.  Application free's the packet context so
48 the lock must later be acquired for putting the unused packet context back
49 to the free list.  It might be possible to later put the packet free list to
50 per-thread context.
51
52 Stream lock is taken everytime data is read from the underlaying stream or
53 sent to the underlaying stream.  In principal it would be possible to read
54 without locking, because we use per-thread incoming buffers but in reality
55 many platforms would not suppots reading and writing to the same underlaying
56 stream (effectively socket) at the same time.  And even if they would, some
57 rare race conditions with closing the stream might occur.  One way of dealing
58 with this would be to make sure that any stream used with SilcPacketStream
59 must itself be thread-safe.  In that case the locking would move to the
60 underlaying stream.
61
62 When reading data from stream, the lock is held during reading and during
63 data processing.  The lock is released when the packet is dispatched to
64 a packet callback.
65
66 When sending packet the lock is acquired only when actually accessing the
67 outgoing buffer and writing to the stream.  This includes encryption.  This
68 means that if two threads send to same stream the encryption is not in
69 parallel.