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