Fixed notify sending to backup routers, and fixed channel
[silc.git] / apps / silcd / serverconfig.c
index 6252325bbf45f707db7633fe253980e5c8b1b742..5123bf0722a7ea0cc2e75284fdc1a6787c5324c9 100644 (file)
@@ -122,9 +122,10 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p,
     /* p is a plain text password */
     if (auth_data && auth_data_len) {
       if (!silc_utf8_valid(p, strlen(p))) {
-       *auth_data_len = silc_utf8_encoded_len(p, strlen(p), 0);
+       *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
+                                              SILC_STRING_LANGUAGE);
        *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
-       silc_utf8_encode(p, strlen(p), SILC_STRING_ASCII, *auth_data,
+       silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data,
                         *auth_data_len);
       } else {
        *auth_data = (void *) strdup(p);
@@ -423,9 +424,8 @@ SILC_CONFIG_CALLBACK(fetch_pkcs)
 
 SILC_CONFIG_CALLBACK(fetch_serverinfo)
 {
-  SilcServerConfig config = (SilcServerConfig) context;
+  SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
   SilcServerConfigServerInfo *server_info = config->server_info;
-  int got_errno = 0;
 
   /* if there isn't the struct alloc it */
   if (!server_info)
@@ -433,8 +433,20 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo)
                silc_calloc(1, sizeof(*server_info));
 
   if (type == SILC_CONFIG_ARG_BLOCK) {
-    /* check for mandatory inputs */
-    if (!server_info->public_key || !server_info->private_key) {
+    if (!strcmp(name, "primary")) {
+      CONFIG_IS_DOUBLE(server_info->primary);
+      if (!tmp)
+       return SILC_CONFIG_OK;
+      server_info->primary = tmp;
+      config->tmp = NULL;
+      return SILC_CONFIG_OK;
+    } else if (!strcmp(name, "secondary")) {
+      if (!tmp)
+       return SILC_CONFIG_OK;
+      SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
+      config->tmp = NULL;
+      return SILC_CONFIG_OK;
+    } else if (!server_info->public_key || !server_info->private_key) {
       got_errno = SILC_CONFIG_EMISSFIELDS;
       goto got_err;
     }
@@ -445,18 +457,20 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo)
     server_info->server_name = strdup((char *) val);
   }
   else if (!strcmp(name, "ip")) {
-    CONFIG_IS_DOUBLE(server_info->server_ip);
-    server_info->server_ip = strdup((char *) val);
+    SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
+    CONFIG_IS_DOUBLE(tmp->server_ip);
+    tmp->server_ip = strdup((char *) val);
   }
   else if (!strcmp(name, "port")) {
     int port = *(int *)val;
+    SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
     if ((port <= 0) || (port > 65535)) {
       SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
                             "Invalid port number!\n"));
       got_errno = SILC_CONFIG_EPRINTLINE;
       goto got_err;
     }
-    server_info->port = (SilcUInt16) port;
+    tmp->port = (SilcUInt16) port;
   }
   else if (!strcmp(name, "servertype")) {
     CONFIG_IS_DOUBLE(server_info->server_type);
@@ -521,6 +535,9 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo)
   return SILC_CONFIG_OK;
 
  got_err:
+  silc_free(tmp);
+  silc_free(config->tmp);
+  config->tmp = NULL;
   return got_errno;
 }
 
@@ -951,6 +968,7 @@ SILC_CONFIG_CALLBACK(fetch_router)
     CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
     tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
                              strdup("*"));
+    tmp->backup_router = TRUE;
   }
   else if (!strcmp(name, "backupport")) {
     int port = *(int *)val;
@@ -1032,10 +1050,16 @@ static const SilcConfigTable table_pkcs[] = {
   { 0, 0, 0, 0 }
 };
 
-static const SilcConfigTable table_serverinfo[] = {
-  { "hostname",                SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
+static const SilcConfigTable table_serverinfo_c[] = {
   { "ip",              SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
   { "port",            SILC_CONFIG_ARG_INT,    fetch_serverinfo, NULL},
+  { 0, 0, 0, 0 }
+};
+
+static const SilcConfigTable table_serverinfo[] = {
+  { "hostname",                SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
+  { "primary",         SILC_CONFIG_ARG_BLOCK,  fetch_serverinfo, table_serverinfo_c},
+  { "secondary",       SILC_CONFIG_ARG_BLOCK,  fetch_serverinfo, table_serverinfo_c},
   { "servertype",      SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
   { "location",                SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
   { "admin",           SILC_CONFIG_ARG_STR,    fetch_serverinfo, NULL},
@@ -1233,8 +1257,6 @@ SilcServerConfig silc_server_config_alloc(const char *filename)
     return NULL;
   }
 
-  /* XXX are there any other mandatory sections in the config file? */
-
   /* Set default to configuration parameters */
   silc_server_config_set_defaults(config_new);
 
@@ -1293,12 +1315,24 @@ void silc_server_config_destroy(SilcServerConfig config)
     silc_free(config->logging_errors->file);
   if (config->logging_fatals)
     silc_free(config->logging_fatals->file);
+  silc_free(config->logging_info);
+  silc_free(config->logging_warnings);
+  silc_free(config->logging_errors);
+  silc_free(config->logging_fatals);
 
   /* Destroy the ServerInfo struct */
   if (config->server_info) {
     register SilcServerConfigServerInfo *si = config->server_info;
     silc_free(si->server_name);
-    silc_free(si->server_ip);
+    if (si->primary) {
+      silc_free(si->primary->server_ip);
+      silc_free(si->primary);
+    }
+    SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
+                                 si->secondary)
+      silc_free(di->server_ip);
+      silc_free(di);
+    }
     silc_free(si->server_type);
     silc_free(si->location);
     silc_free(si->admin);
@@ -1309,6 +1343,7 @@ void silc_server_config_destroy(SilcServerConfig config)
     silc_free(si->pid_file);
     silc_pkcs_public_key_free(si->public_key);
     silc_pkcs_private_key_free(si->private_key);
+    silc_free(si);
   }
 
   /* Now let's destroy the lists */
@@ -1776,6 +1811,31 @@ silc_server_config_find_router_conn(SilcServer server, char *host, int port)
   return serv;
 }
 
+/* Find backup router connection by host (name or ip) */
+
+SilcServerConfigRouter *
+silc_server_config_find_backup_conn(SilcServer server, char *host)
+{
+  SilcServerConfig config = server->config;
+  SilcServerConfigRouter *serv = NULL;
+
+  if (!host)
+    return NULL;
+
+  if (!config->routers)
+    return NULL;
+
+  for (serv = config->routers; serv; serv = serv->next) {
+    if (!serv->backup_router)
+      continue;
+    if (!silc_string_compare(serv->host, host))
+      continue;
+    break;
+  }
+
+  return serv;
+}
+
 /* Returns TRUE if configuration for a router connection that we are
    initiating exists. */
 
@@ -1818,3 +1878,31 @@ silc_server_config_get_primary_router(SilcServer server)
 
   return NULL;
 }
+
+/* If we have backup router configured that is going to replace us this
+   function returns it. */
+
+SilcServerConfigRouter *
+silc_server_config_get_backup_router(SilcServer server)
+{
+  SilcServerConfig config = server->config;
+  SilcServerConfigRouter *serv = NULL;
+  int i;
+
+  if (server->server_type != SILC_ROUTER)
+    return NULL;
+
+  serv = config->routers;
+  for (i = 0; serv; i++) {
+    if (serv->initiator == FALSE && serv->backup_router == TRUE &&
+       serv->backup_local == TRUE &&
+       !strcmp(server->config->server_info->primary->server_ip,
+               serv->backup_replace_ip) &&
+       server->config->server_info->primary->port ==
+       serv->backup_replace_port)
+      return serv;
+    serv = serv->next;
+  }
+
+  return NULL;
+}