5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2006 Pekka Riikonen
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.
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.
20 #ifndef CLIENT_INTERNAL_H
21 #define CLIENT_INTERNAL_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"
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. */
34 SilcConnectionAuthRequest callback;
37 } *SilcClientConnAuthRequest;
39 /* Generic rekey context for connections */
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;
51 /* Internal context for connection process. This is needed as we
52 doing asynchronous connecting. */
55 SilcClientConnection conn;
61 } SilcClientInternalConnectContext;
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
66 struct SilcClientPingStruct {
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 {
78 struct SilcClientAwayStruct *next;
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) */
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;
100 /* Command context given as argument to command state functions. This same
101 context is used when calling, sending and procesing command and command
103 typedef struct SilcClientCommandContextStruct {
104 struct SilcClientCommandContextStruct *next;
105 SilcClientConnection conn; /* Connection */
106 SilcFSMThreadStruct thread; /* FSM thread for command call */
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 */
115 SilcList reply_callbacks; /* Command reply callbacks */
116 SilcStatus status; /* Current command reply status */
117 SilcStatus error; /* Current command reply error */
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;
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 */
135 /* List of connections in client. All the connection data is saved here. */
138 /* Registered commands */
141 /* Generic cipher and hash objects. */
145 /* Client version. Used to compare to remote host's version strings. */
146 char *silc_client_version;
149 unsigned int run_callback : 1; /* Call running callback */
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;
161 /* Pending command queue for this connection */
162 SilcList pending_commands;
164 /* Requested pings. */
165 SilcClientPing *ping;
166 SilcUInt32 ping_count;
168 /* Set away message */
169 SilcClientAway *away;
171 /* Authentication request context. */
172 SilcClientConnAuthRequest connauth;
174 /* File transmission sessions */
175 SilcDList ftp_sessions;
176 SilcUInt32 next_session_id;
177 SilcClientFtpSession active_session;
179 /* Requested Attributes */
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 */
195 SilcHashTable privmsg_wait; /* Waited private messages */
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 */
204 unsigned int verbose : 1; /* Notify application */
205 unsigned int registering : 1; /* Set when registering to network */
208 SILC_FSM_STATE(silc_client_connection_st_packet);
210 void silc_client_channel_message(SilcClient client,
211 SilcClientConnection conn,
213 void silc_client_ftp(SilcClient client, SilcClientConnection conn,
215 void silc_client_channel_key(SilcClient client,
216 SilcClientConnection conn,
218 void silc_client_notify(SilcClient client,
219 SilcClientConnection conn,
221 void silc_client_disconnect(SilcClient client,
222 SilcClientConnection conn,
224 void silc_client_error(SilcClient client,
225 SilcClientConnection conn,
227 void silc_client_key_agreement(SilcClient client,
228 SilcClientConnection conn,
230 void silc_client_connection_auth_request(SilcClient client,
231 SilcClientConnection conn,
233 SilcUInt16 silc_client_command_send_argv(SilcClient client,
234 SilcClientConnection conn,
236 SilcClientCommandReply reply,
239 unsigned char **argv,
240 SilcUInt32 *argv_lens,
241 SilcUInt32 *argv_types);
244 /* Session resuming callback */
245 typedef void (*SilcClientResumeSessionCallback)(SilcClient client,
246 SilcClientConnection conn,
250 /* Rekey must be performed at the lastest when this many packets is sent */
251 #define SILC_CLIENT_REKEY_THRESHOLD 0xfffffe00
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) \
260 silc_schedule_task_add(client->schedule, (fd), \
261 silc_client_packet_process, \
264 SILC_TASK_PRI_NORMAL); \
267 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd) \
269 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE); \
272 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd) \
274 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | \
275 SILC_TASK_WRITE), FALSE); \
278 /* Finds socket connection object by file descriptor */
279 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
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)) \
289 if (__i >= (__x)->internal->conns_count) { \
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]; \
296 (__sock) = (__x)->internal->conns[__i]->sock; \
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)
306 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process);
307 void silc_client_packet_send(SilcClient client,
308 SilcClientConnection conn,
311 SilcIdType dst_id_type,
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);
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,
339 SilcClientEntry newclient);
340 void silc_client_process_failure(SilcClient client,
341 SilcClientConnection conn,
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,
353 SilcBuffer silc_client_attributes_process(SilcClient client,
354 SilcClientConnection conn,
356 void silc_client_packet_queue_purge(SilcClient client,
357 SilcClientConnection conn);
358 SILC_TASK_CALLBACK_GLOBAL(silc_client_rekey_callback);
360 silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,