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 "silcapi.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 (some of the prototypes are defined in the silcapi.h) */
226
227 void silc_client_packet_send(SilcClient client, 
228                              SilcSocketConnection sock,
229                              SilcPacketType type, 
230                              void *dst_id,
231                              SilcIdType dst_id_type,
232                              SilcCipher cipher,
233                              SilcHmac hmac,
234                              unsigned char *data, 
235                              unsigned int data_len, 
236                              int force_send);
237 void silc_client_disconnected_by_server(SilcClient client,
238                                         SilcSocketConnection sock,
239                                         SilcBuffer message);
240 void silc_client_error_by_server(SilcClient client,
241                                  SilcSocketConnection sock,
242                                  SilcBuffer message);
243 void silc_client_notify_by_server(SilcClient client,
244                                   SilcSocketConnection sock,
245                                   SilcPacketContext *packet);
246 void silc_client_receive_new_id(SilcClient client,
247                                 SilcSocketConnection sock,
248                                 SilcIDPayload idp);
249 void silc_client_new_channel_id(SilcClient client,
250                                 SilcSocketConnection sock,
251                                 char *channel_name,
252                                 unsigned int mode, SilcIDPayload idp);
253 void silc_client_save_channel_key(SilcClientConnection conn,
254                                   SilcBuffer key_payload, 
255                                   SilcChannelEntry channel);
256 void silc_client_receive_channel_key(SilcClient client,
257                                      SilcSocketConnection sock,
258                                      SilcBuffer packet);
259 void silc_client_channel_message(SilcClient client, 
260                                  SilcSocketConnection sock, 
261                                  SilcPacketContext *packet);
262 void silc_client_private_message(SilcClient client, 
263                                  SilcSocketConnection sock, 
264                                  SilcPacketContext *packet);
265 void silc_client_remove_from_channels(SilcClient client,
266                                       SilcClientConnection conn,
267                                       SilcClientEntry client_entry);
268 void silc_client_replace_from_channels(SilcClient client, 
269                                        SilcClientConnection conn,
270                                        SilcClientEntry old,
271                                        SilcClientEntry new);
272 char *silc_client_chmode(unsigned int mode);
273 char *silc_client_chumode(unsigned int mode);
274 char *silc_client_chumode_char(unsigned int mode);
275
276 #endif