Added.
[silc.git] / lib / silcserver / server_internal.h
1 /*
2
3   server_internal.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2005 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 SERVER_INTERNAL_H
21 #define SERVER_INTERNAL_H
22
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"
30
31 /* SILC port */
32 #define SILC_PORT 706
33
34 /* Server type */
35 typedef enum {
36   SILC_SERVER         = 0,
37   SILC_ROUTER         = 1,
38   SILC_BACKUP_ROUTER  = 2
39 } SilcServerType;
40
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;
47
48 /* Pending command context */
49 typedef struct {
50   SilcFSMSemaStruct wait_reply;         /* Pending command signaller */
51   SilcServerCommand reply;              /* Command reply context */
52   SilcUInt16 cmd_ident;                 /* Command identifier */
53   SilcInt16 refcnt;                     /* Reference counter */
54 } *SilcServerPending;
55
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 */
65 };
66
67 /* Entry data header.  Client and server entries has this as their first
68    field. */
69 typedef struct {
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 */
75
76   long last_receive;                 /* Time last received data */
77   long last_sent;                    /* Time last sent data */
78
79   unsigned long created;             /* Time when entry was created */
80
81   SilcUInt32 refcnt;                 /* Reference counter */
82
83   /* Flags */
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;
94
95 /* Server entry */
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 */
104 };
105
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;
112
113 /* Client entry */
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
127   long last_command;
128   SilcUInt8 fast_command;
129   unsigned long updated;
130
131   /* data.status is RESOLVING and this includes the resolving command
132      reply identifier. */
133   SilcUInt16 resolve_cmd_ident;
134
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;
138 };
139
140 /* Channel entry */
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 */
146
147   unsigned char *passphrase;         /* Channel's passphrase */
148   SilcHashTable channel_pubkeys;     /* Channel authentication public keys */
149   SilcPublicKey founder_key;         /* Channel founder's public key */
150
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 */
158
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 */
164
165   //  SilcServerChannelRekey rekey;
166   unsigned long created;
167   unsigned long updated;
168
169   /* Flags */
170   unsigned int global_users : 1;
171   unsigned int disabled : 1;
172   unsigned int users_resolved : 1;
173 };
174
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 */
185
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;
195   const char *ip;
196   SilcUInt16 port;
197   SilcStatus error;
198   char *error_string;
199   SilcBool auth_success;
200   SilcConnectionType conn_type;
201   SilcHash hash;
202   struct SilcServerAcceptStruct *next;
203 } *SilcServerAccept;
204
205 /* Server statistics structure. */
206 typedef struct {
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 */
217
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 */
232   /* More to add
233   SilcUInt32 secret_channels;
234   SilcUInt32 private_channels;
235   */
236
237   /* General */
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;
248
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 */
261
262   /* Events */
263   unsigned int new_connection  : 1;  /* New connection received */
264   unsigned int new_packet      : 1;  /* New packet in packet queue */
265 };
266
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;
273
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 */
284
285   SilcFSMSemaStruct wait_event;      /* Main state signaller */
286   SilcFSMSemaStruct thread_up;       /* Signaller when thread is up */
287
288   SilcIDCache clients;               /* Client entry cache */
289   SilcIDCache servers;               /* Server entry cache */
290   SilcIDCache channels;              /* Channel entry cache */
291
292   SilcSKR repository;                /* Public key/certificate repository */
293   SilcHashTable watcher_list;        /* Watcher list, nickname */
294   SilcHashTable watcher_list_pk;     /* Watcher list, public keys */
295
296   void *app_context;                 /* Application specific context */
297
298   char *config_file;
299
300   /* Events */
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 */
307
308   /* Flags */
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. */
326
327   SilcPacketStream router;           /* Pointer to the primary router */
328
329   /* Current command identifier, 0 not used */
330   SilcUInt16 cmd_ident;
331
332   /* Server public key */
333   SilcPKCS pkcs;
334   SilcPublicKey public_key;
335   SilcPrivateKey private_key;
336
337   /* Hash objects for general hashing */
338   SilcHash md5hash;
339   SilcHash sha1hash;
340
341   /* Server statistics */
342   SilcServerStatistics stat;
343
344 #ifdef SILC_SIM
345   /* SIM (SILC Module) list */
346   SilcDList sim;
347 #endif
348
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;
353   void *stop_context;
354 };
355
356 /* Rekey must be performed at the lastest when this many packets is sent */
357 #define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
358
359 /* Macros */
360
361 /* Return pointer to the primary router connection */
362 #define SILC_PRIMARY_ROUTE(server) server->router
363
364 /* Return TRUE if a packet must be broadcasted (router broadcasts) */
365 #define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER)
366
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)
370
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)             \
375 do {                                                    \
376   silc_schedule_task_add(server->schedule, (fd),        \
377                          silc_server_packet_process,    \
378                          context, 0, 0,                 \
379                          SILC_TASK_GENERIC,             \
380                          SILC_TASK_PRI_NORMAL);         \
381 } while(0)
382
383 #define SILC_SET_CONNECTION_FOR_INPUT(s, fd)                            \
384 do {                                                                    \
385   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);        \
386 } while(0)
387
388 #define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd)                                \
389 do {                                                                         \
390   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
391                               FALSE);                                        \
392 } while(0)
393
394 #define SILC_OPER_STATS_UPDATE(c, type, mod)    \
395 do {                                            \
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);                        \
402   }                                             \
403 } while(0)
404
405 #define SILC_UMODE_STATS_UPDATE(oper, mod)      \
406 do {                                            \
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--;         \
413       }                                         \
414     } else {                                    \
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++;         \
420       }                                         \
421     }                                           \
422 } while(0)
423
424 #define SILC_GET_SKE_FLAGS(x, p)                        \
425   if ((x)) {                                            \
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;           \
430   }
431
432 #define SILC_CONNTYPE_STRING(ctype) \
433  (ctype == SILC_CONN_CLIENT ? "Client" : \
434   ctype == SILC_CONN_SERVER ? "Server" : "Router")
435
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
438    argument. */
439 #define SILC_SERVER_SEND_NOTIFY(server, stream, type, fmt)      \
440 do {                                                            \
441   char *__fmt__ = silc_format fmt;                              \
442   if (__fmt__)                                                  \
443     silc_server_send_notify(server, stream, FALSE,              \
444                             type, 1, __fmt__, strlen(__fmt__)); \
445   silc_free(__fmt__);                                           \
446 } while(0)
447
448 /* Send notify to operators */
449 #define SILC_SERVER_SEND_OPERS(server, route, local, type, fmt)         \
450 do {                                                                    \
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__);                                                   \
455 } while(0)
456
457 /* Connection retry timeout. We implement exponential backoff algorithm
458    in connection retry. The interval of timeout grows when retry count
459    grows. */
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 */
465
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 */
471
472 /* Macros */
473
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)
478
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)
483
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)
494
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);
503
504 /* Server's thread's states */
505 SILC_FSM_STATE(silc_server_thread_st_start);
506 SILC_FSM_STATE(silc_server_thread_st_run);
507
508 /* Prototypes */
509 void silc_server_watcher_list_destroy(void *key, void *context,
510                                       void *user_context);
511
512 #include "server_entry.h"
513
514 #endif /* SERVER_INTERNAL_H */