API change of add_connection.
[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                                                 char *hostname,
227                                                 int port,
228                                                 void *context);
229 int silc_client_connect_to_server(SilcClient client, int port,
230                                   char *host, void *context);
231 int silc_client_start_key_exchange(SilcClient client,
232                                    SilcClientConnection conn,
233                                    int fd);
234 void silc_client_packet_send(SilcClient client, 
235                              SilcSocketConnection sock,
236                              SilcPacketType type, 
237                              void *dst_id,
238                              SilcIdType dst_id_type,
239                              SilcCipher cipher,
240                              SilcHmac hmac,
241                              unsigned char *data, 
242                              unsigned int data_len, 
243                              int force_send);
244 void silc_client_packet_send_to_channel(SilcClient client, 
245                                         SilcSocketConnection sock,
246                                         SilcChannelEntry channel,
247                                         unsigned char *data, 
248                                         unsigned int data_len, 
249                                         int force_send);
250 void silc_client_packet_send_private_message(SilcClient client,
251                                              SilcSocketConnection sock,
252                                              SilcClientEntry client_entry,
253                                              unsigned char *data, 
254                                              unsigned int data_len, 
255                                              int force_send);
256 void silc_client_close_connection(SilcClient client,
257                                   SilcSocketConnection sock);
258 void silc_client_disconnected_by_server(SilcClient client,
259                                         SilcSocketConnection sock,
260                                         SilcBuffer message);
261 void silc_client_error_by_server(SilcClient client,
262                                  SilcSocketConnection sock,
263                                  SilcBuffer message);
264 void silc_client_notify_by_server(SilcClient client,
265                                   SilcSocketConnection sock,
266                                   SilcBuffer message);
267 void silc_client_receive_new_id(SilcClient client,
268                                 SilcSocketConnection sock,
269                                 unsigned char *id_string);
270 void silc_client_new_channel_id(SilcClient client,
271                                 SilcSocketConnection sock,
272                                 char *channel_name,
273                                 unsigned int mode,
274                                 unsigned char *id_string);
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 #endif