Merged silc_1_0_branch to trunk.
[silc.git] / lib / silcclient / client_internal.h
1 /*
2
3   client_internal.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2001, 2003 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; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #ifndef CLIENT_INTERNAL_H
21 #define CLIENT_INTERNAL_H
22
23 /* Context to hold the connection authentication request callbacks that
24    will be called when the server has replied back to our request about
25    current authentication method in the session. */
26 typedef struct {
27   SilcConnectionAuthRequest callback;
28   void *context;
29   SilcTask timeout;
30 } *SilcClientConnAuthRequest;
31
32 /* Generic rekey context for connections */
33 typedef struct {
34   /* Current sending encryption key, provided for re-key. The `pfs'
35      is TRUE if the Perfect Forward Secrecy is performed in re-key. */
36   unsigned char *send_enc_key;
37   SilcUInt32 enc_key_len;
38   int ske_group;
39   bool pfs;
40   SilcUInt32 timeout;
41   void *context;
42 } *SilcClientRekey;
43
44 /* Internal context for connection process. This is needed as we
45    doing asynchronous connecting. */
46 typedef struct {
47   SilcClient client;
48   SilcClientConnection conn;
49   SilcTask task;
50   int sock;
51   char *host;
52   int port;
53   int tries;
54   void *context;
55 } SilcClientInternalConnectContext;
56
57 /* Structure to hold ping time information. Every PING command will
58    add entry of this structure and is removed after reply to the ping
59    as been received. */
60 struct SilcClientPingStruct {
61   time_t start_time;
62   void *dest_id;
63   char *dest_name;
64 };
65
66 /* Structure to hold away messages set by user. This is mainly created
67    for future extensions where away messages could be set according filters
68    such as nickname and hostname. For now only one away message can
69    be set in one connection. */
70 struct SilcClientAwayStruct {
71   char *away;
72   struct SilcClientAwayStruct *next;
73 };
74
75 /* Internal context for the client->internal pointer in the SilcClient. */
76 struct SilcClientInternalStruct {
77   /* All client operations that are implemented by the application. */
78   SilcClientOperations *ops;
79
80   /* Client Parameters */
81   SilcClientParams *params;
82
83   /* Table of connections in client. All the connection data is saved here. */
84   SilcClientConnection *conns;
85   SilcUInt32 conns_count;
86
87   /* Table of listenning sockets in client.  Client can have listeners
88      (like key agreement protocol server) and those sockets are saved here.
89      This table is checked always if the connection object cannot be found
90      from the `conns' table. */
91   SilcSocketConnection *sockets;
92   SilcUInt32 sockets_count;
93
94   /* Registered commands */
95   SilcList commands;
96
97   /* Generic cipher and hash objects. */
98   SilcCipher none_cipher;
99   SilcHmac md5hmac;
100   SilcHmac sha1hmac;
101
102   /* Client version. Used to compare to remote host's version strings. */
103   char *silc_client_version;
104 };
105
106 /* Internal context for conn->internal in SilcClientConnection. */
107 struct SilcClientConnectionInternalStruct {
108   /* Keys and stuff negotiated in the SKE protocol */
109   SilcCipher send_key;
110   SilcCipher receive_key;
111   SilcHmac hmac_send;
112   SilcHmac hmac_receive;
113   SilcHash hash;
114   SilcUInt32 psn_send;
115   SilcUInt32 psn_receive;
116
117   /* Client ID and Channel ID cache. Messages transmitted in SILC network
118      are done using different unique ID's. These are the cache for
119      thoses ID's used in the communication. */
120   SilcIDCache client_cache;
121   SilcIDCache channel_cache;
122   SilcIDCache server_cache;
123
124   /* Pending command queue for this connection */
125   SilcDList pending_commands;
126
127   /* Requested pings. */
128   SilcClientPing *ping;
129   SilcUInt32 ping_count;
130
131   /* Set away message */
132   SilcClientAway *away;
133
134   /* Re-key context */
135   SilcClientRekey rekey;
136
137   /* Authentication request context. */
138   SilcClientConnAuthRequest connauth;
139
140   /* File transmission sessions */
141   SilcDList ftp_sessions;
142   SilcUInt32 next_session_id;
143   SilcClientFtpSession active_session;
144
145   /* Requested Attributes */
146   SilcHashTable attrs;
147
148   /* Connection parameters */
149   SilcClientConnectionParams params;
150 };
151
152 /* Session resuming callback */
153 typedef void (*SilcClientResumeSessionCallback)(SilcClient client,
154                                                 SilcClientConnection conn,
155                                                 bool success,
156                                                 void *context);
157
158 /* Rekey must be performed at the lastest when this many packets is sent */
159 #define SILC_CLIENT_REKEY_THRESHOLD 0xfffffe00
160
161 /* Macros */
162
163 /* Registers generic task for file descriptor for reading from network and
164    writing to network. As being generic task the actual task is allocated
165    only once and after that the same task applies to all registered fd's. */
166 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)      \
167 do {                                                    \
168   silc_schedule_task_add(client->schedule, (fd),        \
169                          silc_client_packet_process,    \
170                          context, 0, 0,                 \
171                          SILC_TASK_GENERIC,             \
172                          SILC_TASK_PRI_NORMAL);         \
173 } while(0)
174
175 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)                     \
176 do {                                                                    \
177   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);        \
178 } while(0)
179
180 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)                    \
181 do {                                                                    \
182   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ |              \
183                                           SILC_TASK_WRITE), FALSE);     \
184 } while(0)
185
186 /* Finds socket connection object by file descriptor */
187 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)                 \
188 do {                                                            \
189   int __i;                                                      \
190                                                                 \
191   for (__i = 0; __i < (__x)->internal->conns_count; __i++)      \
192     if ((__x)->internal->conns[__i] &&                          \
193         (__x)->internal->conns[__i]->sock &&                    \
194         (__x)->internal->conns[__i]->sock->sock == (__fd))      \
195       break;                                                    \
196                                                                 \
197   if (__i >= (__x)->internal->conns_count) {                    \
198     (__sock) = NULL;                                            \
199     for (__i = 0; __i < (__x)->internal->sockets_count; __i++)  \
200       if ((__x)->internal->sockets[__i] &&                      \
201           (__x)->internal->sockets[__i]->sock == (__fd))        \
202         (__sock) = (__x)->internal->sockets[__i];               \
203   } else                                                        \
204     (__sock) = (__x)->internal->conns[__i]->sock;               \
205 } while(0)
206
207 /* Check whether rekey protocol is active */
208 #define SILC_CLIENT_IS_REKEY(sock)                                      \
209   (sock->protocol && sock->protocol->protocol &&                        \
210    sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
211
212 /* Prototypes */
213
214 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process);
215 void silc_client_packet_send(SilcClient client,
216                              SilcSocketConnection sock,
217                              SilcPacketType type,
218                              void *dst_id,
219                              SilcIdType dst_id_type,
220                              SilcCipher cipher,
221                              SilcHmac hmac,
222                              unsigned char *data,
223                              SilcUInt32 data_len,
224                              bool force_send);
225 int silc_client_packet_send_real(SilcClient client,
226                                  SilcSocketConnection sock,
227                                  bool force_send);
228 void silc_client_ftp_free_sessions(SilcClient client,
229                                    SilcClientConnection conn);
230 void silc_client_ftp_session_free(SilcClientFtpSession session);
231 void silc_client_ftp_session_free_client(SilcClientConnection conn,
232                                          SilcClientEntry client_entry);
233 void silc_client_close_connection_real(SilcClient client,
234                                        SilcSocketConnection sock,
235                                        SilcClientConnection conn);
236 void silc_client_disconnected_by_server(SilcClient client,
237                                         SilcSocketConnection sock,
238                                         SilcBuffer packet);
239 void silc_client_error_by_server(SilcClient client,
240                                  SilcSocketConnection sock,
241                                  SilcBuffer message);
242 void silc_client_receive_new_id(SilcClient client,
243                                 SilcSocketConnection sock,
244                                 SilcIDPayload idp);
245 void silc_client_save_channel_key(SilcClient client,
246                                   SilcClientConnection conn,
247                                   SilcBuffer key_payload,
248                                   SilcChannelEntry channel);
249 void silc_client_receive_channel_key(SilcClient client,
250                                      SilcSocketConnection sock,
251                                      SilcBuffer packet);
252 void silc_client_channel_message(SilcClient client,
253                                  SilcSocketConnection sock,
254                                  SilcPacketContext *packet);
255 void silc_client_remove_from_channels(SilcClient client,
256                                       SilcClientConnection conn,
257                                       SilcClientEntry client_entry);
258 void silc_client_replace_from_channels(SilcClient client,
259                                        SilcClientConnection conn,
260                                        SilcClientEntry old,
261                                        SilcClientEntry newclient);
262 void silc_client_process_failure(SilcClient client,
263                                  SilcSocketConnection sock,
264                                  SilcPacketContext *packet);
265 void silc_client_key_agreement(SilcClient client,
266                                SilcSocketConnection sock,
267                                SilcPacketContext *packet);
268 void silc_client_notify_by_server(SilcClient client,
269                                   SilcSocketConnection sock,
270                                   SilcPacketContext *packet);
271 void silc_client_private_message(SilcClient client,
272                                  SilcSocketConnection sock,
273                                  SilcPacketContext *packet);
274 void silc_client_connection_auth_request(SilcClient client,
275                                          SilcSocketConnection sock,
276                                          SilcPacketContext *packet);
277 void silc_client_ftp(SilcClient client,
278                      SilcSocketConnection sock,
279                      SilcPacketContext *packet);
280 SilcBuffer silc_client_get_detach_data(SilcClient client,
281                                        SilcClientConnection conn);
282 bool silc_client_process_detach_data(SilcClient client,
283                                      SilcClientConnection conn,
284                                      unsigned char **old_id,
285                                      SilcUInt16 *old_id_len);
286 void silc_client_resume_session(SilcClient client,
287                                 SilcClientConnection conn,
288                                 SilcClientResumeSessionCallback callback,
289                                 void *context);
290 SilcBuffer silc_client_attributes_process(SilcClient client,
291                                           SilcSocketConnection sock,
292                                           SilcDList attrs);
293 void silc_client_packet_queue_purge(SilcClient client,
294                                     SilcSocketConnection sock);
295 SILC_TASK_CALLBACK_GLOBAL(silc_client_rekey_callback);
296
297 #endif