Added SILC Thread Queue API
[crypto.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 - 2006 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   SilcFSMEventStruct 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   SilcUInt16 resolve_cmd_ident;      /* Command identifier when resolving */
127
128   long last_command;
129   SilcUInt8 fast_command;
130   unsigned long updated;
131
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;
135 };
136
137 /* Channel entry */
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 */
143
144   unsigned char *passphrase;         /* Channel's passphrase */
145   SilcHashTable channel_pubkeys;     /* Channel authentication public keys */
146   SilcPublicKey founder_key;         /* Channel founder's public key */
147
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 */
155
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 */
161
162   //  SilcServerChannelRekey rekey;
163   unsigned long created;
164   unsigned long updated;
165
166   /* Flags */
167   unsigned int global_users : 1;
168   unsigned int disabled : 1;
169   unsigned int users_resolved : 1;
170 };
171
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   SilcFSMEventStruct wait_register;   /* Signaller when registering received */
181   SilcPacket register_packet;        /* NEW_CLIENT/NEW_SERVER packet */
182
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;
192   const char *ip;
193   SilcUInt16 port;
194   SilcStatus error;
195   char *error_string;
196   SilcBool auth_success;
197   SilcConnectionType conn_type;
198   SilcHash hash;
199   struct SilcServerAcceptStruct *next;
200 } *SilcServerAccept;
201
202 /* Server statistics structure. */
203 typedef struct {
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 */
214
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 */
229   /* More to add
230   SilcUInt32 secret_channels;
231   SilcUInt32 private_channels;
232   */
233
234   /* General */
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;
245
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   SilcFSMEventStruct 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 */
258
259   /* Events */
260   unsigned int new_connection  : 1;  /* New connection received */
261   unsigned int new_packet      : 1;  /* New packet in packet queue */
262 };
263
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;
270
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 */
281
282   SilcFSMEventStruct wait_event;             /* Main state signaller */
283   SilcFSMEventStruct thread_up;      /* Signaller when thread is up */
284
285   SilcIDCache clients;               /* Client entry cache */
286   SilcIDCache servers;               /* Server entry cache */
287   SilcIDCache channels;              /* Channel entry cache */
288
289   SilcSKR repository;                /* Public key/certificate repository */
290   SilcHashTable watcher_list;        /* Watcher list, nickname */
291   SilcHashTable watcher_list_pk;     /* Watcher list, public keys */
292
293   void *app_context;                 /* Application specific context */
294
295   char *config_file;
296
297   /* Events */
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 */
304
305   /* Flags */
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. */
323
324   SilcPacketStream router;           /* Pointer to the primary router */
325
326   /* Current command identifier, 0 not used */
327   SilcUInt16 cmd_ident;
328
329   /* Server public key */
330   SilcPublicKey public_key;
331   SilcPrivateKey private_key;
332
333   /* Hash objects for general hashing */
334   SilcHash md5hash;
335   SilcHash sha1hash;
336
337   /* Server statistics */
338   SilcServerStatistics stat;
339
340 #ifdef SILC_SIM
341   /* SIM (SILC Module) list */
342   SilcDList sim;
343 #endif
344
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;
349   void *stop_context;
350 };
351
352 /* Rekey must be performed at the lastest when this many packets is sent */
353 #define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
354
355 /* Macros */
356
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)
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) (((SilcEntryData)entry)->local)
369
370 /* Return TRUE if entry is registered */
371 #define SILC_IS_REGISTERED(entry) (((SilcEntryData)entry)->registered)
372
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)             \
377 do {                                                    \
378   silc_schedule_task_add(server->schedule, (fd),        \
379                          silc_server_packet_process,    \
380                          context, 0, 0,                 \
381                          SILC_TASK_GENERIC,             \
382                          SILC_TASK_PRI_NORMAL);         \
383 } while(0)
384
385 #define SILC_SET_CONNECTION_FOR_INPUT(s, fd)                            \
386 do {                                                                    \
387   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);        \
388 } while(0)
389
390 #define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd)                                \
391 do {                                                                         \
392   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
393                               FALSE);                                        \
394 } while(0)
395
396 #define SILC_OPER_STATS_UPDATE(c, type, mod)    \
397 do {                                            \
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);                        \
404   }                                             \
405 } while(0)
406
407 #define SILC_UMODE_STATS_UPDATE(oper, mod)      \
408 do {                                            \
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--;         \
415       }                                         \
416     } else {                                    \
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++;         \
422       }                                         \
423     }                                           \
424 } while(0)
425
426 #define SILC_GET_SKE_FLAGS(x, p)                        \
427   if ((x)) {                                            \
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;           \
432   }
433
434 #define SILC_CONNTYPE_STRING(ctype) \
435  (ctype == SILC_CONN_CLIENT ? "Client" : \
436   ctype == SILC_CONN_SERVER ? "Server" : "Router")
437
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
440    argument. */
441 #define SILC_SERVER_SEND_NOTIFY(server, stream, type, fmt)      \
442 do {                                                            \
443   char *__fmt__ = silc_format fmt;                              \
444   if (__fmt__)                                                  \
445     silc_server_send_notify(server, stream, FALSE,              \
446                             type, 1, __fmt__, strlen(__fmt__)); \
447   silc_free(__fmt__);                                           \
448 } while(0)
449
450 /* Send notify to operators */
451 #define SILC_SERVER_SEND_OPERS(server, route, local, type, fmt)         \
452 do {                                                                    \
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__);                                                   \
457 } while(0)
458
459 #define SILC_SERVER_LOG_FLUSH_DELAY    300       /* Default log flush delay */
460
461 /* Macros */
462
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)
467
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)
472
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)
483
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);
492
493 /* Server's thread's states */
494 SILC_FSM_STATE(silc_server_thread_st_start);
495 SILC_FSM_STATE(silc_server_thread_st_run);
496
497 /* Prototypes */
498 void silc_server_watcher_list_destroy(void *key, void *context,
499                                       void *user_context);
500
501 #include "server_entry.h"
502
503 #endif /* SERVER_INTERNAL_H */