Merged silc_1_0_branch to trunk.
[silc.git] / apps / silcd / server_internal.h
index 346162798eda045b8fb42bc5dfe5a4363234eccc..7cf42a8ed8964553455acac8f70a10e81438c231 100644 (file)
@@ -2,15 +2,15 @@
 
   server_internal.h
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2001 Pekka Riikonen
+  Copyright (C) 1997 - 2003 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
-  
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    various things. */
 typedef struct {
   /* Local stats (server and router) */
-  unsigned long my_clients;      /* Locally connected clients */
-  unsigned long my_servers;      /* Locally connected servers */
-  unsigned long my_routers;      /* Locally connected routers */
-  unsigned long my_channels;     /* Locally created channels */
-  unsigned long my_chanclients;          /* Local clients on local channels */
-  unsigned long my_aways;        /* Local clients away (XXX) */
-  unsigned long my_server_ops;   /* Local server operators */
-  unsigned long my_router_ops;   /* Local router operators */
+  SilcUInt32 my_clients;                 /* Locally connected clients */
+  SilcUInt32 my_servers;                 /* Locally connected servers */
+  SilcUInt32 my_routers;                 /* Locally connected routers */
+  SilcUInt32 my_channels;                /* Locally created channels */
+  SilcUInt32 my_chanclients;             /* Local clients on local channels */
+  SilcUInt32 my_aways;                   /* Local clients away (gone) */
+  SilcUInt32 my_detached;                /* Local clients detached */
+  SilcUInt32 my_server_ops;              /* Local server operators */
+  SilcUInt32 my_router_ops;              /* Local router operators */
 
   /* Global stats (mainly for router) */
-  unsigned long cell_clients;    /* All clients in cell */
-  unsigned long cell_servers;    /* All servers in cell */
-  unsigned long cell_channels;   /* All channels in cell */
-  unsigned long cell_chanclients; /* All clients on cell's channels */
-  unsigned long clients;         /* All clients */
-  unsigned long servers;         /* All servers */
-  unsigned long routers;         /* All routers */
-  unsigned long channels;        /* All channels */
-  unsigned long chanclients;     /* All clients on channels */
-  unsigned long server_ops;      /* All server operators */
-  unsigned long router_ops;      /* All router operators */
+  SilcUInt32 cell_clients;               /* All clients in cell */
+  SilcUInt32 cell_servers;               /* All servers in cell */
+  SilcUInt32 cell_channels;              /* All channels in cell */
+  SilcUInt32 cell_chanclients;           /* All clients on cell's channels */
+  SilcUInt32 clients;                    /* All clients */
+  SilcUInt32 servers;                    /* All servers */
+  SilcUInt32 routers;                    /* All routers */
+  SilcUInt32 channels;                   /* All channels */
+  SilcUInt32 chanclients;                /* All clients on channels */
+  SilcUInt32 aways;                      /* All clients away (gone) */
+  SilcUInt32 detached;                   /* All clients detached */
+  SilcUInt32 server_ops;                 /* All server operators */
+  SilcUInt32 router_ops;                 /* All router operators */
+  /* More to add
+  SilcUInt32 secret_channels;
+  SilcUInt32 private_channels;
+  */
 
   /* General */
-  unsigned long conn_attempts;   /* Connection attempts */
-  unsigned long conn_failures;   /* Connection failure */
-  unsigned long auth_attempts;   /* Authentication attempts */
-  unsigned long auth_failures;   /* Authentication failures */
-  unsigned long packets_sent;    /* Sent packets */
-  unsigned long packets_received; /* Received packets */
+  SilcUInt32 conn_attempts;              /* Connection attempts */
+  SilcUInt32 conn_failures;              /* Connection failure */
+  SilcUInt32 auth_attempts;              /* Authentication attempts */
+  SilcUInt32 auth_failures;              /* Authentication failures */
+  SilcUInt32 packets_sent;               /* Sent SILC packets */
+  SilcUInt32 packets_received;           /* Received SILC packets */
 } SilcServerStatistics;
 
-typedef struct {
-  void *id_entry;
-  SilcSocketConnection sock;
-
-  /* Remote host name and port */
-  char *remote_host;
-  int remote_port;
-  
-  /* Current connection retry info */
-  unsigned int retry_count;
-  unsigned int retry_timeout;
-
-  /* Back pointer to server */
-  SilcServer server;
-} *SilcServerConnection;
-
-/* 
+/*
    SILC Server Object.
 
 */
 struct SilcServerStruct {
   char *server_name;
-  int server_type;
   int sock;
-  int standalone;
-  int listenning;
+  SilcServerEntry id_entry;
   SilcServerID *id;
   unsigned char *id_string;
-  unsigned int id_string_len;
-  SilcIdType id_type;
-
-  /* Server's own ID entry. */
-  SilcServerEntry id_entry;
-
-  /* Back pointer to the primary router of this server. */
-  SilcServerEntry router;
-
-  /* SILC server task queues */
-  SilcTaskQueue io_queue;
-  SilcTaskQueue timeout_queue;
-  SilcTaskQueue generic_queue;
+  SilcUInt32 id_string_len;
+  SilcUInt32 starttime;
+
+  unsigned int server_type    : 2;   /* Server type (server.h) */
+  unsigned int standalone     : 1;   /* Set if server is standalone, and
+                                       does not have connection to network. */
+  unsigned int listenning     : 1;   /* Set if server is listenning for
+                                       incoming connections. */
+  unsigned int background     : 1;   /* Set when server is on background */
+  unsigned int backup_router  : 1;   /* Set if this is backup router */
+  unsigned int backup_primary : 1;   /* Set if we've switched our primary
+                                       router to a backup router. */
+  unsigned int backup_noswitch: 1;   /* Set if we've won't switch to
+                                       become primary (we are backup) */
+  unsigned int backup_closed  : 1;   /* Set if backup closed connection.
+                                       Do not allow resuming in this case. */
+  unsigned int wait_backup    : 1;   /* Set if we are waiting for backup
+                                       router to connect to us. */
+  unsigned int server_shutdown: 1;   /* Set when shutting down */
+  unsigned int no_reconnect   : 1;   /* If set, server won't reconnect to
+                                       router after disconnection. */
+
+  SilcServerEntry router;           /* Pointer to the primary router */
+  unsigned long router_connect;             /* Time when router was connected */
+  SilcServerConnection router_conn;  /* non-NULL when connecting to the
+                                       primary router, and NULL otherwise. */
+  SilcServerBackup backup;          /* Backup routers */
+
+  /* Current command identifier, 0 not used */
+  SilcUInt16 cmd_ident;
+
+  /* SILC server scheduler */
+  SilcSchedule schedule;
 
   /* ID lists. */
   SilcIDList local_list;
   SilcIDList global_list;
+  SilcHashTable watcher_list;
 
   /* Table of connected sockets */
   SilcSocketConnection *sockets;
 
-  /* Server keys */
-  SilcCipher send_key;
-  SilcCipher receive_key;
-  SilcCipher none_cipher;
-
   /* Server public key */
   SilcPKCS pkcs;
   SilcPublicKey public_key;
@@ -119,12 +124,10 @@ struct SilcServerStruct {
   SilcHash md5hash;
   SilcHash sha1hash;
 
-  /* HMAC objects for MAC's. */
-  SilcHmac md5hmac;
-  SilcHmac sha1hmac;
-
   /* Configuration object */
-  SilcConfigServer config;
+  SilcServerConfig config;
+  SilcServerConfigRef config_ref;
+  char *config_file;
 
   /* Random pool */
   SilcRng rng;
@@ -135,8 +138,9 @@ struct SilcServerStruct {
   /* Pending command queue */
   SilcDList pending_commands;
 
-  /* Default parameteres for server */
-  SilcServerParams params;
+  /* Purge context for disconnected clients */
+  SilcIDListPurge purge_i;
+  SilcIDListPurge purge_g;
 
 #ifdef SILC_SIM
   /* SIM (SILC Module) list */
@@ -144,37 +148,96 @@ struct SilcServerStruct {
 #endif
 };
 
-/* Server's heartbeat context */
+/* Failure context. This is allocated when failure packet is received.
+   Failure packets are processed with timeout and data is saved in this
+   structure. */
 typedef struct {
-  SilcServer server;
-} *SilcServerHBContext;
+  SilcSocketConnection sock;
+  SilcUInt32 failure;
+} *SilcServerFailureContext;
+
+/* Rekey must be performed at the lastest when this many packets is sent */
+#define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
 
 /* Macros */
 
+/* Return pointer to the primary router connection */
+#define SILC_PRIMARY_ROUTE(server) \
+  (!server->standalone && server->router ? server->router->connection : NULL)
+
+/* Return TRUE if a packet must be broadcasted (router broadcasts) */
+#define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER)
+
+/* Return TRUE if entry is locally connected or local to us */
+#define SILC_IS_LOCAL(entry) \
+  (((SilcIDListData)entry)->status & SILC_IDLIST_STATUS_LOCAL)
+
 /* Registers generic task for file descriptor for reading from network and
-   writing to network. As being generic task the actual task is allocated 
+   writing to network. As being generic task the actual task is allocated
    only once and after that the same task applies to all registered fd's. */
-#define SILC_REGISTER_CONNECTION_FOR_IO(fd)                            \
-do {                                                                   \
-  SilcTask tmptask = silc_task_register(server->generic_queue, (fd),   \
-                                       silc_server_packet_process,     \
-                                       context, 0, 0,                  \
-                                       SILC_TASK_GENERIC,              \
-                                       SILC_TASK_PRI_NORMAL);          \
-  silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                      \
+#define SILC_REGISTER_CONNECTION_FOR_IO(fd)            \
+do {                                                   \
+  silc_schedule_task_add(server->schedule, (fd),       \
+                        silc_server_packet_process,    \
+                        context, 0, 0,                 \
+                        SILC_TASK_GENERIC,             \
+                        SILC_TASK_PRI_NORMAL);         \
 } while(0)
 
-#define SILC_SET_CONNECTION_FOR_INPUT(fd)                              \
+#define SILC_SET_CONNECTION_FOR_INPUT(s, fd)                           \
 do {                                                                   \
-  silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));            \
+  silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);       \
 } while(0)
-     
-#define SILC_SET_CONNECTION_FOR_OUTPUT(fd)                             \
-do {                                                                   \
-  silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |           \
-                                    (1L << SILC_TASK_WRITE)));         \
+
+#define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd)                               \
+do {                                                                        \
+  silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
+                             FALSE);                                        \
+} while(0)
+
+#define SILC_OPER_STATS_UPDATE(c, type, mod)   \
+do {                                           \
+  if ((c)->mode & (mod)) {                     \
+    if (SILC_IS_LOCAL((c)))                    \
+      server->stat.my_ ## type ## _ops--;      \
+    if (server->server_type == SILC_ROUTER)    \
+      server->stat. type ## _ops--;            \
+    (c)->mode &= ~(mod);                       \
+  }                                            \
 } while(0)
 
+#define SILC_UMODE_STATS_UPDATE(oper, mod)     \
+do {                                           \
+    if (client->mode & (mod)) {                        \
+      if (!(mode & (mod))) {                   \
+       if (SILC_IS_LOCAL(client))              \
+         server->stat.my_ ## oper ## _ops--;   \
+        if (server->server_type == SILC_ROUTER)        \
+         server->stat. oper ## _ops--;         \
+      }                                                \
+    } else {                                   \
+      if (mode & (mod)) {                      \
+       if (SILC_IS_LOCAL(client))              \
+         server->stat.my_ ## oper ## _ops++;   \
+        if (server->server_type == SILC_ROUTER)        \
+         server->stat. oper ## _ops++;         \
+      }                                                \
+    }                                          \
+} while(0)
+
+#define SILC_GET_SKE_FLAGS(x, p)                       \
+  if ((x)) {                                           \
+    if ((x)->param && (x)->param->key_exchange_pfs)    \
+      (p)->flags |= SILC_SKE_SP_FLAG_PFS;              \
+    if (!(x)->publickeys)                              \
+      (p)->flags |= SILC_SKE_SP_FLAG_MUTUAL;           \
+  }
+
 /* Prototypes */
+SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final);
+SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback);
+SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router);
+void silc_server_watcher_list_destroy(void *key, void *context,
+                                     void *user_context);
 
 #endif