Initial client library rewrite, connects to remote server already.
[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 - 2006 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 #include "command.h"
24 #include "command_reply.h"
25 #include "client_connect.h"
26 #include "client_register.h"
27 #include "client_entry.h"
28 #include "client_prvmsg.h"
29
30 /* Context to hold the connection authentication request callbacks that
31    will be called when the server has replied back to our request about
32    current authentication method in the session. */
33 typedef struct {
34   SilcConnectionAuthRequest callback;
35   void *context;
36   SilcTask timeout;
37 } *SilcClientConnAuthRequest;
38
39 /* Generic rekey context for connections */
40 typedef struct {
41   /* Current sending encryption key, provided for re-key. The `pfs'
42      is TRUE if the Perfect Forward Secrecy is performed in re-key. */
43   unsigned char *send_enc_key;
44   SilcUInt32 enc_key_len;
45   int ske_group;
46   SilcBool pfs;
47   SilcUInt32 timeout;
48   void *context;
49 } *SilcClientRekey;
50
51 /* Internal context for connection process. This is needed as we
52    doing asynchronous connecting. */
53 typedef struct {
54   SilcClient client;
55   SilcClientConnection conn;
56   SilcTask task;
57   int sock;
58   char *host;
59   int port;
60   void *context;
61 } SilcClientInternalConnectContext;
62
63 /* Structure to hold ping time information. Every PING command will
64    add entry of this structure and is removed after reply to the ping
65    as been received. */
66 struct SilcClientPingStruct {
67   time_t start_time;
68   void *dest_id;
69   char *dest_name;
70 };
71
72 /* Structure to hold away messages set by user. This is mainly created
73    for future extensions where away messages could be set according filters
74    such as nickname and hostname. For now only one away message can
75    be set in one connection. */
76 struct SilcClientAwayStruct {
77   char *away;
78   struct SilcClientAwayStruct *next;
79 };
80
81 /* Command and command reply context used to hold registered commands
82    in the SILC client. */
83 typedef struct SilcClientCommandStruct {
84   struct SilcClientCommandStruct *next;
85   SilcCommand cmd;                    /* Command type */
86   SilcFSMStateCallback command;       /* Command function */
87   SilcFSMStateCallback reply;         /* Command reply callback */
88   char *name;                         /* Name of the command (optional) */
89   SilcUInt8 max_args;                 /* Maximum arguments (optional)  */
90 } *SilcClientCommand;
91
92 /* Command reply callback structure */
93 typedef struct SilcClientCommandReplyCallbackStruct  {
94   struct SilcClientCommandReplyCallbackStruct *next;
95   SilcClientCommandReply reply;       /* Command reply callback */
96   void *context;                      /* Command reply context */
97   unsigned int do_not_call     : 1;   /* Set to not call the callback */
98 } *SilcClientCommandReplyCallback;
99
100 /* Command context given as argument to command state functions.  This same
101    context is used when calling, sending and procesing command and command
102    reply. */
103 typedef struct SilcClientCommandContextStruct {
104   struct SilcClientCommandContextStruct *next;
105   SilcClientConnection conn;          /* Connection */
106   SilcFSMThreadStruct thread;         /* FSM thread for command call */
107
108   SilcCommand cmd;                    /* Command */
109   SilcUInt16 cmd_ident;               /* Command identifier */
110   SilcUInt32 argc;                    /* Number of arguments */
111   unsigned char **argv;               /* Arguments, may be NULL */
112   SilcUInt32 *argv_lens;              /* Argument lengths, may be NULL */
113   SilcUInt32 *argv_types;             /* Argument types, may be NULL */
114
115   SilcList reply_callbacks;           /* Command reply callbacks */
116   SilcStatus status;                  /* Current command reply status */
117   SilcStatus error;                   /* Current command reply error */
118
119   void *context;                      /* Context for free use */
120   unsigned int processed     : 1;     /* Set when reply was processed  */
121   unsigned int called        : 1;     /* Set when called by application */
122   unsigned int verbose       : 1;     /* Verbose with 'say' client operation */
123   unsigned int resolved      : 1;     /* Set when resolving something */
124 } *SilcClientCommandContext;
125
126 /* Internal context for the client->internal pointer in the SilcClient. */
127 struct SilcClientInternalStruct {
128   SilcFSMStruct fsm;                     /* Client's FSM */
129   SilcFSMSemaStruct wait_event;          /* Event signaller */
130   SilcClientOperations *ops;             /* Client operations */
131   SilcClientParams *params;              /* Client parameters */
132   SilcPacketEngine packet_engine;        /* Packet engine */
133   SilcMutex lock;                        /* Client lock */
134
135   /* List of connections in client. All the connection data is saved here. */
136   SilcDList conns;
137
138   /* Registered commands */
139   SilcList commands;
140
141   /* Generic cipher and hash objects. */
142   SilcHmac md5hmac;
143   SilcHmac sha1hmac;
144
145   /* Client version. Used to compare to remote host's version strings. */
146   char *silc_client_version;
147
148   /* Events */
149   unsigned int run_callback    : 1;      /* Call running callback */
150 };
151
152 /* Internal context for conn->internal in SilcClientConnection. */
153 struct SilcClientConnectionInternalStruct {
154   /* Client ID and Channel ID cache. Messages transmitted in SILC network
155      are done using different unique ID's. These are the cache for
156      thoses ID's used in the communication. */
157   SilcIDCache client_cache;
158   SilcIDCache channel_cache;
159   SilcIDCache server_cache;
160
161   /* Pending command queue for this connection */
162   SilcList pending_commands;
163
164   /* Requested pings. */
165   SilcClientPing *ping;
166   SilcUInt32 ping_count;
167
168   /* Set away message */
169   SilcClientAway *away;
170
171   /* Authentication request context. */
172   SilcClientConnAuthRequest connauth;
173
174   /* File transmission sessions */
175   SilcDList ftp_sessions;
176   SilcUInt32 next_session_id;
177   SilcClientFtpSession active_session;
178
179   /* Requested Attributes */
180   SilcHashTable attrs;
181
182   SilcFSMStruct fsm;                     /* Connection FSM */
183   SilcFSMThreadStruct packet_thread;     /* FSM thread for packet processor */
184   SilcFSMThreadStruct event_thread;      /* FSM thread for events */
185   SilcFSMSemaStruct wait_event;          /* Event signaller */
186   SilcMutex lock;                        /* Connection lock */
187   SilcSchedule schedule;                 /* Connection's scheduler */
188   SilcSKE ske;                           /* Key exchange protocol */
189   SilcSKERekeyMaterial rekey;            /* Rekey material */
190   SilcHash hash;                         /* Negotiated hash function */
191   SilcClientConnectionParams params;     /* Connection parameters */
192   SilcAtomic16 cmd_ident;                /* Current command identifier */
193   SilcIDCacheEntry local_entry;          /* Local client cache entry */
194
195   SilcHashTable privmsg_wait;            /* Waited private messages */
196
197   /* Events */
198   unsigned int connect            : 1;   /* Connect remote host */
199   unsigned int disconnected       : 1;   /* Disconnected by remote host */
200   unsigned int key_exchange       : 1;   /* Start key exchange */
201   unsigned int new_packet         : 1;   /* New packet received */
202
203   /* Flags */
204   unsigned int verbose            : 1;   /* Notify application */
205   unsigned int registering        : 1;   /* Set when registering to network */
206 };
207
208 SILC_FSM_STATE(silc_client_connection_st_packet);
209
210 void silc_client_channel_message(SilcClient client,
211                                  SilcClientConnection conn,
212                                  SilcPacket packet);
213 void silc_client_ftp(SilcClient client, SilcClientConnection conn,
214                      SilcPacket packet);
215 void silc_client_channel_key(SilcClient client,
216                              SilcClientConnection conn,
217                              SilcPacket packet);
218 void silc_client_notify(SilcClient client,
219                         SilcClientConnection conn,
220                         SilcPacket packet);
221 void silc_client_disconnect(SilcClient client,
222                             SilcClientConnection conn,
223                             SilcPacket packet);
224 void silc_client_error(SilcClient client,
225                        SilcClientConnection conn,
226                        SilcPacket packet);
227 void silc_client_key_agreement(SilcClient client,
228                                SilcClientConnection conn,
229                                SilcPacket packet);
230 void silc_client_connection_auth_request(SilcClient client,
231                                          SilcClientConnection conn,
232                                          SilcPacket packet);
233 SilcUInt16 silc_client_command_send_argv(SilcClient client,
234                                          SilcClientConnection conn,
235                                          SilcCommand command,
236                                          SilcClientCommandReply reply,
237                                          void *reply_context,
238                                          SilcUInt32 argc,
239                                          unsigned char **argv,
240                                          SilcUInt32 *argv_lens,
241                                          SilcUInt32 *argv_types);
242
243 #if 0
244 /* Session resuming callback */
245 typedef void (*SilcClientResumeSessionCallback)(SilcClient client,
246                                                 SilcClientConnection conn,
247                                                 SilcBool success,
248                                                 void *context);
249
250 /* Rekey must be performed at the lastest when this many packets is sent */
251 #define SILC_CLIENT_REKEY_THRESHOLD 0xfffffe00
252
253 /* Macros */
254
255 /* Registers generic task for file descriptor for reading from network and
256    writing to network. As being generic task the actual task is allocated
257    only once and after that the same task applies to all registered fd's. */
258 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)      \
259 do {                                                    \
260   silc_schedule_task_add(client->schedule, (fd),        \
261                          silc_client_packet_process,    \
262                          context, 0, 0,                 \
263                          SILC_TASK_GENERIC,             \
264                          SILC_TASK_PRI_NORMAL);         \
265 } while(0)
266
267 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)                     \
268 do {                                                                    \
269   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);        \
270 } while(0)
271
272 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)                    \
273 do {                                                                    \
274   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ |              \
275                                           SILC_TASK_WRITE), FALSE);     \
276 } while(0)
277
278 /* Finds socket connection object by file descriptor */
279 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)                 \
280 do {                                                            \
281   int __i;                                                      \
282                                                                 \
283   for (__i = 0; __i < (__x)->internal->conns_count; __i++)      \
284     if ((__x)->internal->conns[__i] &&                          \
285         (__x)->internal->conns[__i]->sock &&                    \
286         (__x)->internal->conns[__i]->sock->sock == (__fd))      \
287       break;                                                    \
288                                                                 \
289   if (__i >= (__x)->internal->conns_count) {                    \
290     (__sock) = NULL;                                            \
291     for (__i = 0; __i < (__x)->internal->sockets_count; __i++)  \
292       if ((__x)->internal->sockets[__i] &&                      \
293           (__x)->internal->sockets[__i]->sock == (__fd))        \
294         (__sock) = (__x)->internal->sockets[__i];               \
295   } else                                                        \
296     (__sock) = (__x)->internal->conns[__i]->sock;               \
297 } while(0)
298
299 /* Check whether rekey protocol is active */
300 #define SILC_CLIENT_IS_REKEY(sock)                                      \
301   (sock->protocol && sock->protocol->protocol &&                        \
302    sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
303
304 /* Prototypes */
305
306 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process);
307 void silc_client_packet_send(SilcClient client,
308                              SilcClientConnection conn,
309                              SilcPacketType type,
310                              void *dst_id,
311                              SilcIdType dst_id_type,
312                              SilcCipher cipher,
313                              SilcHmac hmac,
314                              unsigned char *data,
315                              SilcUInt32 data_len,
316                              SilcBool force_send);
317 int silc_client_packet_send_real(SilcClient client,
318                                  SilcClientConnection conn,
319                                  SilcBool force_send);
320 void silc_client_ftp_free_sessions(SilcClient client,
321                                    SilcClientConnection conn);
322 void silc_client_ftp_session_free(SilcClientFtpSession session);
323 void silc_client_ftp_session_free_client(SilcClientConnection conn,
324                                          SilcClientEntry client_entry);
325 void silc_client_close_connection_real(SilcClient client,
326                                        SilcClientConnection conn,
327                                        SilcClientConnection conn);
328
329 void silc_client_save_channel_key(SilcClient client,
330                                   SilcClientConnection conn,
331                                   SilcBuffer key_payload,
332                                   SilcChannelEntry channel);
333 void silc_client_remove_from_channels(SilcClient client,
334                                       SilcClientConnection conn,
335                                       SilcClientEntry client_entry);
336 void silc_client_replace_from_channels(SilcClient client,
337                                        SilcClientConnection conn,
338                                        SilcClientEntry old,
339                                        SilcClientEntry newclient);
340 void silc_client_process_failure(SilcClient client,
341                                  SilcClientConnection conn,
342                                  SilcPacket packet);
343 SilcBuffer silc_client_get_detach_data(SilcClient client,
344                                        SilcClientConnection conn);
345 SilcBool silc_client_process_detach_data(SilcClient client,
346                                      SilcClientConnection conn,
347                                      unsigned char **old_id,
348                                      SilcUInt16 *old_id_len);
349 void silc_client_resume_session(SilcClient client,
350                                 SilcClientConnection conn,
351                                 SilcClientResumeSessionCallback callback,
352                                 void *context);
353 SilcBuffer silc_client_attributes_process(SilcClient client,
354                                           SilcClientConnection conn,
355                                           SilcDList attrs);
356 void silc_client_packet_queue_purge(SilcClient client,
357                                     SilcClientConnection conn);
358 SILC_TASK_CALLBACK_GLOBAL(silc_client_rekey_callback);
359 void
360 silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
361                                      SilcStatus status,
362                                      SilcBool notify);
363 #endif /* 0 */
364
365 #endif