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