removed memset not needed
[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 - 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 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   /* Requested pings. */
114   SilcClientPing *ping;
115   unsigned int ping_count;
116
117   /* Set away message */
118   SilcClientAway *away;
119
120   /* Pointer back to the SilcClient. This object is passed to the application
121      and the actual client object is accesible through this pointer. */
122   SilcClient client;
123
124   /* User data context. Library does not touch this. */
125   void *context;
126 };
127
128 /* Main client structure. */
129 struct SilcClientObject {
130   /*
131    * Public data. All the following pointers must be set by the allocator
132    * of this structure.
133    */
134
135   /* Users's username, hostname and realname. */
136   char *username;
137   char *hostname;
138   char *realname;
139
140   /* Private and public key of the user. */
141   SilcPKCS pkcs;
142   SilcPublicKey public_key;
143   SilcPrivateKey private_key;
144
145   /* Application specific user data pointer. Client library does not
146      touch this. */
147   void *application;
148
149   /*
150    * Private data. Following pointers are used internally by the client
151    * library and should be considered read-only fields.
152    */
153
154   /* All client operations that are implemented in the application. */
155   SilcClientOperations *ops;
156
157   /* SILC client task queues */
158   SilcTaskQueue io_queue;
159   SilcTaskQueue timeout_queue;
160   SilcTaskQueue generic_queue;
161
162   /* Table of connections in client. All the connection data is saved here. */
163   SilcClientConnection *conns;
164   unsigned int conns_count;
165
166   /* Generic cipher and hash objects. These can be used and referenced
167      by the application as well. */
168   SilcCipher none_cipher;
169   SilcHash md5hash;
170   SilcHash sha1hash;
171   SilcHmac md5hmac;
172   SilcHmac sha1hmac;
173
174   /* Random Number Generator. Application should use this as its primary
175      random number generator. */
176   SilcRng rng;
177 };
178
179 /* Macros */
180
181 /* Registers generic task for file descriptor for reading from network and
182    writing to network. As being generic task the actual task is allocated 
183    only once and after that the same task applies to all registered fd's. */
184 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)                      \
185 do {                                                                    \
186   SilcTask tmptask = silc_task_register(client->generic_queue, (fd),    \
187                                         silc_client_packet_process,     \
188                                         context, 0, 0,                  \
189                                         SILC_TASK_GENERIC,              \
190                                         SILC_TASK_PRI_NORMAL);          \
191   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                       \
192 } while(0)
193
194 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd)                \
195 do {                                                            \
196   silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));    \
197 } while(0)                                                      \
198      
199 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd)               \
200 do {                                                            \
201   silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |   \
202                                      (1L << SILC_TASK_WRITE))); \
203 } while(0)
204
205 /* Finds socket connection object by file descriptor */
206 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
207 do {                                                    \
208   int __i;                                              \
209                                                         \
210   for (__i = 0; __i < (__x)->conns_count; __i++)        \
211     if ((__x)->conns[__i]->sock->sock == (__fd))        \
212       break;                                            \
213                                                         \
214   if (__i >= (__x)->conns_count)                        \
215     (__sock) = NULL;                                    \
216  (__sock) = (__x)->conns[__i]->sock;                    \
217 } while(0)
218
219 /* Prototypes */
220
221 SilcClient silc_client_alloc(SilcClientOperations *ops, void *application);
222 void silc_client_free(SilcClient client);
223 int silc_client_init(SilcClient client);
224 void silc_client_stop(SilcClient client);
225 void silc_client_run(SilcClient client);
226 SilcClientConnection silc_client_add_connection(SilcClient client,
227                                                 char *hostname,
228                                                 int port,
229                                                 void *context);
230 int silc_client_connect_to_server(SilcClient client, int port,
231                                   char *host, void *context);
232 int silc_client_start_key_exchange(SilcClient client,
233                                    SilcClientConnection conn,
234                                    int fd);
235 void silc_client_packet_send(SilcClient client, 
236                              SilcSocketConnection sock,
237                              SilcPacketType type, 
238                              void *dst_id,
239                              SilcIdType dst_id_type,
240                              SilcCipher cipher,
241                              SilcHmac hmac,
242                              unsigned char *data, 
243                              unsigned int data_len, 
244                              int force_send);
245 void silc_client_packet_send_to_channel(SilcClient client, 
246                                         SilcSocketConnection sock,
247                                         SilcChannelEntry channel,
248                                         unsigned char *data, 
249                                         unsigned int data_len, 
250                                         int force_send);
251 void silc_client_packet_send_private_message(SilcClient client,
252                                              SilcSocketConnection sock,
253                                              SilcClientEntry client_entry,
254                                              unsigned char *data, 
255                                              unsigned int data_len, 
256                                              int force_send);
257 void silc_client_close_connection(SilcClient client,
258                                   SilcSocketConnection sock);
259 void silc_client_disconnected_by_server(SilcClient client,
260                                         SilcSocketConnection sock,
261                                         SilcBuffer message);
262 void silc_client_error_by_server(SilcClient client,
263                                  SilcSocketConnection sock,
264                                  SilcBuffer message);
265 void silc_client_notify_by_server(SilcClient client,
266                                   SilcSocketConnection sock,
267                                   SilcPacketContext *packet);
268 void silc_client_receive_new_id(SilcClient client,
269                                 SilcSocketConnection sock,
270                                 SilcIDPayload idp);
271 void silc_client_new_channel_id(SilcClient client,
272                                 SilcSocketConnection sock,
273                                 char *channel_name,
274                                 unsigned int mode, SilcIDPayload idp);
275 void silc_client_receive_channel_key(SilcClient client,
276                                      SilcSocketConnection sock,
277                                      SilcBuffer packet);
278 void silc_client_channel_message(SilcClient client, 
279                                  SilcSocketConnection sock, 
280                                  SilcPacketContext *packet);
281 void silc_client_private_message(SilcClient client, 
282                                  SilcSocketConnection sock, 
283                                  SilcPacketContext *packet);
284 void silc_client_remove_from_channels(SilcClient client,
285                                       SilcClientConnection conn,
286                                       SilcClientEntry client_entry);
287 void silc_client_replace_from_channels(SilcClient client, 
288                                        SilcClientConnection conn,
289                                        SilcClientEntry old,
290                                        SilcClientEntry new);
291 #endif