5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2005 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 */
128 SilcUInt8 fast_command;
129 unsigned long updated;
131 /* data.status is RESOLVING and this includes the resolving command
133 SilcUInt16 resolve_cmd_ident;
135 /* we need this so nobody can resume more than once at the same time -
136 * server crashes, really odd behaviour, ... */
137 SilcClientEntry resuming_client;
141 struct SilcChannelEntryStruct {
142 SilcChannelID id; /* Channel ID */
143 char *channel_name; /* Channel name */
144 SilcUInt32 mode; /* Channel's mode */
145 SilcPacketStream router; /* Channel's owner */
147 unsigned char *passphrase; /* Channel's passphrase */
148 SilcHashTable channel_pubkeys; /* Channel authentication public keys */
149 SilcPublicKey founder_key; /* Channel founder's public key */
151 char *topic; /* Current topic */
152 char *cipher; /* User set cipher */
153 char *hmac_name; /* User set HMAC */
154 SilcUInt32 user_limit; /* Maximum user limit */
155 SilcHashTable invite_list; /* Invited list */
156 SilcHashTable ban_list; /* Ban list */
157 SilcHashTable user_list; /* Joined users */
159 SilcCipher channel_key; /* Current channel key */
160 unsigned char *key; /* Current channel key data */
161 SilcUInt32 key_len; /* Channel key data length */
162 SilcHmac hmac; /* Current HMAC */
163 SilcUInt32 refcnt; /* Reference counter */
165 // SilcServerChannelRekey rekey;
166 unsigned long created;
167 unsigned long updated;
170 unsigned int global_users : 1;
171 unsigned int disabled : 1;
172 unsigned int users_resolved : 1;
175 /* Internal context for accepting new connection */
176 typedef struct SilcServerAcceptStruct {
177 SilcEntryDataStruct data;
178 SilcServerThread thread;
179 SilcFSMThread t; /* Thread for accepting connection */
180 SilcStream stream; /* Remote connection */
181 SilcPacketStream packet_stream; /* Remote connection */
182 SilcConnAuth connauth; /* Connection authentication context */
183 SilcFSMSemaStruct wait_register; /* Signaller when registering received */
184 SilcPacket register_packet; /* NEW_CLIENT/NEW_SERVER packet */
186 SilcServerParamClient cconfig;
187 SilcServerParamServer sconfig;
188 SilcServerParamRouter rconfig;
189 SilcSKEStatus status;
190 SilcSKESecurityProperties prop;
191 SilcSKEKeyMaterial keymat;
192 SilcSKERekeyMaterial rekey;
193 SilcAsyncOperation op;
194 const char *hostname;
199 SilcBool auth_success;
200 SilcConnectionType conn_type;
202 struct SilcServerAcceptStruct *next;
205 /* Server statistics structure. */
207 /* Local stats (server and router) */
208 SilcUInt32 my_clients; /* Locally connected clients */
209 SilcUInt32 my_servers; /* Locally connected servers */
210 SilcUInt32 my_routers; /* Locally connected routers */
211 SilcUInt32 my_channels; /* Locally created channels */
212 SilcUInt32 my_chanclients; /* Local clients on local channels */
213 SilcUInt32 my_aways; /* Local clients away (gone) */
214 SilcUInt32 my_detached; /* Local clients detached */
215 SilcUInt32 my_server_ops; /* Local server operators */
216 SilcUInt32 my_router_ops; /* Local router operators */
218 /* Global stats (mainly for router) */
219 SilcUInt32 cell_clients; /* All clients in cell */
220 SilcUInt32 cell_servers; /* All servers in cell */
221 SilcUInt32 cell_channels; /* All channels in cell */
222 SilcUInt32 cell_chanclients; /* All clients on cell's channels */
223 SilcUInt32 clients; /* All clients */
224 SilcUInt32 servers; /* All servers */
225 SilcUInt32 routers; /* All routers */
226 SilcUInt32 channels; /* All channels */
227 SilcUInt32 chanclients; /* All clients on channels */
228 SilcUInt32 aways; /* All clients away (gone) */
229 SilcUInt32 detached; /* All clients detached */
230 SilcUInt32 server_ops; /* All server operators */
231 SilcUInt32 router_ops; /* All router operators */
233 SilcUInt32 secret_channels;
234 SilcUInt32 private_channels;
238 SilcUInt32 conn_attempts; /* Connection attempts */
239 SilcUInt32 conn_failures; /* Connection failure */
240 SilcUInt32 auth_attempts; /* Authentication attempts */
241 SilcUInt32 auth_failures; /* Authentication failures */
242 SilcUInt32 packets_sent; /* Sent SILC packets */
243 SilcUInt32 packets_received; /* Received SILC packets */
244 SilcUInt32 conn_num; /* Number of connections */
245 SilcUInt32 commands_sent; /* Commands/replies sent */
246 SilcUInt32 commands_received; /* Commands/replies received */
247 } SilcServerStatistics;
249 /* Server thread context */
250 struct SilcServerThreadStruct {
251 struct SilcServerThreadStruct *next;
252 SilcServer server; /* Pointer to server */
253 SilcStack stack; /* Data stack for fast allocations */
254 SilcPacketEngine packet_engine; /* Packet engine */
255 SilcFSMThreadStruct thread; /* FSM thread */
256 SilcFSMStruct fsm; /* Thread's FSM */
257 SilcFSMSemaStruct wait_event; /* Thread's event signaller */
258 SilcUInt32 num_conns; /* Number of connections in the thread */
259 SilcList new_conns; /* New network connections */
260 SilcList packet_queue; /* Incoming packet queue */
263 unsigned int new_connection : 1; /* New connection received */
264 unsigned int new_packet : 1; /* New packet in packet queue */
267 /* Server context. */
268 struct SilcServerStruct {
269 char *server_name; /* Server name */
270 SilcServerEntry server_entry; /* Server entry */
271 SilcServerID id; /* Server ID */
272 SilcUInt32 starttime;
274 SilcFSMStruct fsm; /* Server FSM */
275 SilcSchedule schedule; /* Scheduler */
276 SilcMutex lock; /* Server lock */
277 SilcRng rng; /* Random number generator */
278 SilcServerParams params; /* Server parameters */
279 SilcDList listeners; /* Network listeners */
280 SilcList threads; /* Server worker threads */
281 SilcList new_conns; /* New network connections */
282 SilcList command_pool; /* Command context freelist */
283 SilcHashTable pending_commands; /* Pending commands */
285 SilcFSMSemaStruct wait_event; /* Main state signaller */
286 SilcFSMSemaStruct thread_up; /* Signaller when thread is up */
288 SilcIDCache clients; /* Client entry cache */
289 SilcIDCache servers; /* Server entry cache */
290 SilcIDCache channels; /* Channel entry cache */
292 SilcSKR repository; /* Public key/certificate repository */
293 SilcHashTable watcher_list; /* Watcher list, nickname */
294 SilcHashTable watcher_list_pk; /* Watcher list, public keys */
296 void *app_context; /* Application specific context */
301 unsigned int new_connection : 1; /* New connection received */
302 unsigned int connect_router : 1; /* Connect to configured routers */
303 unsigned int get_statistics : 1; /* Get statistics */
304 unsigned int reconfigure : 1; /* Reconfigure server */
305 unsigned int server_shutdown : 1; /* Shutdown server */
306 unsigned int run_callback : 1; /* Call running callback */
309 unsigned int server_type : 2; /* Server type (server.h) */
310 unsigned int standalone : 1; /* Set if server is standalone, and
311 does not have connection to network. */
312 unsigned int listenning : 1; /* Set if server is listenning for
313 incoming connections. */
314 unsigned int background : 1; /* Set when server is on background */
315 unsigned int backup_router : 1; /* Set if this is backup router */
316 unsigned int backup_primary : 1; /* Set if we've switched our primary
317 router to a backup router. */
318 unsigned int backup_noswitch: 1; /* Set if we've won't switch to
319 become primary (we are backup) */
320 unsigned int backup_closed : 1; /* Set if backup closed connection.
321 Do not allow resuming in this case. */
322 unsigned int wait_backup : 1; /* Set if we are waiting for backup
323 router to connect to us. */
324 unsigned int no_reconnect : 1; /* If set, server won't reconnect to
325 router after disconnection. */
327 SilcPacketStream router; /* Pointer to the primary router */
329 /* Current command identifier, 0 not used */
330 SilcUInt16 cmd_ident;
332 /* Server public key */
334 SilcPublicKey public_key;
335 SilcPrivateKey private_key;
337 /* Hash objects for general hashing */
341 /* Server statistics */
342 SilcServerStatistics stat;
345 /* SIM (SILC Module) list */
349 /* Application callbacks */
350 SilcServerRunning running; /* Called to indicate server is up */
351 SilcServerStop stopped; /* Called to indicate server is down */
352 void *running_context;
356 /* Rekey must be performed at the lastest when this many packets is sent */
357 #define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
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) \
369 (((SilcIDListData)entry)->status & SILC_IDLIST_STATUS_LOCAL)
371 /* Registers generic task for file descriptor for reading from network and
372 writing to network. As being generic task the actual task is allocated
373 only once and after that the same task applies to all registered fd's. */
374 #define SILC_REGISTER_CONNECTION_FOR_IO(fd) \
376 silc_schedule_task_add(server->schedule, (fd), \
377 silc_server_packet_process, \
380 SILC_TASK_PRI_NORMAL); \
383 #define SILC_SET_CONNECTION_FOR_INPUT(s, fd) \
385 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE); \
388 #define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd) \
390 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
394 #define SILC_OPER_STATS_UPDATE(c, type, mod) \
396 if ((c)->mode & (mod)) { \
397 if (SILC_IS_LOCAL((c))) \
398 server->stat.my_ ## type ## _ops--; \
399 if (server->server_type == SILC_ROUTER) \
400 server->stat. type ## _ops--; \
401 (c)->mode &= ~(mod); \
405 #define SILC_UMODE_STATS_UPDATE(oper, mod) \
407 if (client->mode & (mod)) { \
408 if (!(mode & (mod))) { \
409 if (SILC_IS_LOCAL(client)) \
410 server->stat.my_ ## oper ## _ops--; \
411 if (server->server_type == SILC_ROUTER) \
412 server->stat. oper ## _ops--; \
415 if (mode & (mod)) { \
416 if (SILC_IS_LOCAL(client)) \
417 server->stat.my_ ## oper ## _ops++; \
418 if (server->server_type == SILC_ROUTER) \
419 server->stat. oper ## _ops++; \
424 #define SILC_GET_SKE_FLAGS(x, p) \
426 if ((x)->param && (x)->param->key_exchange_pfs) \
427 (p) |= SILC_SKE_SP_FLAG_PFS; \
428 if (!(x)->publickeys) \
429 (p) |= SILC_SKE_SP_FLAG_MUTUAL; \
432 #define SILC_CONNTYPE_STRING(ctype) \
433 (ctype == SILC_CONN_CLIENT ? "Client" : \
434 ctype == SILC_CONN_SERVER ? "Server" : "Router")
436 /* This macro is used to send notify messages with formatted string. The
437 string is formatted with arguments and the formatted string is sent as
439 #define SILC_SERVER_SEND_NOTIFY(server, stream, type, fmt) \
441 char *__fmt__ = silc_format fmt; \
443 silc_server_send_notify(server, stream, FALSE, \
444 type, 1, __fmt__, strlen(__fmt__)); \
445 silc_free(__fmt__); \
448 /* Send notify to operators */
449 #define SILC_SERVER_SEND_OPERS(server, route, local, type, fmt) \
451 char *__fmt__ = silc_format fmt; \
452 silc_server_send_opers_notify(server, route, local, \
453 type, 1, __fmt__, strlen(__fmt__)); \
454 silc_free(__fmt__); \
457 /* Connection retry timeout. We implement exponential backoff algorithm
458 in connection retry. The interval of timeout grows when retry count
460 #define SILC_SERVER_RETRY_COUNT 7 /* Max retry count */
461 #define SILC_SERVER_RETRY_MULTIPLIER 2 /* Interval growth */
462 #define SILC_SERVER_RETRY_RANDOMIZER 2 /* timeout += rnd % 2 */
463 #define SILC_SERVER_RETRY_INTERVAL_MIN 10 /* Min retry timeout */
464 #define SILC_SERVER_RETRY_INTERVAL_MAX 600 /* Max generated timeout */
466 #define SILC_SERVER_KEEPALIVE 300 /* Heartbeat interval */
467 #define SILC_SERVER_REKEY 3600 /* Session rekey interval */
468 #define SILC_SERVER_MAX_CONNECTIONS 1000 /* Max connections */
469 #define SILC_SERVER_MAX_CONNECTIONS_SINGLE 1000 /* Max connections per host */
470 #define SILC_SERVER_LOG_FLUSH_DELAY 300 /* Default log flush delay */
474 /* Check whether rekey protocol is active */
475 #define SILC_SERVER_IS_REKEY(sock) \
476 (sock->protocol && sock->protocol->protocol && \
477 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
479 /* Check whether backup resuming protocol is active */
480 #define SILC_SERVER_IS_BACKUP(sock) \
481 (sock->protocol && sock->protocol->protocol && \
482 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP)
484 /* Output a message to stderr or to the appropriate log facility wether
485 we are in the background or not. */
486 #define SILC_SERVER_LOG_INFO(fmt) \
487 silc_server_stderr(SILC_LOG_INFO, silc_format fmt)
488 #define SILC_SERVER_LOG_WARNING(fmt) \
489 silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
490 #define SILC_SERVER_LOG_ERROR(fmt) \
491 silc_server_stderr(SILC_LOG_ERROR, silc_format fmt)
492 #define SILC_SERVER_LOG_FATAL(fmt) \
493 silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
495 /* Server's states */
496 SILC_FSM_STATE(silc_server_st_run);
497 SILC_FSM_STATE(silc_server_st_new_connection);
498 SILC_FSM_STATE(silc_server_st_wait_new_thread);
499 SILC_FSM_STATE(silc_server_st_stop);
500 SILC_FSM_STATE(silc_server_st_reconfigure);
501 SILC_FSM_STATE(silc_server_st_get_stats);
502 SILC_FSM_STATE(silc_server_st_connect_router);
504 /* Server's thread's states */
505 SILC_FSM_STATE(silc_server_thread_st_start);
506 SILC_FSM_STATE(silc_server_thread_st_run);
509 void silc_server_watcher_list_destroy(void *key, void *context,
512 #include "server_entry.h"
514 #endif /* SERVER_INTERNAL_H */