Added support to retry when connecting.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 6 Nov 2000 22:12:44 +0000 (22:12 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 6 Nov 2000 22:12:44 +0000 (22:12 +0000)
apps/silcd/idlist.h
apps/silcd/protocol.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/server_internal.h
apps/silcd/serverconfig.c
apps/silcd/testi2.conf

index 51a143bbc4760c0e0fc3152a8e29ce82a13c84f6..52d3307e7bb9eb4e887cee156701b93644f20811 100644 (file)
@@ -430,7 +430,7 @@ typedef struct SilcIDListStruct {
 } *SilcIDList;
 
 /*
-   Temporary ID Entry object.
+   ID Entry for Unknown connections.
 
    This is used during authentication phases where we still don't know 
    what kind of connection remote connection is, hence, we will use this
index 67d76a638df0fe1ac618fde04afefdeaf3631337..7748faa19f007e854b1b36ec6f75edbf5a1b4d21 100644 (file)
@@ -30,6 +30,7 @@
 /* Internal context for Key Exchange protocol. */
 typedef struct {
   void *server;
+  void *context;
   SilcSocketConnection sock;
   SilcRng rng;
 
@@ -49,6 +50,7 @@ typedef struct {
 /* Internal context for connection authentication protocol */
 typedef struct {
   void *server;
+  void *context;
   SilcSocketConnection sock;
 
   /* TRUE if we are receiving part of the protocol */
index 149b34b963574d14593861624ed5396ead137537..d95352867312e189c670e2f3b790443bcf48d740 100644 (file)
@@ -28,6 +28,7 @@
 #include "server_internal.h"
 
 /* Static prototypes */
+SILC_TASK_CALLBACK(silc_server_connect_router);
 SILC_TASK_CALLBACK(silc_server_connect_to_router);
 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
@@ -86,6 +87,9 @@ void silc_server_free(SilcServer server)
     }
     silc_dlist_uninit(server->sim);
 
+    if (server->params)
+      silc_free(server->params);
+
     silc_math_primegen_uninit(); /* XXX */
     silc_free(server);
   }
@@ -108,6 +112,15 @@ int silc_server_init(SilcServer server)
   assert(server);
   assert(server->config);
 
+  /* XXX After server is made as Silc Server Library this can be given
+     as argument, for now this is hard coded */
+  server->params = silc_calloc(1, sizeof(*server->params));
+  server->params->retry_count = SILC_SERVER_RETRY_COUNT;
+  server->params->retry_interval_min = SILC_SERVER_RETRY_INTERVAL_MIN;
+  server->params->retry_interval_max = SILC_SERVER_RETRY_INTERVAL_MAX;
+  server->params->retry_keep_trying = FALSE;
+  server->params->protocol_timeout = 60;
+
   /* Set log files where log message should be saved. */
   server->config->server = server;
   silc_config_server_setlogfiles(server->config);
@@ -355,6 +368,120 @@ void silc_server_run(SilcServer server)
   silc_schedule();
 }
 
+/* Timeout callback that will be called to retry connecting to remote
+   router. This is used by both normal and router server. This will wait
+   before retrying the connecting. The timeout is generated by exponential
+   backoff algorithm. */
+
+SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
+{
+  SilcServerConnection sconn = (SilcServerConnection)context;
+  SilcServer server = sconn->server;
+
+  SILC_LOG_INFO(("Retrying connecting to a router"));
+
+  /* Calculate next timeout */
+  if (sconn->retry_count >= 1) {
+    sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
+    if (sconn->retry_timeout > SILC_SERVER_RETRY_INTERVAL_MAX)
+      sconn->retry_timeout = SILC_SERVER_RETRY_INTERVAL_MAX;
+  } else {
+    sconn->retry_timeout = server->params->retry_interval_min;
+  }
+  sconn->retry_count++;
+  sconn->retry_timeout = sconn->retry_timeout +
+    silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
+
+  /* If we've reached max retry count, give up. */
+  if (sconn->retry_count > server->params->retry_count && 
+      server->params->retry_keep_trying == FALSE) {
+    SILC_LOG_ERROR(("Could not connect to router, giving up"));
+    return;
+  }
+
+  /* Wait one before retrying */
+  silc_task_register(server->timeout_queue, fd, silc_server_connect_router,
+                    context, sconn->retry_timeout, 
+                    server->params->retry_interval_min_usec,
+                    SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+}
+
+/* Generic routine to use connect to a router. */
+
+SILC_TASK_CALLBACK(silc_server_connect_router)
+{    
+  SilcServerConnection sconn = (SilcServerConnection)context;
+  SilcServer server = sconn->server;
+  SilcSocketConnection newsocket;
+  SilcProtocol protocol;
+  SilcServerKEInternalContext *proto_ctx;
+  int sock;
+
+  /* Connect to remote host */
+  sock = silc_net_create_connection(sconn->remote_port, 
+                                   sconn->remote_host);
+  if (sock < 0) {
+    SILC_LOG_ERROR(("Could not connect to router"));
+    silc_task_register(server->timeout_queue, fd, 
+                      silc_server_connect_to_router_retry,
+                      context, 0, 1, SILC_TASK_TIMEOUT, 
+                      SILC_TASK_PRI_NORMAL);
+    return;
+  }
+
+  /* Set socket options */
+  silc_net_set_socket_nonblock(sock);
+  silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
+
+  /* Create socket connection for the connection. Even though we
+     know that we are connecting to a router we will mark the socket
+     to be unknown connection until we have executed authentication
+     protocol. */
+  silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
+  server->sockets[sock] = newsocket;
+  newsocket->hostname = sconn->remote_host;
+  newsocket->port = sconn->remote_port;
+  sconn->sock = newsocket;
+
+  /* Allocate internal protocol context. This is sent as context
+     to the protocol. */
+  proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+  proto_ctx->server = (void *)server;
+  proto_ctx->context = (void *)sconn;
+  proto_ctx->sock = newsocket;
+  proto_ctx->rng = server->rng;
+  proto_ctx->responder = FALSE;
+      
+  /* Perform key exchange protocol. silc_server_connect_to_router_second
+     will be called after the protocol is finished. */
+  silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
+                     &protocol, proto_ctx,
+                     silc_server_connect_to_router_second);
+  newsocket->protocol = protocol;
+      
+  /* Register a timeout task that will be executed if the protocol
+     is not executed within set limit. */
+  proto_ctx->timeout_task = 
+    silc_task_register(server->timeout_queue, sock, 
+                      silc_server_timeout_remote,
+                      server, server->params->protocol_timeout,
+                      server->params->protocol_timeout_usec,
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_LOW);
+
+  /* Register the connection for network input and output. This sets
+     that scheduler will listen for incoming packets for this connection 
+     and sets that outgoing packets may be sent to this connection as 
+     well. However, this doesn't set the scheduler for outgoing traffic,
+     it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
+     later when outgoing data is available. */
+  context = (void *)server;
+  SILC_REGISTER_CONNECTION_FOR_IO(sock);
+  
+  /* Run the protocol */
+  protocol->execute(server->timeout_queue, 0, protocol, sock, 0, 0);
+}
+  
 /* This function connects to our primary router or if we are a router this
    establishes all our primary routes. This is called at the start of the
    server to do authentication and key exchange with our router - called
@@ -363,148 +490,53 @@ void silc_server_run(SilcServer server)
 SILC_TASK_CALLBACK(silc_server_connect_to_router)
 {
   SilcServer server = (SilcServer)context;
-  SilcSocketConnection newsocket;
-  int sock;
+  SilcServerConnection sconn;
 
   SILC_LOG_DEBUG(("Connecting to router(s)"));
 
-  /* if we are normal SILC server we need to connect to our cell's
+  /* If we are normal SILC server we need to connect to our cell's
      router. */
   if (server->server_type == SILC_SERVER) {
-    SilcProtocol protocol;
-    SilcServerKEInternalContext *proto_ctx;
+    SILC_LOG_DEBUG(("We are normal server"));
 
     /* Create connection to the router, if configured. */
     if (server->config->routers) {
-      sock = silc_net_create_connection(server->config->routers->port, 
-                                       server->config->routers->host);
-      if (sock < 0) {
-       SILC_LOG_ERROR(("Could not connect to router"));
-       silc_schedule_stop();
-       return;
-      }
 
-      /* Set socket options */
-      silc_net_set_socket_nonblock(sock);
-      silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-
-      /* Create socket connection for the connection. Even though we
-        know that we are connecting to a router we will mark the socket
-        to be unknown connection until we have executed authentication
-        protocol. */
-      silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
-      server->sockets[sock] = newsocket;
-      newsocket->hostname = server->config->routers->host;
-      newsocket->port = server->config->routers->port;
-
-      /* Allocate internal protocol context. This is sent as context
-        to the protocol. */
-      proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
-      proto_ctx->server = context;
-      proto_ctx->sock = newsocket;
-      proto_ctx->rng = server->rng;
-      proto_ctx->responder = FALSE;
-      
-      /* Perform key exchange protocol. silc_server_connect_to_router_second
-        will be called after the protocol is finished. */
-      silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
-                         &protocol, proto_ctx,
-                         silc_server_connect_to_router_second);
-      newsocket->protocol = protocol;
-      
-      /* Register a timeout task that will be executed if the protocol
-        is not executed within 60 seconds. For now, this is a hard coded 
-        limit. After 60 secs the connection will be closed if the key 
-        exchange protocol has not been executed. */
-      proto_ctx->timeout_task = 
-       silc_task_register(server->timeout_queue, sock, 
-                          silc_server_timeout_remote,
-                          context, 60, 0,
-                          SILC_TASK_TIMEOUT,
-                          SILC_TASK_PRI_LOW);
-
-      /* Register the connection for network input and output. This sets
-        that scheduler will listen for incoming packets for this connection 
-        and sets that outgoing packets may be sent to this connection as 
-        well. However, this doesn't set the scheduler for outgoing traffic,
-        it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
-        later when outgoing data is available. */
-      SILC_REGISTER_CONNECTION_FOR_IO(sock);
-      
-      /* Run the protocol */
-      protocol->execute(server->timeout_queue, 0, protocol, sock, 0, 0);
+      /* Allocate connection object for hold connection specific stuff. */
+      sconn = silc_calloc(1, sizeof(*sconn));
+      sconn->server = server;
+      sconn->remote_host = server->config->routers->host;
+      sconn->remote_port = server->config->routers->port;
+
+      silc_task_register(server->timeout_queue, fd, 
+                        silc_server_connect_router,
+                        (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
+                        SILC_TASK_PRI_NORMAL);
       return;
     }
   }
-  
-  /* if we are a SILC router we need to establish all of our primary
+
+  /* If we are a SILC router we need to establish all of our primary
      routes. */
   if (server->server_type == SILC_ROUTER) {
     SilcConfigServerSectionServerConnection *ptr;
 
+    SILC_LOG_DEBUG(("We are router"));
+
     /* Create the connections to all our routes */
     ptr = server->config->routers;
     while (ptr) {
-      SilcProtocol protocol;
-      SilcServerKEInternalContext *proto_ctx;
-
-      /* Create the connection to the remote end */
-      sock = silc_net_create_connection(ptr->port, ptr->host);
-      if (sock < 0) {
-       SILC_LOG_ERROR(("Could not connect to router"));
-       silc_schedule_stop();
-       return;
-      }
 
-      /* Set socket options */
-      silc_net_set_socket_nonblock(sock);
-      silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-
-      /* Create socket connection for the connection. Even though we
-        know that we are connecting to a router we will mark the socket
-        to be unknown connection until we have executed authentication
-        protocol. */
-      silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
-      server->sockets[sock] = newsocket;
-      newsocket->hostname = ptr->host;
-      newsocket->port = ptr->port;
-
-      /* Allocate internal protocol context. This is sent as context
-        to the protocol. */
-      proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
-      proto_ctx->server = context;
-      proto_ctx->sock = newsocket;
-      proto_ctx->rng = server->rng;
-      proto_ctx->responder = FALSE;
-      
-      /* Perform key exchange protocol. silc_server_connect_to_router_final
-        will be called after the protocol is finished. */
-      silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
-                         &protocol, proto_ctx,
-                         silc_server_connect_to_router_second);
-      newsocket->protocol = protocol;
-
-      /* Register a timeout task that will be executed if the protocol
-        is not executed within 60 seconds. For now, this is a hard coded 
-        limit. After 60 secs the connection will be closed if the key 
-        exchange protocol has not been executed. */
-      proto_ctx->timeout_task = 
-       silc_task_register(server->timeout_queue, sock, 
-                          silc_server_timeout_remote,
-                          context, 60, 0,
-                          SILC_TASK_TIMEOUT,
-                          SILC_TASK_PRI_LOW);
-
-      /* Register the connection for network input and output. This sets
-        that scheduler will listen for incoming packets for this connection 
-        and sets that outgoing packets may be sent to this connection as 
-        well. However, this doesn't set the scheduler for outgoing traffic,
-        it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
-        later when outgoing data is available. */
-      SILC_REGISTER_CONNECTION_FOR_IO(sock);
-      
-      /* Run the protocol */
-      protocol->execute(server->timeout_queue, 0, protocol, sock, 0, 0);
+      /* Allocate connection object for hold connection specific stuff. */
+      sconn = silc_calloc(1, sizeof(*sconn));
+      sconn->server = server;
+      sconn->remote_host = ptr->host;
+      sconn->remote_port = ptr->port;
+
+      silc_task_register(server->timeout_queue, fd, 
+                        silc_server_connect_router,
+                        (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
+                        SILC_TASK_PRI_NORMAL);
 
       if (!ptr->next)
        return;
@@ -521,14 +553,11 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router)
 
   /* Add a task to the queue. This task receives new connections to the 
      server. This task remains on the queue until the end of the program. */
-  if (silc_task_register(server->io_queue, fd, 
-                        silc_server_accept_new_connection,
-                        (void *)server, 0, 0, 
-                        SILC_TASK_FD,
-                        SILC_TASK_PRI_NORMAL) == NULL) {
-    silc_schedule_stop();
-    return;
-  }
+  silc_task_register(server->io_queue, fd, 
+                    silc_server_accept_new_connection,
+                    (void *)server, 0, 0, 
+                    SILC_TASK_FD,
+                    SILC_TASK_PRI_NORMAL);
 }
 
 /* Second part of connecting to router(s). Key exchange protocol has been
@@ -540,6 +569,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
   SilcServerKEInternalContext *ctx = 
     (SilcServerKEInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
+  SilcServerConnection sconn = (SilcServerConnection)ctx->context;
   SilcSocketConnection sock = NULL;
   SilcServerConnAuthInternalContext *proto_ctx;
 
@@ -565,6 +595,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
      is sent as context for the protocol. */
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->server = (void *)server;
+  proto_ctx->context = (void *)sconn;
   proto_ctx->sock = sock = server->sockets[fd];
   proto_ctx->ske = ctx->ske;      /* Save SKE object from previous protocol */
   proto_ctx->dest_id_type = ctx->dest_id_type;
@@ -633,6 +664,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   SilcServerConnAuthInternalContext *ctx = 
     (SilcServerConnAuthInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
+  SilcServerConnection sconn = (SilcServerConnection)ctx->context;
   SilcSocketConnection sock = ctx->sock;
   SilcServerEntry id_entry;
   SilcUnknownEntry conn_data;
@@ -660,16 +692,12 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   /* Add a task to the queue. This task receives new connections to the 
      server. This task remains on the queue until the end of the program. */
   if (!server->listenning) {
-    if (silc_task_register(server->io_queue, server->sock, 
-                          silc_server_accept_new_connection,
-                          (void *)server, 0, 0, 
-                          SILC_TASK_FD,
-                          SILC_TASK_PRI_NORMAL) == NULL) {
-      silc_schedule_stop();
-      return;
-    } else {
-      server->listenning = TRUE;
-    }
+    silc_task_register(server->io_queue, server->sock, 
+                      silc_server_accept_new_connection,
+                      (void *)server, 0, 0, 
+                      SILC_TASK_FD,
+                      SILC_TASK_PRI_NORMAL);
+    server->listenning = TRUE;
   }
 
   /* Send NEW_SERVER packet to the router. We will become registered
@@ -713,6 +741,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
     
   /* Free the temporary connection data context from key exchange */
   silc_free(conn_data);
+  if (sconn)
+    silc_free(sconn);
 
   /* Free the protocol object */
   silc_protocol_free(protocol);
@@ -2395,10 +2425,10 @@ int silc_server_client_on_channel(SilcClientEntry client,
 
 SILC_TASK_CALLBACK(silc_server_timeout_remote)
 {
-  SilcServer server = (SilcServer)context;
-  SilcSocketConnection sock = server->sockets[fd];
+  SilcServerConnection sconn = (SilcServerConnection)context;
+  SilcSocketConnection sock = sconn->server->sockets[fd];
 
-  silc_server_disconnect_remote(server, sock, 
+  silc_server_disconnect_remote(sconn->server, sock, 
                                "Server closed connection: "
                                "Connection timeout");
 }
index 41379eab36342905ccee30bce80c8503f9dbf17a..1e3dd56427fa40b92c6b2fa683db49805ec4b36a 100644 (file)
 /* Forward declaration for SILC Server object. The actual object is
    defined in internal header file for server routines. I want to keep
    the object private hence this declaration. */
-typedef struct SilcServerObjectStruct *SilcServer;
+typedef struct SilcServerStruct *SilcServer;
 
 #define SILC_SERVER_MAX_CONNECTIONS 10000
 
 /* General definitions */
 
+/* Server and router. Used internally by the code. */
 #define SILC_SERVER 0
 #define SILC_ROUTER 1
 
+/* Connection retry timeout. We implement exponential backoff algorithm
+   in connection retry. The interval of timeuot grows when retry count
+   grows. */
+#define SILC_SERVER_RETRY_COUNT        3        /* Max retry count */
+#define SILC_SERVER_RETRY_MULTIPLIER   7 / 4    /* Interval growth */
+#define SILC_SERVER_RETRY_RANDOMIZER   2        /* timeout += rnd % 2 */
+#define SILC_SERVER_RETRY_INTERVAL_MIN 2        /* Min retry timeout */
+#define SILC_SERVER_RETRY_INTERVAL_MAX 30       /* Max generated timeout */
+
+/* 
+   Silc Server Params.
+
+   Structure to hold various default parameters for server that can be
+   given before running the server. 
+
+*/
+typedef struct {
+  unsigned int retry_count;
+  unsigned long retry_interval_min;
+  unsigned long retry_interval_min_usec;
+  unsigned long retry_interval_max;
+  unsigned int retry_keep_trying;
+
+  unsigned long protocol_timeout;
+  unsigned long protocol_timeout_usec;
+} *SilcServerParams;
+
 /* Macros */
 
 /* This macro is used to send notify messages with formatted string. The
index e0c037e8f6a7c2267f18b4900a77f8c49f00c6f4..0b748b528947af6b9460b988eac75e630804ee26 100644 (file)
@@ -28,11 +28,27 @@ typedef struct {
 
 } 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.
 
 */
-typedef struct SilcServerObjectStruct {
+struct SilcServerStruct {
   char *server_name;
   int server_type;
   int sock;
@@ -81,11 +97,14 @@ typedef struct SilcServerObjectStruct {
   /* Server statistics */
   SilcServerStatistics stats;
 
+  /* Default parameteres for server */
+  SilcServerParams params;
+
 #ifdef SILC_SIM
   /* SIM (SILC Module) list */
   SilcDList sim;
 #endif
-} SilcServerObject;
+};
 
 /* Macros */
 
index 34985bad68c9f26444cd9a0084adde19ec183541..25c562f49df47c8f713b5d72637685432090bd94 100644 (file)
   GNU General Public License for more details.
 
 */
-/*
- * $Id$
- * $Log$
- * Revision 1.5  2000/11/02 22:15:23  priikone
- *     Some bugfixes.
- *     Changed server->sim to SilcDList and code accordingly.
- *     Changes SilcClientEntry->channel to SilcList and added
- *     back-pointer to SilcChannelClientEntry which is now used by both
- *     client entry and channel entry
- *
- * Revision 1.4  2000/10/06 08:10:23  priikone
- *     Added WHOIS to send multiple replies if multiple nicknames are
- *     found.
- *     Added MOTD command and [motd] config section and server also sends
- *     motd to client on connection now.
- *     Fixed TOPIC command some more.
- *
- * Revision 1.3  2000/07/10 05:41:20  priikone
- *     Added missing token to administrative information.
- *
- * Revision 1.2  2000/07/05 06:14:01  priikone
- *     Global costemic changes.
- *
- * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
- *     Imported from internal CVS/Added Log headers.
- *
- *
- */
+/* $Id$ */
 
 #include "serverincludes.h"
 #include "server_internal.h"
index 8d444563233f65b4783219fa1a5fcc583f544fe4..bf4d2408af814e94ed459d4349f434d6eaa4f899 100644 (file)
@@ -22,9 +22,9 @@ lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1334
 10.2.1.6:10.2.1.6:1334
 
 [Logging]
-infologfile:silcd.log:10000
+infologfile:silcd2.log:10000
 #warninglogfile:/var/log/silcd_warning.log:10000
-errorlogfile:silcd2_error.log:10000
+errorlogfile:silcd2.log:10000
 #fatallogfile:/var/log/silcd_error.log:
 
 [ConnectionClass]
@@ -34,14 +34,17 @@ errorlogfile:silcd2_error.log:10000
 [ClientConnection]
 10.2.1.199:passwd:priikone:333:1
 :::1333:1
+:::1334:1
+:::1335:1
 
 [AdminConnection]
 10.2.1.199:passwd:priikone:priikone:1
 
 [ServerConnection]
+10.2.1.6:passwd:priikone:1335:1:1
 
 [RouterConnection]
-10.2.1.6:passwd:priikone:1333:1:1
+#10.2.1.6:passwd:priikone:1333:1:1
 
 [DenyConnection]
 [RedirectClient]