updates.
[silc.git] / lib / silcclient / client.h
1 /*
2
3   client.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 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 CLIENT_H
22 #define CLIENT_H
23
24 /* Forward declarations */
25 typedef struct SilcClientStruct *SilcClient;
26 typedef struct SilcClientConnectionStruct *SilcClientConnection;
27 typedef struct SilcClientPingStruct SilcClientPing;
28 typedef struct SilcClientAwayStruct SilcClientAway;
29 typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
30
31 #include "idlist.h"
32 #include "command.h"
33 #include "silcapi.h"
34
35 /* Connection structure used in client to associate all the important
36    connection specific data to this structure. */
37 struct SilcClientConnectionStruct {
38   /*
39    * Local data 
40    */
41   char *nickname;
42
43   /* Local client ID for this connection */
44   SilcClientID *local_id;
45
46   /* Decoded local ID so that the above defined ID would not have
47      to be decoded for every packet. */
48   unsigned char *local_id_data;
49   unsigned int local_id_data_len;
50
51   /* Own client entry. */
52   SilcClientEntry local_entry;
53
54   /*
55    * Remote data 
56    */
57   char *remote_host;
58   int remote_port;
59   int remote_type;
60   char *remote_info;
61
62   /* Remote server ID for this connection */
63   SilcServerID *remote_id;
64
65   /* Decoded remote ID so that the above defined ID would not have
66      to be decoded for every packet. */
67   unsigned char *remote_id_data;
68   unsigned int remote_id_data_len;
69
70   /*
71    * Common data 
72    */
73   /* Keys */
74   SilcCipher send_key;
75   SilcCipher receive_key;
76   SilcHmac hmac;
77   unsigned char *hmac_key;
78   unsigned int hmac_key_len;
79
80   /* Client ID and Channel ID cache. Messages transmitted in SILC network
81      are done using different unique ID's. These are the cache for
82      thoses ID's used in the communication. */
83   SilcIDCache client_cache;
84   SilcIDCache channel_cache;
85   SilcIDCache server_cache;
86
87   /* Current channel on window. All channels are saved (allocated) into
88      the cache entries. */
89   SilcChannelEntry current_channel;
90
91   /* Socket connection object for this connection (window). This
92      object will have a back-pointer to this window object for fast
93      referencing (sock->user_data). */
94   SilcSocketConnection sock;
95
96   /* Pending command queue for this connection */
97   SilcDList pending_commands;
98
99   /* Current command identifier, 0 not used */
100   unsigned short cmd_ident;
101
102   /* Requested pings. */
103   SilcClientPing *ping;
104   unsigned int ping_count;
105
106   /* Set away message */
107   SilcClientAway *away;
108
109   /* Pointer back to the SilcClient. This object is passed to the application
110      and the actual client object is accesible through this pointer. */
111   SilcClient client;
112
113   /* User data context. Library does not touch this. */
114   void *context;
115 };
116
117 /* Main client structure. */
118 struct SilcClientStruct {
119   /*
120    * Public data. All the following pointers must be set by the allocator
121    * of this structure.
122    */
123
124   /* Users's username, hostname and realname. */
125   char *username;
126   char *hostname;
127   char *realname;
128
129   /* Private and public key of the user. */
130   SilcPKCS pkcs;
131   SilcPublicKey public_key;
132   SilcPrivateKey private_key;
133
134   /* Application specific user data pointer. Client library does not
135      touch this. */
136   void *application;
137
138   /*
139    * Private data. Following pointers are used internally by the client
140    * library and should be considered read-only fields.
141    */
142
143   /* All client operations that are implemented in the application. */
144   SilcClientOperations *ops;
145
146   /* SILC client task queues */
147   SilcTaskQueue io_queue;
148   SilcTaskQueue timeout_queue;
149   SilcTaskQueue generic_queue;
150
151   /* Table of connections in client. All the connection data is saved here. */
152   SilcClientConnection *conns;
153   unsigned int conns_count;
154
155   /* Table of listenning sockets in client.  Client can have listeners
156      (like key agreement protocol server) and those sockets are saved here.
157      This table is checked always if the connection object cannot be found
158      from the `conns' table. */
159   SilcSocketConnection *sockets;
160   unsigned int sockets_count;
161
162   /* Generic cipher and hash objects. These can be used and referenced
163      by the application as well. */
164   SilcCipher none_cipher;
165   SilcHash md5hash;
166   SilcHash sha1hash;
167   SilcHmac md5hmac;
168   SilcHmac sha1hmac;
169
170   /* Random Number Generator. Application should use this as its primary
171      random number generator. */
172   SilcRng rng;
173 };
174
175 /* Macros */
176
177 /* Registers generic task for file descriptor for reading from network and
178    writing to network. As being generic task the actual task is allocated 
179    only once and after that the same task applies to all registered fd's. */
180 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)                      \
181 do {                                                                    \
182   SilcTask tmptask = silc_task_register(client->generic_queue, (fd),    \
183                                         silc_client_packet_process,     \
184                                         context, 0, 0,                  \
185                                         SILC_TASK_GENERIC,              \
186                                         SILC_TASK_PRI_NORMAL);          \
187   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                       \
188 } while(0)
189
190 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd)                \
191 do {                                                            \
192   silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));    \
193 } while(0)                                                      \
194      
195 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd)               \
196 do {                                                            \
197   silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |   \
198                                      (1L << SILC_TASK_WRITE))); \
199 } while(0)
200
201 /* Finds socket connection object by file descriptor */
202 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
203 do {                                                    \
204   int __i;                                              \
205                                                         \
206   for (__i = 0; __i < (__x)->conns_count; __i++)        \
207     if ((__x)->conns[__i] &&                            \
208         (__x)->conns[__i]->sock->sock == (__fd))        \
209       break;                                            \
210                                                         \
211   if (__i >= (__x)->conns_count) {                      \
212     (__sock) = NULL;                                    \
213     for (__i = 0; __i < (__x)->sockets_count; __i++)    \
214       if ((__x)->sockets[__i] &&                        \
215           (__x)->sockets[__i]->sock == (__fd))          \
216         (__sock) = (__x)->sockets[__i];                 \
217   } else                                                \
218     (__sock) = (__x)->conns[__i]->sock;                 \
219 } while(0)
220
221 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
222
223 void silc_client_packet_send(SilcClient client, 
224                              SilcSocketConnection sock,
225                              SilcPacketType type, 
226                              void *dst_id,
227                              SilcIdType dst_id_type,
228                              SilcCipher cipher,
229                              SilcHmac hmac,
230                              unsigned char *data, 
231                              unsigned int data_len, 
232                              int force_send);
233 void silc_client_disconnected_by_server(SilcClient client,
234                                         SilcSocketConnection sock,
235                                         SilcBuffer message);
236 void silc_client_error_by_server(SilcClient client,
237                                  SilcSocketConnection sock,
238                                  SilcBuffer message);
239 void silc_client_receive_new_id(SilcClient client,
240                                 SilcSocketConnection sock,
241                                 SilcIDPayload idp);
242 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
243                                             SilcSocketConnection sock,
244                                             char *channel_name,
245                                             unsigned int mode, 
246                                             SilcIDPayload idp);
247 void silc_client_save_channel_key(SilcClientConnection conn,
248                                   SilcBuffer key_payload, 
249                                   SilcChannelEntry channel);
250 void silc_client_receive_channel_key(SilcClient client,
251                                      SilcSocketConnection sock,
252                                      SilcBuffer packet);
253 void silc_client_channel_message(SilcClient client, 
254                                  SilcSocketConnection sock, 
255                                  SilcPacketContext *packet);
256 void silc_client_remove_from_channels(SilcClient client,
257                                       SilcClientConnection conn,
258                                       SilcClientEntry client_entry);
259 void silc_client_replace_from_channels(SilcClient client, 
260                                        SilcClientConnection conn,
261                                        SilcClientEntry old,
262                                        SilcClientEntry new);
263 char *silc_client_chmode(unsigned int mode, SilcChannelEntry channel);
264 char *silc_client_chumode(unsigned int mode);
265 char *silc_client_chumode_char(unsigned int mode);
266 void silc_client_process_failure(SilcClient client,
267                                  SilcSocketConnection sock,
268                                  SilcPacketContext *packet);
269 void silc_client_key_agreement(SilcClient client,
270                                SilcSocketConnection sock,
271                                SilcPacketContext *packet);
272 void silc_client_notify_by_server(SilcClient client,
273                                   SilcSocketConnection sock,
274                                   SilcPacketContext *packet);
275 void silc_client_private_message(SilcClient client, 
276                                  SilcSocketConnection sock, 
277                                  SilcPacketContext *packet);
278 #endif