5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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; either version 2 of the License, or
12 (at your option) any later version.
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.
24 /* Forward declarations */
25 typedef struct SilcClientStruct *SilcClient;
26 typedef struct SilcClientConnectionStruct *SilcClientConnection;
27 typedef struct SilcClientPingStruct SilcClientPing;
28 typedef struct SilcClientAwayStruct SilcClientAway;
29 typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
35 /* Connection structure used in client to associate all the important
36 connection specific data to this structure. */
37 struct SilcClientConnectionStruct {
43 /* Local client ID for this connection */
44 SilcClientID *local_id;
46 /* Decoded local ID so that the above defined ID would not have
47 to be decoded for every packet. */
48 unsigned char *local_id_data;
49 unsigned int local_id_data_len;
51 /* Own client entry. */
52 SilcClientEntry local_entry;
62 /* Remote server ID for this connection */
63 SilcServerID *remote_id;
65 /* Decoded remote ID so that the above defined ID would not have
66 to be decoded for every packet. */
67 unsigned char *remote_id_data;
68 unsigned int remote_id_data_len;
75 SilcCipher receive_key;
77 unsigned char *hmac_key;
78 unsigned int hmac_key_len;
80 /* Client ID and Channel ID cache. Messages transmitted in SILC network
81 are done using different unique ID's. These are the cache for
82 thoses ID's used in the communication. */
83 SilcIDCache client_cache;
84 SilcIDCache channel_cache;
85 SilcIDCache server_cache;
87 /* Current channel on window. All channels are saved (allocated) into
89 SilcChannelEntry current_channel;
91 /* Socket connection object for this connection (window). This
92 object will have a back-pointer to this window object for fast
93 referencing (sock->user_data). */
94 SilcSocketConnection sock;
96 /* Pending command queue for this connection */
97 SilcDList pending_commands;
99 /* Current command identifier, 0 not used */
100 unsigned short cmd_ident;
102 /* Requested pings. */
103 SilcClientPing *ping;
104 unsigned int ping_count;
106 /* Set away message */
107 SilcClientAway *away;
109 /* Pointer back to the SilcClient. This object is passed to the application
110 and the actual client object is accesible through this pointer. */
113 /* User data context. Library does not touch this. */
117 /* Main client structure. */
118 struct SilcClientStruct {
120 * Public data. All the following pointers must be set by the allocator
124 /* Users's username, hostname and realname. */
129 /* Private and public key of the user. */
131 SilcPublicKey public_key;
132 SilcPrivateKey private_key;
134 /* Application specific user data pointer. Client library does not
139 * Private data. Following pointers are used internally by the client
140 * library and should be considered read-only fields.
143 /* All client operations that are implemented in the application. */
144 SilcClientOperations *ops;
146 /* SILC client task queues */
147 SilcTaskQueue io_queue;
148 SilcTaskQueue timeout_queue;
149 SilcTaskQueue generic_queue;
151 /* Table of connections in client. All the connection data is saved here. */
152 SilcClientConnection *conns;
153 unsigned int conns_count;
155 /* Table of listenning sockets in client. Client can have listeners
156 (like key agreement protocol server) and those sockets are saved here.
157 This table is checked always if the connection object cannot be found
158 from the `conns' table. */
159 SilcSocketConnection *sockets;
160 unsigned int sockets_count;
162 /* Generic cipher and hash objects. These can be used and referenced
163 by the application as well. */
164 SilcCipher none_cipher;
170 /* Random Number Generator. Application should use this as its primary
171 random number generator. */
177 /* Registers generic task for file descriptor for reading from network and
178 writing to network. As being generic task the actual task is allocated
179 only once and after that the same task applies to all registered fd's. */
180 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \
182 SilcTask tmptask = silc_task_register(client->generic_queue, (fd), \
183 silc_client_packet_process, \
186 SILC_TASK_PRI_NORMAL); \
187 silc_task_set_iotype(tmptask, SILC_TASK_WRITE); \
190 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd) \
192 silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ)); \
195 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd) \
197 silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) | \
198 (1L << SILC_TASK_WRITE))); \
201 /* Finds socket connection object by file descriptor */
202 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
206 for (__i = 0; __i < (__x)->conns_count; __i++) \
207 if ((__x)->conns[__i] && \
208 (__x)->conns[__i]->sock->sock == (__fd)) \
211 if (__i >= (__x)->conns_count) { \
213 for (__i = 0; __i < (__x)->sockets_count; __i++) \
214 if ((__x)->sockets[__i] && \
215 (__x)->sockets[__i]->sock == (__fd)) \
216 (__sock) = (__x)->sockets[__i]; \
218 (__sock) = (__x)->conns[__i]->sock; \
221 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
223 void silc_client_packet_send(SilcClient client,
224 SilcSocketConnection sock,
227 SilcIdType dst_id_type,
231 unsigned int data_len,
233 void silc_client_disconnected_by_server(SilcClient client,
234 SilcSocketConnection sock,
236 void silc_client_error_by_server(SilcClient client,
237 SilcSocketConnection sock,
239 void silc_client_receive_new_id(SilcClient client,
240 SilcSocketConnection sock,
242 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
243 SilcSocketConnection sock,
247 void silc_client_save_channel_key(SilcClientConnection conn,
248 SilcBuffer key_payload,
249 SilcChannelEntry channel);
250 void silc_client_receive_channel_key(SilcClient client,
251 SilcSocketConnection sock,
253 void silc_client_channel_message(SilcClient client,
254 SilcSocketConnection sock,
255 SilcPacketContext *packet);
256 void silc_client_remove_from_channels(SilcClient client,
257 SilcClientConnection conn,
258 SilcClientEntry client_entry);
259 void silc_client_replace_from_channels(SilcClient client,
260 SilcClientConnection conn,
262 SilcClientEntry new);
263 char *silc_client_chmode(unsigned int mode, SilcChannelEntry channel);
264 char *silc_client_chumode(unsigned int mode);
265 char *silc_client_chumode_char(unsigned int mode);
266 void silc_client_process_failure(SilcClient client,
267 SilcSocketConnection sock,
268 SilcPacketContext *packet);
269 void silc_client_key_agreement(SilcClient client,
270 SilcSocketConnection sock,
271 SilcPacketContext *packet);
272 void silc_client_notify_by_server(SilcClient client,
273 SilcSocketConnection sock,
274 SilcPacketContext *packet);
275 void silc_client_private_message(SilcClient client,
276 SilcSocketConnection sock,
277 SilcPacketContext *packet);