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 SERVER_INTERNAL_H
21 #define SERVER_INTERNAL_H
23 #include "server_st_accept.h"
24 #include "server_st_connect.h"
25 #include "server_st_notify.h"
26 #include "server_st_query.h"
27 #include "server_st_command.h"
28 #include "server_st_command_reply.h"
29 #include "server_st_packet.h"
38 SILC_BACKUP_ROUTER = 2
41 /* Forward declarations */
42 typedef struct SilcServerEntryStruct *SilcServerEntry;
43 typedef struct SilcClientEntryStruct *SilcClientEntry;
44 typedef struct SilcChannelEntryStruct *SilcChannelEntry;
45 typedef struct SilcServerCommandStruct *SilcServerCommand;
46 typedef struct SilcServerThreadStruct *SilcServerThread;
48 /* Pending command context */
50 SilcFSMSemaStruct wait_reply; /* Pending command signaller */
51 SilcServerCommand reply; /* Command reply context */
52 SilcUInt16 cmd_ident; /* Command identifier */
53 SilcInt16 refcnt; /* Reference counter */
56 /* Command state context. This is used with both commands and command
57 replies. When command or command reply is executed its state is saved
58 here while processing. */
59 struct SilcServerCommandStruct {
60 struct SilcServerCommandStruct *next;
61 SilcServerThread thread; /* Server thread */
62 SilcPacket packet; /* Command packet */
63 SilcCommandPayload payload; /* Command payload */
64 SilcServerPending pending; /* Pending command context */
67 /* Entry data header. Client and server entries has this as their first
70 SilcConnectionType type; /* Connection type */
71 SilcSKE ske; /* Key exchange protocol, for rekey */
72 SilcHash hash; /* Hash selected in SKE protocol */
73 SilcPublicKey public_key; /* Public key */
74 unsigned char fingerprint[20]; /* SHA-1 fingerprint */
76 long last_receive; /* Time last received data */
77 long last_sent; /* Time last sent data */
79 unsigned long created; /* Time when entry was created */
81 SilcUInt32 refcnt; /* Reference counter */
84 unsigned int registered : 1; /* Set if registered to network */
85 unsigned int local : 1; /* Set if locally connected entry */
86 unsigned int resolving : 1; /* Set if entry data being resolved */
87 unsigned int resolved : 1; /* Set if entry data resolved */
88 unsigned int disabled : 1; /* Set if entry is disabled */
89 unsigned int resumed : 1; /* Set if entry resumed */
90 unsigned int resume_res : 1; /* Set if resolved while resuming */
91 unsigned int noattr : 1; /* Set if entry does not support
92 user attributes in WHOIS */
93 } *SilcEntryData, SilcEntryDataStruct;
96 struct SilcServerEntryStruct {
97 SilcEntryDataStruct data; /* Entry data header */
98 SilcServerID id; /* Server ID */
99 char *server_name; /* Server name */
100 char *server_info; /* Server info */
101 char *motd; /* Message of the day */
102 SilcPacketStream stream; /* Connection to entry/origin of entry */
103 SilcUInt8 server_type; /* Server type */
106 /* Client's joined channel entry */
107 typedef struct SilcChannelClientEntryStruct {
108 SilcClientEntry client; /* Client on channel */
109 SilcChannelEntry channel; /* Joined channel */
110 SilcUInt32 mode; /* Client's mode on channel */
111 } *SilcChannelClientEntry;
114 struct SilcClientEntryStruct {
115 SilcEntryDataStruct data; /* Entry data header */
116 SilcClientID id; /* Client ID */
117 unsigned char *nickname; /* Client's nickname (not normalized) */
118 char *servername; /* Client's server's name */
119 char *username; /* Client's username */
120 char *userinfo; /* Client's user info */
121 SilcUInt32 mode; /* Client's mode in the network */
122 unsigned char *attrs; /* User attributes */
123 SilcUInt16 attrs_len; /* Attributes data length */
124 SilcHashTable channels; /* Joined channels */
125 SilcPacketStream stream; /* Connection to entry/origin of entry */
126 SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */
129 SilcUInt8 fast_command;
130 unsigned long updated;
132 /* we need this so nobody can resume more than once at the same time -
133 * server crashes, really odd behaviour, ... */
134 SilcClientEntry resuming_client;
138 struct SilcChannelEntryStruct {
139 SilcChannelID id; /* Channel ID */
140 char *channel_name; /* Channel name */
141 SilcUInt32 mode; /* Channel's mode */
142 SilcPacketStream router; /* Channel's owner */
144 unsigned char *passphrase; /* Channel's passphrase */
145 SilcHashTable channel_pubkeys; /* Channel authentication public keys */
146 SilcPublicKey founder_key; /* Channel founder's public key */
148 char *topic; /* Current topic */
149 char *cipher; /* User set cipher */
150 char *hmac_name; /* User set HMAC */
151 SilcUInt32 user_limit; /* Maximum user limit */
152 SilcHashTable invite_list; /* Invited list */
153 SilcHashTable ban_list; /* Ban list */
154 SilcHashTable user_list; /* Joined users */
156 SilcCipher channel_key; /* Current channel key */
157 unsigned char *key; /* Current channel key data */
158 SilcUInt32 key_len; /* Channel key data length */
159 SilcHmac hmac; /* Current HMAC */
160 SilcUInt32 refcnt; /* Reference counter */
162 // SilcServerChannelRekey rekey;
163 unsigned long created;
164 unsigned long updated;
167 unsigned int global_users : 1;
168 unsigned int disabled : 1;
169 unsigned int users_resolved : 1;
172 /* Internal context for accepting new connection */
173 typedef struct SilcServerAcceptStruct {
174 SilcEntryDataStruct data;
175 SilcServerThread thread;
176 SilcFSMThreadStruct t; /* Thread for accepting connection */
177 SilcStream stream; /* Remote connection */
178 SilcPacketStream packet_stream; /* Remote connection */
179 SilcConnAuth connauth; /* Connection authentication context */
180 SilcFSMSemaStruct wait_register; /* Signaller when registering received */
181 SilcPacket register_packet; /* NEW_CLIENT/NEW_SERVER packet */
183 SilcServerParamClient cconfig;
184 SilcServerParamServer sconfig;
185 SilcServerParamRouter rconfig;
186 SilcSKEStatus status;
187 SilcSKESecurityProperties prop;
188 SilcSKEKeyMaterial keymat;
189 SilcSKERekeyMaterial rekey;
190 SilcAsyncOperation op;
191 const char *hostname;
196 SilcBool auth_success;
197 SilcConnectionType conn_type;
199 struct SilcServerAcceptStruct *next;
202 /* Server statistics structure. */
204 /* Local stats (server and router) */
205 SilcUInt32 my_clients; /* Locally connected clients */
206 SilcUInt32 my_servers; /* Locally connected servers */
207 SilcUInt32 my_routers; /* Locally connected routers */
208 SilcUInt32 my_channels; /* Locally created channels */
209 SilcUInt32 my_chanclients; /* Local clients on local channels */
210 SilcUInt32 my_aways; /* Local clients away (gone) */
211 SilcUInt32 my_detached; /* Local clients detached */
212 SilcUInt32 my_server_ops; /* Local server operators */
213 SilcUInt32 my_router_ops; /* Local router operators */
215 /* Global stats (mainly for router) */
216 SilcUInt32 cell_clients; /* All clients in cell */
217 SilcUInt32 cell_servers; /* All servers in cell */
218 SilcUInt32 cell_channels; /* All channels in cell */
219 SilcUInt32 cell_chanclients; /* All clients on cell's channels */
220 SilcUInt32 clients; /* All clients */
221 SilcUInt32 servers; /* All servers */
222 SilcUInt32 routers; /* All routers */
223 SilcUInt32 channels; /* All channels */
224 SilcUInt32 chanclients; /* All clients on channels */
225 SilcUInt32 aways; /* All clients away (gone) */
226 SilcUInt32 detached; /* All clients detached */
227 SilcUInt32 server_ops; /* All server operators */
228 SilcUInt32 router_ops; /* All router operators */
230 SilcUInt32 secret_channels;
231 SilcUInt32 private_channels;
235 SilcUInt32 conn_attempts; /* Connection attempts */
236 SilcUInt32 conn_failures; /* Connection failure */
237 SilcUInt32 auth_attempts; /* Authentication attempts */
238 SilcUInt32 auth_failures; /* Authentication failures */
239 SilcUInt32 packets_sent; /* Sent SILC packets */
240 SilcUInt32 packets_received; /* Received SILC packets */
241 SilcUInt32 conn_num; /* Number of connections */
242 SilcUInt32 commands_sent; /* Commands/replies sent */
243 SilcUInt32 commands_received; /* Commands/replies received */
244 } SilcServerStatistics;
246 /* Server thread context */
247 struct SilcServerThreadStruct {
248 struct SilcServerThreadStruct *next;
249 SilcServer server; /* Pointer to server */
250 SilcStack stack; /* Data stack for fast allocations */
251 SilcPacketEngine packet_engine; /* Packet engine */
252 SilcFSMThreadStruct thread; /* FSM thread */
253 SilcFSMStruct fsm; /* Thread's FSM */
254 SilcFSMSemaStruct wait_event; /* Thread's event signaller */
255 SilcUInt32 num_conns; /* Number of connections in the thread */
256 SilcList new_conns; /* New network connections */
257 SilcList packet_queue; /* Incoming packet queue */
260 unsigned int new_connection : 1; /* New connection received */
261 unsigned int new_packet : 1; /* New packet in packet queue */
264 /* Server context. */
265 struct SilcServerStruct {
266 char *server_name; /* Server name */
267 SilcServerEntry server_entry; /* Server entry */
268 SilcServerID id; /* Server ID */
269 SilcUInt32 starttime;
271 SilcFSMStruct fsm; /* Server FSM */
272 SilcSchedule schedule; /* Scheduler */
273 SilcMutex lock; /* Server lock */
274 SilcRng rng; /* Random number generator */
275 SilcServerParams params; /* Server parameters */
276 SilcDList listeners; /* Network listeners */
277 SilcList threads; /* Server worker threads */
278 SilcList new_conns; /* New network connections */
279 SilcList command_pool; /* Command context freelist */
280 SilcHashTable pending_commands; /* Pending commands */
282 SilcFSMSemaStruct wait_event; /* Main state signaller */
283 SilcFSMSemaStruct thread_up; /* Signaller when thread is up */
285 SilcIDCache clients; /* Client entry cache */
286 SilcIDCache servers; /* Server entry cache */
287 SilcIDCache channels; /* Channel entry cache */
289 SilcSKR repository; /* Public key/certificate repository */
290 SilcHashTable watcher_list; /* Watcher list, nickname */
291 SilcHashTable watcher_list_pk; /* Watcher list, public keys */
293 void *app_context; /* Application specific context */
298 unsigned int new_connection : 1; /* New connection received */
299 unsigned int connect_router : 1; /* Connect to configured routers */
300 unsigned int get_statistics : 1; /* Get statistics */
301 unsigned int reconfigure : 1; /* Reconfigure server */
302 unsigned int server_shutdown : 1; /* Shutdown server */
303 unsigned int run_callback : 1; /* Call running callback */
306 unsigned int server_type : 2; /* Server type (server.h) */
307 unsigned int standalone : 1; /* Set if server is standalone, and
308 does not have connection to network. */
309 unsigned int listenning : 1; /* Set if server is listenning for
310 incoming connections. */
311 unsigned int background : 1; /* Set when server is on background */
312 unsigned int backup_router : 1; /* Set if this is backup router */
313 unsigned int backup_primary : 1; /* Set if we've switched our primary
314 router to a backup router. */
315 unsigned int backup_noswitch: 1; /* Set if we've won't switch to
316 become primary (we are backup) */
317 unsigned int backup_closed : 1; /* Set if backup closed connection.
318 Do not allow resuming in this case. */
319 unsigned int wait_backup : 1; /* Set if we are waiting for backup
320 router to connect to us. */
321 unsigned int no_reconnect : 1; /* If set, server won't reconnect to
322 router after disconnection. */
324 SilcPacketStream router; /* Pointer to the primary router */
326 /* Current command identifier, 0 not used */
327 SilcUInt16 cmd_ident;
329 /* Server public key */
330 SilcPublicKey public_key;
331 SilcPrivateKey private_key;
333 /* Hash objects for general hashing */
337 /* Server statistics */
338 SilcServerStatistics stat;
341 /* SIM (SILC Module) list */
345 /* Application callbacks */
346 SilcServerRunning running; /* Called to indicate server is up */
347 SilcServerStop stopped; /* Called to indicate server is down */
348 void *running_context;
352 /* Rekey must be performed at the lastest when this many packets is sent */
353 #define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
357 #define SILC_IS_CLIENT(entry) (entry->data.type == SILC_CONN_CLIENT)
358 #define SILC_IS_SERVER(entry) (entry->data.type == SILC_CONN_SERVER)
359 #define SILC_IS_ROUTER(entry) (entry->data.type == SILC_CONN_ROUTER)
361 /* Return pointer to the primary router connection */
362 #define SILC_PRIMARY_ROUTE(server) server->router
364 /* Return TRUE if a packet must be broadcasted (router broadcasts) */
365 #define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER)
367 /* Return TRUE if entry is locally connected or local to us */
368 #define SILC_IS_LOCAL(entry) (((SilcEntryData)entry)->local)
370 /* Return TRUE if entry is registered */
371 #define SILC_IS_REGISTERED(entry) (((SilcEntryData)entry)->registered)
373 /* Registers generic task for file descriptor for reading from network and
374 writing to network. As being generic task the actual task is allocated
375 only once and after that the same task applies to all registered fd's. */
376 #define SILC_REGISTER_CONNECTION_FOR_IO(fd) \
378 silc_schedule_task_add(server->schedule, (fd), \
379 silc_server_packet_process, \
382 SILC_TASK_PRI_NORMAL); \
385 #define SILC_SET_CONNECTION_FOR_INPUT(s, fd) \
387 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE); \
390 #define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd) \
392 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
396 #define SILC_OPER_STATS_UPDATE(c, type, mod) \
398 if ((c)->mode & (mod)) { \
399 if (SILC_IS_LOCAL((c))) \
400 server->stat.my_ ## type ## _ops--; \
401 if (server->server_type == SILC_ROUTER) \
402 server->stat. type ## _ops--; \
403 (c)->mode &= ~(mod); \
407 #define SILC_UMODE_STATS_UPDATE(oper, mod) \
409 if (client->mode & (mod)) { \
410 if (!(mode & (mod))) { \
411 if (SILC_IS_LOCAL(client)) \
412 server->stat.my_ ## oper ## _ops--; \
413 if (server->server_type == SILC_ROUTER) \
414 server->stat. oper ## _ops--; \
417 if (mode & (mod)) { \
418 if (SILC_IS_LOCAL(client)) \
419 server->stat.my_ ## oper ## _ops++; \
420 if (server->server_type == SILC_ROUTER) \
421 server->stat. oper ## _ops++; \
426 #define SILC_GET_SKE_FLAGS(x, p) \
428 if ((x)->param && (x)->param->key_exchange_pfs) \
429 (p) |= SILC_SKE_SP_FLAG_PFS; \
430 if (!(x)->publickeys) \
431 (p) |= SILC_SKE_SP_FLAG_MUTUAL; \
434 #define SILC_CONNTYPE_STRING(ctype) \
435 (ctype == SILC_CONN_CLIENT ? "Client" : \
436 ctype == SILC_CONN_SERVER ? "Server" : "Router")
438 /* This macro is used to send notify messages with formatted string. The
439 string is formatted with arguments and the formatted string is sent as
441 #define SILC_SERVER_SEND_NOTIFY(server, stream, type, fmt) \
443 char *__fmt__ = silc_format fmt; \
445 silc_server_send_notify(server, stream, FALSE, \
446 type, 1, __fmt__, strlen(__fmt__)); \
447 silc_free(__fmt__); \
450 /* Send notify to operators */
451 #define SILC_SERVER_SEND_OPERS(server, route, local, type, fmt) \
453 char *__fmt__ = silc_format fmt; \
454 silc_server_send_opers_notify(server, route, local, \
455 type, 1, __fmt__, strlen(__fmt__)); \
456 silc_free(__fmt__); \
459 #define SILC_SERVER_LOG_FLUSH_DELAY 300 /* Default log flush delay */
463 /* Check whether rekey protocol is active */
464 #define SILC_SERVER_IS_REKEY(sock) \
465 (sock->protocol && sock->protocol->protocol && \
466 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
468 /* Check whether backup resuming protocol is active */
469 #define SILC_SERVER_IS_BACKUP(sock) \
470 (sock->protocol && sock->protocol->protocol && \
471 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP)
473 /* Output a message to stderr or to the appropriate log facility wether
474 we are in the background or not. */
475 #define SILC_SERVER_LOG_INFO(fmt) \
476 silc_server_stderr(SILC_LOG_INFO, silc_format fmt)
477 #define SILC_SERVER_LOG_WARNING(fmt) \
478 silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
479 #define SILC_SERVER_LOG_ERROR(fmt) \
480 silc_server_stderr(SILC_LOG_ERROR, silc_format fmt)
481 #define SILC_SERVER_LOG_FATAL(fmt) \
482 silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
484 /* Server's states */
485 SILC_FSM_STATE(silc_server_st_run);
486 SILC_FSM_STATE(silc_server_st_new_connection);
487 SILC_FSM_STATE(silc_server_st_wait_new_thread);
488 SILC_FSM_STATE(silc_server_st_stop);
489 SILC_FSM_STATE(silc_server_st_reconfigure);
490 SILC_FSM_STATE(silc_server_st_get_stats);
491 SILC_FSM_STATE(silc_server_st_connect_router);
493 /* Server's thread's states */
494 SILC_FSM_STATE(silc_server_thread_st_start);
495 SILC_FSM_STATE(silc_server_thread_st_run);
498 void silc_server_watcher_list_destroy(void *key, void *context,
501 #include "server_entry.h"
503 #endif /* SERVER_INTERNAL_H */