updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 17 Apr 2001 22:17:01 +0000 (22:17 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 17 Apr 2001 22:17:01 +0000 (22:17 +0000)
CHANGES
TODO
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/protocol.c
apps/silcd/protocol.h
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/serverconfig.h
lib/silcutil/silcnet.c
lib/silcutil/silcnet.h

diff --git a/CHANGES b/CHANGES
index a03d3512eeb97d71ffeb3a8d934983490cf78721..939fa274c390a471d81f97e750e2507ee33fba5a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,54 @@
+Tue Apr 17 21:18:19 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Fixed the [AdminConnection] server config section to support
+         multiple entries.  Affected file silcd/serverconfig.c.
+
+       * Added support into the server to check the validity of the
+         incoming connection before executing any KE or authentication
+         protocols.
+
+       * The connection configuration is now saved to the KE and 
+         connection auth protocol contexts and not fetched anymore in 
+         the protocol.  Affected files silcd/server.c, silcd/protocol.[ch].
+
+       * The local hosts listenning address and port is also resolved
+         now when starting the server.  We want to have the socket object
+         to include the real address and port for the listener.  Added
+         new function silc_net_check_local_by_sock into the files
+         lib/silcutil/silcnet.[ch].
+
+       * Fixed a broadcast bug in server -> do not broadcast if we
+         are standalone.
+
+       * Fixed a routing bug.  Do not route broadcast packets ever.
+         Broadcast packets must be processed always and not routed since
+         they may be destined to some other host than yourself and thus
+         would get routed without no good reason.  Affected file is
+         silcd/server.c.
+
+       * Added function silc_server_config_is_primary_route to check
+         whether primary router connection has been configured (a router
+         configuration that we are initiating).  If there is not, we 
+         will assume that there is only two routers in the SILC network
+         and we will use the incoming router connection as our primary
+         route.  Affected files silcd/serverconfig.[ch], silcd/server.c.
+
+       * Changed the order of the broadcasting.  Broadcast _after_ the
+         packet has been processed not before.  Affected file is
+         silcd/server.c.
+
+       * Fixed a [ClientConnection] parsing bug.  The port was never
+         parsed correctly thus resulting to port 0.  Affected file
+         silcd/serverconfig.c.
+
+       * Fixed silc_server_send_notify_args -> it ignored the `broadcast'
+         argument and did not set the broadcast packet flag.  Affected
+         file silcd/packet_send.c.  Fixed same bug in the function
+         silc_server_send_notify as well.
+
+       * If we receive NEW_ID packet for our own ID in the server, ignore
+         the packet.
+
 Mon Apr 16 12:10:33 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Updated TODO.
 Mon Apr 16 12:10:33 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Updated TODO.
diff --git a/TODO b/TODO
index bed19134bf67c043651f892329e30cd7e448b721..658383a98394d71942e8ed905c37073e9a4b054f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -48,9 +48,6 @@ TODO/bugs In SILC Server
    own resolver stuff (through scheduler, if possible without writing
    too much own stuff) or use threads.
 
    own resolver stuff (through scheduler, if possible without writing
    too much own stuff) or use threads.
 
- o [AdminConnection] config section does not work correctly, it takes
-   only one entry and ignores the other -> authentication fails.
-
  o [DenyConnection] config section is not implemented.
 
  o The backup router support described in the protocol specification
  o [DenyConnection] config section is not implemented.
 
  o The backup router support described in the protocol specification
index e5669d7eb2255721a36ecdb4bf639c3f58649abe..b6caf4ef916e8411bf18be47e9b313c13ed611dc 100644 (file)
@@ -1601,11 +1601,17 @@ static void silc_server_new_id_real(SilcServer server,
     break;
 
   case SILC_ID_SERVER:
     break;
 
   case SILC_ID_SERVER:
+    /* If the ID is mine, ignore it. */
+    if (!SILC_ID_SERVER_COMPARE(id, server->id)) {
+      SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
+      break;
+    }
+
     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
                    silc_id_render(id, SILC_ID_SERVER),
                    sock->type == SILC_SOCKET_TYPE_SERVER ?
                    "Server" : "Router", sock->hostname));
     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
                    silc_id_render(id, SILC_ID_SERVER),
                    sock->type == SILC_SOCKET_TYPE_SERVER ?
                    "Server" : "Router", sock->hostname));
-    
+
     /* As a router we keep information of all global information in our global
        list. Cell wide information however is kept in the local list. */
     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
     /* As a router we keep information of all global information in our global
        list. Cell wide information however is kept in the local list. */
     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
index c64ef04b381166ce96d777c515e98352e7d23980..00f30978c09d8859453afcd03feb1e792c068344 100644 (file)
@@ -866,7 +866,8 @@ void silc_server_send_notify(SilcServer server,
   va_start(ap, argc);
 
   packet = silc_notify_payload_encode(type, argc, ap);
   va_start(ap, argc);
 
   packet = silc_notify_payload_encode(type, argc, ap);
-  silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 0, 
+  silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 
+                         broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
                          packet->data, packet->len, FALSE);
   silc_buffer_free(packet);
 }
                          packet->data, packet->len, FALSE);
   silc_buffer_free(packet);
 }
@@ -884,7 +885,8 @@ void silc_server_send_notify_args(SilcServer server,
   SilcBuffer packet;
 
   packet = silc_notify_payload_encode_args(type, argc, args);
   SilcBuffer packet;
 
   packet = silc_notify_payload_encode_args(type, argc, args);
-  silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 0, 
+  silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 
+                         broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
                          packet->data, packet->len, FALSE);
   silc_buffer_free(packet);
 }
                          packet->data, packet->len, FALSE);
   silc_buffer_free(packet);
 }
index a13d193c4f89948bc0c84fcc83c835148bb55876..10e74a9d14dffe960661bfd90407f1d6809cccb1 100644 (file)
@@ -665,14 +665,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
 
        /* Remote end is client */
        if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
 
        /* Remote end is client */
        if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
-         SilcServerConfigSectionClientConnection *client = NULL;
-         client = silc_server_config_find_client_conn(server->config,
-                                                      ctx->sock->ip,
-                                                      ctx->sock->port);
-         if (!client)
-           client = silc_server_config_find_client_conn(server->config,
-                                                        ctx->sock->hostname,
-                                                        ctx->sock->port);
+         SilcServerConfigSectionClientConnection *client = ctx->config;
          
          if (client) {
            switch(client->auth_meth) {
          
          if (client) {
            switch(client->auth_meth) {
@@ -734,15 +727,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        
        /* Remote end is server */
        if (conn_type == SILC_SOCKET_TYPE_SERVER) {
        
        /* Remote end is server */
        if (conn_type == SILC_SOCKET_TYPE_SERVER) {
-         SilcServerConfigSectionServerConnection *serv = NULL;
-         serv = silc_server_config_find_server_conn(server->config,
-                                                    ctx->sock->ip,
-                                                    ctx->sock->port);
-         if (!serv)
-           serv = silc_server_config_find_server_conn(server->config,
-                                                      ctx->sock->hostname,
-                                                      ctx->sock->port);
-
+         SilcServerConfigSectionServerConnection *serv = ctx->config;
+         
          if (serv) {
            switch(serv->auth_meth) {
            case SILC_AUTH_NONE:
          if (serv) {
            switch(serv->auth_meth) {
            case SILC_AUTH_NONE:
@@ -803,15 +789,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        
        /* Remote end is router */
        if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
        
        /* Remote end is router */
        if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
-         SilcServerConfigSectionServerConnection *serv = NULL;
-         serv = silc_server_config_find_router_conn(server->config,
-                                                    ctx->sock->ip,
-                                                    ctx->sock->port);
-         if (!serv)
-           serv = silc_server_config_find_router_conn(server->config,
-                                                      ctx->sock->hostname,
-                                                      ctx->sock->port);
-         
+         SilcServerConfigSectionServerConnection *serv = ctx->config;
+
          if (serv) {
            switch(serv->auth_meth) {
            case SILC_AUTH_NONE:
          if (serv) {
            switch(serv->auth_meth) {
            case SILC_AUTH_NONE:
index 99f2e72071b423b69c57e1c5b930d731c3375158..f5ab3c5b2a48d764ad2bd3f0b0d9603c9e72133a 100644 (file)
@@ -43,6 +43,9 @@ typedef struct {
   void *dest_id;
   SilcIdType dest_id_type;
 
   void *dest_id;
   SilcIdType dest_id_type;
 
+  /* Pointer to the configuration. */
+  void *config;
+
   SilcTask timeout_task;
   SilcPacketContext *packet;
   SilcSKE ske;
   SilcTask timeout_task;
   SilcPacketContext *packet;
   SilcSKE ske;
@@ -76,6 +79,9 @@ typedef struct {
   void *dest_id;
   SilcIdType dest_id_type;
 
   void *dest_id;
   SilcIdType dest_id_type;
 
+  /* Pointer to the configuration. */
+  void *config;
+
   SilcTask timeout_task;
   SilcPacketContext *packet;
   uint16 conn_type;
   SilcTask timeout_task;
   SilcPacketContext *packet;
   uint16 conn_type;
index 288a5734384f20ba2bc07b60b1c83957c431eba9..7a88cad30610d813ca94849c8330c06649ee582c 100644 (file)
@@ -239,6 +239,23 @@ int silc_server_init(SilcServer server)
                      &newsocket);
 
     server->sockets[sock[i]] = newsocket;
                      &newsocket);
 
     server->sockets[sock[i]] = newsocket;
+    
+    /* Perform name and address lookups to resolve the listenning address
+       and port. */
+    if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname, 
+                                    &newsocket->ip)) {
+      if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
+         !newsocket->ip) {
+       SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
+                       newsocket->hostname ? newsocket->hostname :
+                       newsocket->ip ? newsocket->ip : ""));
+       server->stat.conn_failures++;
+       goto err0;
+      }
+      if (!newsocket->hostname)
+       newsocket->hostname = strdup(newsocket->ip);
+    }
+    newsocket->port = silc_net_get_local_port(sock[i]);
 
     /* Put the allocated socket pointer also to the entry allocated above 
        for fast back-referencing to the socket list. */
 
     /* Put the allocated socket pointer also to the entry allocated above 
        for fast back-referencing to the socket list. */
@@ -929,7 +946,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
   SilcServer server = (SilcServer)context;
   SilcSocketConnection newsocket;
   SilcServerKEInternalContext *proto_ctx;
   SilcServer server = (SilcServer)context;
   SilcSocketConnection newsocket;
   SilcServerKEInternalContext *proto_ctx;
-  int sock;
+  int sock, port;
+  void *config;
 
   SILC_LOG_DEBUG(("Accepting new connection"));
 
 
   SILC_LOG_DEBUG(("Accepting new connection"));
 
@@ -977,6 +995,45 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
   }
   newsocket->port = silc_net_get_remote_port(sock);
 
   }
   newsocket->port = silc_net_get_remote_port(sock);
 
+  /* 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);
+
+  /* Check whether we have configred this sort of connection at all. We
+     have to check all configurations since we don't know what type of
+     connection this is. */
+  port = server->sockets[fd]->port; /* Listenning port */
+  if (!(config = silc_server_config_find_client_conn(server->config,
+                                                    newsocket->ip, port)))
+    if (!(config = silc_server_config_find_client_conn(server->config,
+                                                      newsocket->hostname, 
+                                                      port)))
+      if (!(config = silc_server_config_find_server_conn(server->config,
+                                                        newsocket->ip, 
+                                                        port)))
+       if (!(config = silc_server_config_find_server_conn(server->config,
+                                                          newsocket->hostname,
+                                                          port)))
+         if (!(config = 
+               silc_server_config_find_router_conn(server->config,
+                                                   newsocket->ip, port)))
+           if (!(config = 
+                 silc_server_config_find_router_conn(server->config,
+                                                     newsocket->hostname, 
+                                                     port))) {
+             silc_server_disconnect_remote(server, newsocket, 
+                                           "Server closed connection: "
+                                           "Connection refused");
+             server->stat.conn_failures++;
+             return;
+           }
+
+  /* The connection is allowed */
+
   SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
                 newsocket->ip));
 
   SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
                 newsocket->ip));
 
@@ -987,6 +1044,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
   proto_ctx->sock = newsocket;
   proto_ctx->rng = server->rng;
   proto_ctx->responder = TRUE;
   proto_ctx->sock = newsocket;
   proto_ctx->rng = server->rng;
   proto_ctx->responder = TRUE;
+  proto_ctx->config = config;
 
   /* Prepare the connection for key exchange protocol. We allocate the
      protocol but will not start it yet. The connector will be the
 
   /* Prepare the connection for key exchange protocol. We allocate the
      protocol but will not start it yet. The connector will be the
@@ -1007,14 +1065,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
                       context, 60, 0,
                       SILC_TASK_TIMEOUT,
                       SILC_TASK_PRI_LOW);
                       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);
 }
 
 /* Second part of accepting new connection. Key exchange protocol has been
 }
 
 /* Second part of accepting new connection. Key exchange protocol has been
@@ -1093,6 +1143,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
   proto_ctx->responder = TRUE;
   proto_ctx->dest_id_type = ctx->dest_id_type;
   proto_ctx->dest_id = ctx->dest_id;
   proto_ctx->responder = TRUE;
   proto_ctx->dest_id_type = ctx->dest_id_type;
   proto_ctx->dest_id = ctx->dest_id;
+  proto_ctx->config = ctx->config;
 
   /* Free old protocol as it is finished now */
   silc_protocol_free(protocol);
 
   /* Free old protocol as it is finished now */
   silc_protocol_free(protocol);
@@ -1192,6 +1243,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
   case SILC_SOCKET_TYPE_ROUTER:
     {
       SilcServerEntry new_server;
   case SILC_SOCKET_TYPE_ROUTER:
     {
       SilcServerEntry new_server;
+      SilcServerConfigSectionServerConnection *conn = ctx->config;
 
       SILC_LOG_DEBUG(("Remote host is %s", 
                      sock->type == SILC_SOCKET_TYPE_SERVER ? 
 
       SILC_LOG_DEBUG(("Remote host is %s", 
                      sock->type == SILC_SOCKET_TYPE_SERVER ? 
@@ -1224,12 +1276,14 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
       server->stat.servers++;
 
       id_entry = (void *)new_server;
       server->stat.servers++;
 
       id_entry = (void *)new_server;
-      
-      /* There is connection to other server now, if it is router then
-        we will have connection to outside world.  If we are router but
-        normal server connected to us then we will remain standalone,
-        if we are standlone. */
+
+      /* Check whether this connection is to be our primary router connection
+        if we dont' already have the primary route. */
       if (server->standalone && sock->type == SILC_SOCKET_TYPE_ROUTER) {
       if (server->standalone && sock->type == SILC_SOCKET_TYPE_ROUTER) {
+       if (silc_server_config_is_primary_route(server->config) &&
+           !conn->initiator)
+         break;
+
        SILC_LOG_DEBUG(("We are not standalone server anymore"));
        server->standalone = FALSE;
        if (!server->id_entry->router) {
        SILC_LOG_DEBUG(("We are not standalone server anymore"));
        server->standalone = FALSE;
        if (!server->id_entry->router) {
@@ -1237,6 +1291,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
          server->router = id_entry;
        }
       }
          server->router = id_entry;
        }
       }
+
       break;
     }
   default:
       break;
     }
   default:
@@ -1473,7 +1528,8 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
   if (server->server_type == SILC_ROUTER) {
     /* Route the packet if it is not destined to us. Other ID types but
        server are handled separately after processing them. */
   if (server->server_type == SILC_ROUTER) {
     /* Route the packet if it is not destined to us. Other ID types but
        server are handled separately after processing them. */
-    if (packet->dst_id_type == SILC_ID_SERVER && 
+    if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
+       packet->dst_id_type == SILC_ID_SERVER && 
        sock->type != SILC_SOCKET_TYPE_CLIENT &&
        SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
       
        sock->type != SILC_SOCKET_TYPE_CLIENT &&
        SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
       
@@ -1489,18 +1545,21 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
       silc_free(id);
       goto out;
     }
       silc_free(id);
       goto out;
     }
-    
+  }
+
+  /* Parse the incoming packet type */
+  silc_server_packet_parse_type(server, sock, packet);
+
+  if (server->server_type == SILC_ROUTER) {
     /* Broadcast packet if it is marked as broadcast packet and it is
        originated from router and we are router. */
     if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
     /* Broadcast packet if it is marked as broadcast packet and it is
        originated from router and we are router. */
     if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
-       packet->flags & SILC_PACKET_FLAG_BROADCAST) {
+       packet->flags & SILC_PACKET_FLAG_BROADCAST &&
+       !server->standalone) {
       silc_server_packet_broadcast(server, server->router->connection, packet);
     }
   }
 
       silc_server_packet_broadcast(server, server->router->connection, packet);
     }
   }
 
-  /* Parse the incoming packet type */
-  silc_server_packet_parse_type(server, sock, packet);
-
  out:
   /*  silc_buffer_clear(sock->inbuf); */
   silc_packet_context_free(packet);
  out:
   /*  silc_buffer_clear(sock->inbuf); */
   silc_packet_context_free(packet);
@@ -2334,8 +2393,8 @@ int silc_server_remove_clients_by_server(SilcServer server,
                                          argv_types);
       silc_server_send_notify_args(server, 
                                   server->router->connection,
                                          argv_types);
       silc_server_send_notify_args(server, 
                                   server->router->connection,
-                                  server->server_type == 
-                                  SILC_SERVER ? FALSE : TRUE, 
+                                  server->server_type == SILC_SERVER ? 
+                                  FALSE : TRUE, 
                                   SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
                                   argc, args);
       silc_buffer_free(args);
                                   SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
                                   argc, args);
       silc_buffer_free(args);
index 1a9abdf33eeb53b57eea533afc0b3ab0cb358149..d099e7dda8a6d93945bf56542d6029705eb349af 100644 (file)
@@ -760,7 +760,7 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       ret = silc_config_get_token(line, &tmp);
       if (ret < 0)
        break;
       ret = silc_config_get_token(line, &tmp);
       if (ret < 0)
        break;
-      if (ret == 0) {
+      if (ret) {
        config->clients->port = atoi(tmp);
        silc_free(tmp);
       }
        config->clients->port = atoi(tmp);
        silc_free(tmp);
       }
@@ -1106,6 +1106,8 @@ int silc_server_config_parse_lines(SilcServerConfig config,
     config->clients = config->clients->prev;
   while (config->servers && config->servers->prev)
     config->servers = config->servers->prev;
     config->clients = config->clients->prev;
   while (config->servers && config->servers->prev)
     config->servers = config->servers->prev;
+  while (config->admins && config->admins->prev)
+    config->admins = config->admins->prev;
   while (config->routers && config->routers->prev)
     config->routers = config->routers->prev;
   
   while (config->routers && config->routers->prev)
     config->routers = config->routers->prev;
   
@@ -1422,7 +1424,8 @@ void silc_server_config_register_hmacs(SilcServerConfig config)
 }
 
 /* Returns client authentication information from server configuration
 }
 
 /* Returns client authentication information from server configuration
-   by host (name or ip). */
+   by host (name or ip). If `port' is non-null then both name or IP and 
+   the port must match. */
 
 SilcServerConfigSectionClientConnection *
 silc_server_config_find_client_conn(SilcServerConfig config, 
 
 SilcServerConfigSectionClientConnection *
 silc_server_config_find_client_conn(SilcServerConfig config, 
@@ -1430,6 +1433,7 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionClientConnection *client = NULL;
 {
   int i;
   SilcServerConfigSectionClientConnection *client = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
 
   if (!host)
     return NULL;
@@ -1441,7 +1445,14 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 
   for (i = 0; client; i++) {
     if (silc_string_compare(client->host, host))
 
   for (i = 0; client; i++) {
     if (silc_string_compare(client->host, host))
+      match = TRUE;
+
+    if (port && client->port != port)
+      match = FALSE;
+
+    if (match)
       break;
       break;
+
     client = client->next;
   }
 
     client = client->next;
   }
 
@@ -1452,7 +1463,8 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 }
 
 /* Returns server connection info from server configuartion by host 
 }
 
 /* Returns server connection info from server configuartion by host 
-   (name or ip). */
+   (name or ip). If `port' is non-null then both name or IP and the port
+   must match. */
 
 SilcServerConfigSectionServerConnection *
 silc_server_config_find_server_conn(SilcServerConfig config, 
 
 SilcServerConfigSectionServerConnection *
 silc_server_config_find_server_conn(SilcServerConfig config, 
@@ -1460,6 +1472,7 @@ silc_server_config_find_server_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
 
   if (!host)
     return NULL;
@@ -1470,7 +1483,14 @@ silc_server_config_find_server_conn(SilcServerConfig config,
   serv = config->servers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
   serv = config->servers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
+      match = TRUE;
+
+    if (port && serv->port != port)
+      match = FALSE;
+
+    if (match)
       break;
       break;
+
     serv = serv->next;
   }
 
     serv = serv->next;
   }
 
@@ -1489,6 +1509,7 @@ silc_server_config_find_router_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
 
   if (!host)
     return NULL;
@@ -1499,7 +1520,14 @@ silc_server_config_find_router_conn(SilcServerConfig config,
   serv = config->routers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
   serv = config->routers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
+      match = TRUE;
+
+    if (port && serv->port != port)
+      match = FALSE;
+
+    if (match)
       break;
       break;
+
     serv = serv->next;
   }
 
     serv = serv->next;
   }
 
@@ -1509,6 +1537,28 @@ silc_server_config_find_router_conn(SilcServerConfig config,
   return serv;
 }
 
   return serv;
 }
 
+/* Returns TRUE if configuartion for a router connection that we are 
+   initiating exists. */
+
+bool silc_server_config_is_primary_route(SilcServerConfig config)
+{
+  int i;
+  SilcServerConfigSectionServerConnection *serv = NULL;
+  bool found = FALSE;
+
+  serv = config->routers;
+  for (i = 0; serv; i++) {
+    if (serv->initiator == TRUE) {
+      found = TRUE;
+      break;
+    }
+
+    serv = serv->next;
+  }
+
+  return found;
+}
+
 /* Returns Admin connection configuration by host, username and/or 
    nickname. */
 
 /* Returns Admin connection configuration by host, username and/or 
    nickname. */
 
index 885c32eb7d531de36d36325fa1b4f7b51c3e1316..5b6c3aa92414b292bd95cae1e4dfc8eda5901edc 100644 (file)
@@ -131,7 +131,7 @@ typedef struct SilcServerConfigSectionServerConnectionStruct {
   uint16 port;
   char *version;
   uint32 class;
   uint16 port;
   char *version;
   uint32 class;
-  int initiator;
+  bool initiator;
   struct SilcServerConfigSectionServerConnectionStruct *next;
   struct SilcServerConfigSectionServerConnectionStruct *prev;
 } SilcServerConfigSectionServerConnection;
   struct SilcServerConfigSectionServerConnectionStruct *next;
   struct SilcServerConfigSectionServerConnectionStruct *prev;
 } SilcServerConfigSectionServerConnection;
@@ -269,6 +269,7 @@ silc_server_config_find_server_conn(SilcServerConfig config,
 SilcServerConfigSectionServerConnection *
 silc_server_config_find_router_conn(SilcServerConfig config, 
                                    char *host, int port);
 SilcServerConfigSectionServerConnection *
 silc_server_config_find_router_conn(SilcServerConfig config, 
                                    char *host, int port);
+bool silc_server_config_is_primary_route(SilcServerConfig config);
 SilcServerConfigSectionAdminConnection *
 silc_server_config_find_admin(SilcServerConfig config,
                              char *host, char *username, char *nickname);
 SilcServerConfigSectionAdminConnection *
 silc_server_config_find_admin(SilcServerConfig config,
                              char *host, char *username, char *nickname);
index 71fd0667394add250c398e0461b1172690db5657..0f240b7c9c1fa51639b9d72ba16ebbcc516d6bcf 100644 (file)
@@ -299,6 +299,71 @@ bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
   return TRUE;
 }
 
   return TRUE;
 }
 
+/* Performs lookups for local name and IP address. This peforms reverse
+   lookup as well to verify that the IP has FQDN. */
+
+bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
+{
+  struct sockaddr_in local;
+  struct hostent *dest;
+  char *host_ip = NULL;
+  char host_name[1024];
+  int rval, len;
+  int i;
+
+  *hostname = NULL;
+  *ip = NULL;
+
+  SILC_LOG_DEBUG(("Resolving local hostname and IP address"));
+
+  memset(&local, 0, sizeof(local));
+  len = sizeof(local);
+  rval = getsockname(sock, (struct sockaddr *)&local, &len);
+  if (rval < 0)
+    return FALSE;
+
+  host_ip = inet_ntoa(local.sin_addr);
+  if (!host_ip)
+    return FALSE;
+
+  *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
+  memcpy(*ip, host_ip, strlen(host_ip));
+
+  /* Get host by address */
+  dest = gethostbyaddr((char *)&local.sin_addr, 
+                      sizeof(struct in_addr), AF_INET);
+  if (!dest)
+    return FALSE;
+
+  /* Get same host by name to see that the local host really is
+     the who it says it is */
+  memset(host_name, 0, sizeof(host_name));
+  memcpy(host_name, dest->h_name, strlen(dest->h_name));
+
+  *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char));
+  memcpy(*hostname, host_name, strlen(host_name));
+  SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
+
+  dest = gethostbyname(host_name);
+  if (!dest)
+    return FALSE;
+
+  /* Find the address from list */
+  for (i = 0; dest->h_addr_list[i]; i++)
+    if (!memcmp(dest->h_addr_list[i], &local.sin_addr, 
+              sizeof(struct in_addr)))
+      break;
+  if (!dest->h_addr_list[i])
+    return FALSE;
+
+  silc_free(*ip);
+  *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
+  memcpy(*ip, host_ip, strlen(host_ip));
+  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
+
+  return TRUE;
+}
+
 /* Return remote port by socket. */
 
 uint16 silc_net_get_remote_port(int sock)
 /* Return remote port by socket. */
 
 uint16 silc_net_get_remote_port(int sock)
index 8445d1413138cf1050bdd1e72613d951ef075cf3..7522e5a1b2c244fd5c0d43f12ebd79d81cba2393 100644 (file)
@@ -32,6 +32,7 @@ int silc_net_set_socket_nonblock(int sock);
 int silc_net_set_socket_opt(int sock, int level, int option, int on);
 int silc_net_is_ip(const char *addr);
 bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip);
 int silc_net_set_socket_opt(int sock, int level, int option, int on);
 int silc_net_is_ip(const char *addr);
 bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip);
+bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip);
 uint16 silc_net_get_remote_port(int sock);
 uint16 silc_net_get_local_port(int sock);
 char *silc_net_localhost();
 uint16 silc_net_get_remote_port(int sock);
 uint16 silc_net_get_local_port(int sock);
 char *silc_net_localhost();