Added reference count to SilcPacketContext and added two new
[silc.git] / lib / silccore / silcpacket.h
1 /*
2
3   silcpacket.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 #ifndef SILCPACKET_H
22 #define SILCPACKET_H
23
24 /* Amount of bytes to be read from the socket connection at once. */
25 #define SILC_PACKET_READ_SIZE 16384
26
27 /* Default byte size of the packet. This can be set larger if this
28    is not enough, we shall see. */
29 #define SILC_PACKET_DEFAULT_SIZE 2048
30
31 /* Header length without source and destination ID's. */
32 #define SILC_PACKET_HEADER_LEN 8 + 2
33
34 /* Minimum length of SILC Packet Header. This much is decrypted always
35    when packet is received to be able to get all the relevant data out
36    from the header. */
37 #define SILC_PACKET_MIN_HEADER_LEN 16 + 2
38
39 /* Maximum padding length */
40 #define SILC_PACKET_MAX_PADLEN 16
41
42 /* Minimum packet length */
43 #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1)
44
45 /* Maximum length of ID */
46 #define SILC_PACKET_MAX_ID_LEN 16
47
48 /* SILC packet type definition. For now, it is defined like this and I don't 
49    expect it to change in any near future. If one byte as a packet type is 
50    not enough we can, then, think something else. */
51 typedef unsigned char SilcPacketType;
52
53 /* SILC packet version type definition. */
54 typedef unsigned char SilcPacketVersion;
55
56 /* SILC packet flags type definition. */
57 typedef unsigned char SilcPacketFlags;
58
59 /* All defined packet flags */
60 #define SILC_PACKET_FLAG_NONE             0x00
61 #define SILC_PACKET_FLAG_PRIVMSG_KEY      0x01
62 #define SILC_PACKET_FLAG_FORWARDED        0x02
63 #define SILC_PACKET_FLAG_BROADCAST        0x04
64 #define SILC_PACKET_FLAG_TUNNELED         0x08
65 /* Rest of flags still available
66 #define SILC_PACKET_FLAG_XXX              0x10
67 #define SILC_PACKET_FLAG_XXX              0x20
68 #define SILC_PACKET_FLAG_XXX              0x40
69 #define SILC_PACKET_FLAG_XXX              0x80
70 */
71
72 /* 
73    SILC packet context. 
74
75    In packet sending this is filled and sent to silc_packet_assemble 
76    which then uses it to assemble new packet. In packet reception pointer 
77    to this context is sent to silc_packet_parse which parses the packet 
78    and returns the relevant information to this structure. On packet 
79    reception returned ID's are always the hash values of the ID's from 
80    the packet. 
81
82    Short description of the fields following:
83
84    SilcBuffer buffer
85
86        The data buffer.
87
88    SilcPacketType type
89
90        Type of the packet. Types are defined below.
91
92    SilcPacketFlags flags
93
94        Packet flags. Flags are defined above.
95
96    unsigned char *src_id
97    unsigned short src_id_len
98    unsigned char src_id_type
99
100        Source ID, its length and type. On packet reception retuned ID's
101        are always the hash values of the ID's from the packet.
102
103   unsigned char *dst_id;
104   unsigned short dst_id_len;
105   unsigned char src_id_type;
106
107        Destination ID, its length and type. On packet reception retuned
108        ID's are always the hash values of the ID's from the packet.
109
110    SilcHash hash
111
112        Pointer to allocated hash object. This must be MD5 hash object.
113        This is used to calculate checksum of the packet.
114
115 */
116 typedef struct {
117   SilcBuffer buffer;
118   SilcPacketType type;
119   SilcPacketFlags flags;
120
121   unsigned char *src_id;
122   unsigned short src_id_len;
123   unsigned char src_id_type;
124
125   unsigned char *dst_id;
126   unsigned short dst_id_len;
127   unsigned char dst_id_type;
128
129   unsigned short truelen;
130   unsigned short padlen;
131
132   /* For padding generation */
133   SilcRng rng;
134
135   /* Back pointers */
136   void *context;
137   SilcSocketConnection sock;
138
139   /* Reference count for this context. The context is free'd only
140      after the reference count is zero. */
141   int users;
142 } SilcPacketContext;
143
144 /* 
145    Silc Packet Parser context.
146
147    This context is used in packet reception when silc_packet_receive_process
148    function calls parser callback that performs the actual packet decryption
149    and parsing. This context is sent as argument to the parser function.
150    This context must be free'd by the parser callback function.
151
152    Following description of the fields:
153
154    SilcPacketContext *packet
155
156        The actual packet received from the network. In this phase the
157        context is not parsed, only the packet->buffer is allocated and
158        it includes the raw packet data, which is encrypted.
159
160    SilcSocketConnection sock
161
162        The associated connection.
163
164    SilcCipher cipher
165
166        The cipher to be used in the decryption.
167
168    SilcHmac hmac
169
170        The HMAC to be used in the decryption.
171
172    void *context
173
174        User context that is sent to the silc_packet_receive_process
175        function. This usually includes application and connection specific
176        data.
177
178 */
179
180 typedef struct {
181   SilcPacketContext *packet;
182   SilcSocketConnection sock;
183   SilcCipher cipher;
184   SilcHmac hmac;
185   void *context;
186 } SilcPacketParserContext;
187
188 /* The parser callback function. */
189 typedef void (*SilcPacketParserCallback)(SilcPacketParserContext 
190                                          *parse_context);
191
192
193 /* SILC Packet types. */
194 #define SILC_PACKET_NONE                 0       /* NULL, never sent */
195 #define SILC_PACKET_DISCONNECT           1       /* Disconnection */
196 #define SILC_PACKET_SUCCESS              2       /* Success */
197 #define SILC_PACKET_FAILURE              3       /* Failure */
198 #define SILC_PACKET_REJECT               4       /* Rejected */
199 #define SILC_PACKET_NOTIFY               5       /* Notify message */
200 #define SILC_PACKET_ERROR                6       /* Error message */
201 #define SILC_PACKET_CHANNEL_MESSAGE      7       /* Message for channel */
202 #define SILC_PACKET_CHANNEL_KEY          8       /* Key of the channel */
203 #define SILC_PACKET_PRIVATE_MESSAGE      9       /* Private message */
204 #define SILC_PACKET_PRIVATE_MESSAGE_KEY  10      /* Private message key*/
205 #define SILC_PACKET_COMMAND              11      /* Command */
206 #define SILC_PACKET_COMMAND_REPLY        12      /* Reply to a command */
207 #define SILC_PACKET_KEY_EXCHANGE         13      /* Start of KE */
208 #define SILC_PACKET_KEY_EXCHANGE_1       14      /* KE1 */
209 #define SILC_PACKET_KEY_EXCHANGE_2       15      /* KE2 */
210 #define SILC_PACKET_CONNECTION_AUTH_REQUEST 16   /* Request of auth meth */
211 #define SILC_PACKET_CONNECTION_AUTH      17      /* Connectinon auth */
212 #define SILC_PACKET_NEW_ID               18      /* Sending new ID */
213 #define SILC_PACKET_NEW_ID_LIST          19      /* Sending list of them */
214 #define SILC_PACKET_NEW_CLIENT           20      /* Registering client */
215 #define SILC_PACKET_NEW_SERVER           21      /* Registering server */
216 #define SILC_PACKET_NEW_CHANNEL          22      /* Registering channel */
217 #define SILC_PACKET_NEW_CHANNEL_USER     23      /*   "" user on channel */
218 #define SILC_PACKET_NEW_CHANNEL_LIST     24      /* List of new channels */
219 #define SILC_PACKET_NEW_CHANNEL_USER_LIST 25     /* List of users on "" */
220 #define SILC_PACKET_REPLACE_ID           26      /* To replace old ID */
221 #define SILC_PACKET_REMOVE_ID            27      /* To remove ID */
222 #define SILC_PACKET_REMOVE_CHANNEL_USER  28      /* Remove user from channel */
223 #define SILC_PACKET_REKEY                29
224 #define SILC_PACKET_REKEY_DONE           30
225 /* #define SILC_PACKET_MAX               255 */
226
227 /* Macros */
228
229 /* Returns true length of the packet and padded length of the packet */
230 #define SILC_PACKET_LENGTH(__packet, __ret_truelen, __ret_padlen)            \
231 do {                                                                         \
232   SILC_GET16_MSB((__ret_truelen), (__packet)->data);                         \
233   (__ret_padlen) = (((__ret_truelen) - 2) +                                  \
234                     SILC_PACKET_MAX_PADLEN) & ~(SILC_PACKET_MAX_PADLEN - 1); \
235 } while(0)
236
237 /* Returns pad length of the packet */
238 #define SILC_PACKET_PADLEN(__packetlen)                                  \
239   SILC_PACKET_MAX_PADLEN - ((__packetlen) - 2) % SILC_PACKET_MAX_PADLEN;
240
241 /* Prototypes */
242 int silc_packet_write(int sock, SilcBuffer src);
243 int silc_packet_send(SilcSocketConnection sock, int force_send);
244 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, 
245                          SilcBuffer buffer, unsigned int len);
246 void silc_packet_assemble(SilcPacketContext *ctx);
247 void silc_packet_send_prepare(SilcSocketConnection sock,
248                               unsigned int header_len,
249                               unsigned int padlen,
250                               unsigned int data_len);
251 int silc_packet_read(int sock, SilcBuffer dest);
252 int silc_packet_receive(SilcSocketConnection sock);
253 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
254                         SilcBuffer buffer, SilcPacketContext *packet);
255 void silc_packet_receive_process(SilcSocketConnection sock,
256                                  SilcCipher cipher, SilcHmac hmac,
257                                  SilcPacketParserCallback parser,
258                                  void *context);
259 SilcPacketType silc_packet_parse(SilcPacketContext *ctx);
260 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx);
261 SilcPacketContext *silc_packet_context_alloc();
262 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx);
263 void silc_packet_context_free(SilcPacketContext *ctx);
264
265 #endif