updates
[silc.git] / apps / silcd / serverconfig.c
index b0f3b1db084191d5ee18d6aaaa58d87425892ff8..5a8f731d0b0414570a6701e05e2026a239dd21ba 100644 (file)
 #include "server_internal.h"
 
 SilcServerConfigSection silc_server_config_sections[] = {
-  { "[Cipher]", 
+  { "[Cipher]",
     SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 },
-  { "[PKCS]", 
+  { "[PKCS]",
     SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 },
-  { "[Hash]", 
+  { "[Hash]",
     SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
-  { "[hmac]", 
+  { "[hmac]",
     SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 },
-  { "[ServerKeys]", 
+  { "[ServerKeys]",
     SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 },
-  { "[ServerInfo]", 
+  { "[ServerInfo]",
     SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
-  { "[AdminInfo]", 
+  { "[AdminInfo]",
     SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
-  { "[ListenPort]", 
+  { "[ListenPort]",
     SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
-  { "[Identity]", 
+  { "[Identity]",
     SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 },
-  { "[Logging]", 
+  { "[Logging]",
     SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
   { "[ConnectionClass]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
@@ -57,6 +57,8 @@ SilcServerConfigSection silc_server_config_sections[] = {
     SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
   { "[motd]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
+  { "[pid]",
+    SILC_CONFIG_SERVER_SECTION_TYPE_PID, 1},
   
   { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
 };
@@ -94,11 +96,12 @@ SilcServerConfig silc_server_config_alloc(char *filename)
   if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
     goto fail;
 
-  silc_free(buffer);
+  silc_buffer_free(buffer);
 
   return new;
 
  fail:
+  silc_buffer_free(buffer);
   silc_free(new);
   return NULL;
 }
@@ -121,6 +124,7 @@ void silc_server_config_free(SilcServerConfig config)
     silc_free(config->routers);
     silc_free(config->denied);
     silc_free(config->motd);
+    silc_free(config->pidfile);
     silc_free(config);
   }
 }
@@ -143,7 +147,7 @@ int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
 
   begin = 0;
   linenum = 0;
-  while((begin = silc_gets(line, sizeof(line), 
+  while((begin = silc_gets(line, sizeof(line),
                           buffer->data, buffer->len, begin)) != EOF) {
     cp = line;
     linenum++;
@@ -268,7 +272,7 @@ int silc_server_config_parse_lines(SilcServerConfig config,
 
     /* Get number of tokens in line */
     ret = silc_config_check_num_token(line);
-    if (ret != pc->section->maxfields) {
+    if (ret < pc->section->maxfields) {
       /* Bad line */
       fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
              config->filename, pc->linenum, ret, 
@@ -557,13 +561,13 @@ int silc_server_config_parse_lines(SilcServerConfig config,
 
       SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
 
-      /* Get host */
-      ret = silc_config_get_token(line, &config->listen_port->host);
+      /* Get local IP */
+      ret = silc_config_get_token(line, &config->listen_port->local_ip);
       if (ret < 0)
        break;
 
-      /* Get remote IP */
-      ret = silc_config_get_token(line, &config->listen_port->remote_ip);
+      /* Get listener IP */
+      ret = silc_config_get_token(line, &config->listen_port->listener_ip);
       if (ret < 0)
        break;
 
@@ -649,14 +653,16 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       if (ret < 0)
        break;
       if (ret == 0) {
-       fprintf(stderr, "%s:%d: Log file section not defined\n", 
+       fprintf(stderr, "%s:%d: Log file section not defined\n",
                config->filename, pc->linenum);
        break;
       }
       if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
          && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
          && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
-         && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
+         && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)
+         && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_QUICK)
+         && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
        fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
                config->filename, pc->linenum, config->logging->logtype);
        break;
@@ -848,6 +854,15 @@ int silc_server_config_parse_lines(SilcServerConfig config,
        silc_free(tmp);
       }
 
+      /* Check whether this connection is backup router connection */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret != -1) {
+       config->servers->backup_router = atoi(tmp);
+       if (config->servers->backup_router != 0)
+         config->servers->backup_router = TRUE;
+       silc_free(tmp);
+      }
+
       check = TRUE;
       checkmask |= (1L << pc->section->type);
       break;
@@ -860,9 +875,6 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       ret = silc_config_get_token(line, &config->routers->host);
       if (ret < 0)
        break;
-      //      if (ret == 0)
-      ///* Any host */
-      //       config->routers->host = strdup("*");
 
       /* Get authentication method */
       ret = silc_config_get_token(line, &tmp);
@@ -945,6 +957,29 @@ int silc_server_config_parse_lines(SilcServerConfig config,
        silc_free(tmp);
       }
 
+      /* Get backup replace IP */
+      ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
+      if (ret != -1)
+       config->routers->backup_router = TRUE;
+
+      if (config->routers->backup_router) {
+       /* Get backup replace port */
+       ret = silc_config_get_token(line, &tmp);
+       if (ret != -1) {
+         config->routers->backup_replace_port = atoi(tmp);
+         silc_free(tmp);
+       }
+       
+       /* Check whether the backup connection is local */
+       ret = silc_config_get_token(line, &tmp);
+       if (ret != -1) {
+         config->routers->backup_local = atoi(tmp);
+         if (config->routers->backup_local != 0)
+           config->routers->backup_local = TRUE;
+         silc_free(tmp);
+       }
+      }
+
       check = TRUE;
       checkmask |= (1L << pc->section->type);
       break;
@@ -1078,6 +1113,19 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       checkmask |= (1L << pc->section->type);
       break;
 
+    case SILC_CONFIG_SERVER_SECTION_TYPE_PID:
+
+       if (!config->pidfile)
+          config->pidfile = silc_calloc(1, sizeof(*config->pidfile));
+          
+       ret = silc_config_get_token(line, &config->pidfile->pid_file);
+       if (ret < 0)
+          break;
+          
+       check = TRUE;
+       checkmask |= (1L << pc->section->type);
+       break;
+
     case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
     default:
       /* Error */
@@ -1095,7 +1143,7 @@ int silc_server_config_parse_lines(SilcServerConfig config,
   }
 
   if (check == FALSE)
-    return FALSE;;
+    return FALSE;
 
   /* Check that all mandatory sections really were found. If not, the server
      cannot function and we return error. */
@@ -1162,9 +1210,9 @@ int silc_server_config_check_sections(uint32 checkmask)
     
     return FALSE;
   }
-  if (!(checkmask 
+  if (!(checkmask
        & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
-    
+
     return FALSE;
   }
 
@@ -1173,60 +1221,57 @@ int silc_server_config_check_sections(uint32 checkmask)
 
 /* Sets log files where log messages is saved by the server. */
 
-void silc_server_config_setlogfiles(SilcServerConfig config)
+void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked)
 {
+  long tmp;
   SilcServerConfigSectionLogging *log;
-  char *info, *warning, *error, *fatal;
-  uint32 info_size, warning_size, error_size, fatal_size;
 
   SILC_LOG_DEBUG(("Setting configured log file names"));
-
-  /* Set default files before checking configuration */
-  info = SILC_LOG_FILE_INFO;
-  warning = SILC_LOG_FILE_WARNING;
-  error = SILC_LOG_FILE_ERROR;
-  fatal = SILC_LOG_FILE_FATAL;
-  info_size = 0;
-  warning_size = 0;
-  error_size = 0;
-  fatal_size = 0;
-
   log = config->logging;
-  while(log) {
-    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
-      info = log->filename;
-      info_size = log->maxsize;
+  while (log) {
+    /* Logging Files */
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO))
+      silc_log_set_file(SILC_LOG_INFO, log->filename, log->maxsize, sked);
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING))
+      silc_log_set_file(SILC_LOG_WARNING, log->filename, log->maxsize, sked);
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR))
+      silc_log_set_file(SILC_LOG_ERROR, log->filename, log->maxsize, sked);
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL))
+      silc_log_set_file(SILC_LOG_FATAL, log->filename, log->maxsize, sked);
+    /* Logging Options */
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_QUICK)) {
+      if (!strcasecmp(log->filename, "yes") ||
+         !strcasecmp(log->filename, "on"))
+          silc_log_quick = TRUE;
     }
-    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
-      warning = log->filename;
-      warning_size = log->maxsize;
-    }
-    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
-      error = log->filename;
-      error_size = log->maxsize;
-    }
-    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
-      fatal = log->filename;
-      fatal_size = log->maxsize;
+    if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
+      tmp = atol(log->filename);
+      if (tmp > 0)
+        silc_log_flushdelay = tmp;
+      else {
+        fprintf(stderr, "config: invalid flushdelay value, use quicklogs if "
+               "you want real-time logging.\n");
+       exit(1);
+      }
     }
 
     log = log->next;
   }
-
-  silc_log_set_files(info, info_size, warning, warning_size,
-                    error, error_size, fatal, fatal_size);
 }
 
 /* Registers configured ciphers. These can then be allocated by the
    server when needed. */
 
-void silc_server_config_register_ciphers(SilcServerConfig config)
+bool silc_server_config_register_ciphers(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured ciphers"));
 
+  if (!config->cipher)
+    return FALSE;
+
   alg = config->cipher;
   while(alg) {
 
@@ -1303,17 +1348,22 @@ void silc_server_config_register_ciphers(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configured PKCS's. */
 
-void silc_server_config_register_pkcs(SilcServerConfig config)
+bool silc_server_config_register_pkcs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg = config->pkcs;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured PKCS"));
 
+  if (!config->pkcs)
+    return FALSE;
+
   while(alg) {
     int i;
     
@@ -1331,18 +1381,23 @@ void silc_server_config_register_pkcs(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configured hash functions. These can then be allocated by the
    server when needed. */
 
-void silc_server_config_register_hashfuncs(SilcServerConfig config)
+bool silc_server_config_register_hashfuncs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured hash functions"));
 
+  if (!config->hash_func)
+    return FALSE;
+
   alg = config->hash_func;
   while(alg) {
 
@@ -1409,24 +1464,22 @@ void silc_server_config_register_hashfuncs(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configure HMACs. These can then be allocated by the server
    when needed. */
 
-void silc_server_config_register_hmacs(SilcServerConfig config)
+bool silc_server_config_register_hmacs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured HMACs"));
 
-  if (!config->hmac) {
-    SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
-                   "HMACs"));
-    silc_server_stop(server);
-    exit(1);
-  }
+  if (!config->hmac)
+    return FALSE;
 
   alg = config->hmac;
   while(alg) {
@@ -1446,6 +1499,8 @@ void silc_server_config_register_hmacs(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Returns client authentication information from server configuration
@@ -1573,7 +1628,7 @@ bool silc_server_config_is_primary_route(SilcServerConfig config)
 
   serv = config->routers;
   for (i = 0; serv; i++) {
-    if (serv->initiator == TRUE) {
+    if (serv->initiator == TRUE && serv->backup_router == FALSE) {
       found = TRUE;
       break;
     }
@@ -1584,6 +1639,25 @@ bool silc_server_config_is_primary_route(SilcServerConfig config)
   return found;
 }
 
+/* Returns our primary connection configuration or NULL if we do not
+   have primary router configured. */
+
+SilcServerConfigSectionServerConnection *
+silc_server_config_get_primary_router(SilcServerConfig config)
+{
+  int i;
+  SilcServerConfigSectionServerConnection *serv = NULL;
+
+  serv = config->routers;
+  for (i = 0; serv; i++) {
+    if (serv->initiator == TRUE && serv->backup_router == FALSE)
+      return serv;
+    serv = serv->next;
+  }
+
+  return NULL;
+}
+
 /* Returns Admin connection configuration by host, username and/or 
    nickname. */