updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 19 Feb 2001 14:49:33 +0000 (14:49 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 19 Feb 2001 14:49:33 +0000 (14:49 +0000)
CHANGES
apps/silc/silc.c
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/server.c
lib/silcclient/command.c

diff --git a/CHANGES b/CHANGES
index 2b5c1b283771a8e620fe86a9bbad00984ed4e697..c5b8a54f84be56e9573031fb11b8ed52df87b048 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,27 @@ Mon Feb 19 14:26:49 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
          in command sending and with pending commands.  The affected file
          is silcd/idlist.h.
 
+       * Added reference counter to the SilcSocketConnection objecet to
+         indicate the usage count of the object.  The object won't be
+         freed untill the reference counter hits zero.  Currently only
+         server uses this, and client ignores it.  The client must be
+         set to use this too later.  The affected files are
+         lib/silccore/silcsockconn.[ch].  Added also the function
+         silc_socket_dup to increase the reference counter.
+
+         This was mainly added because it is possible that the socket
+         is removed underneath of pending command or other async
+         operation.  Now it won't be free'd and proper DISCONNECTING
+         flags, etc. can be set to avoid sending data to connection that
+         is not valid anymore.
+
+       * Added SILC_SET_DISCONNECTING to server.c when EOF is read from
+         the connection.  After that it sets SILC_SET_DISCONNECTED.
+         It is, however, possible that the socket data is not still freed.
+         The silc_server_packet_process now checks that data is not
+         read or written to connection that is DISCONNECTED.  The socket
+         get's freed when the reference counter hits zero.
+
 Mon Feb 19 00:50:57 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Changed the client operation API: channel_message operation's
index 6a766e5750216c7889efd33c2114818341f211e3..60aa56633075d30a8a8bb96dce7ba7a90761682f 100644 (file)
@@ -546,7 +546,7 @@ static void silc_client_process_message(SilcClientInternal app)
 
     /* Allocate command context. This and its internals must be free'd 
        by the command routine receiving it. */
-    ctx = silc_calloc(1, sizeof(*ctx));
+    ctx = silc_client_command_alloc();
     ctx->client = app->client;
     ctx->conn = app->conn;
     ctx->command = cmd;
@@ -560,7 +560,7 @@ static void silc_client_process_message(SilcClientInternal app)
 
   } else {
     /* Normal message to a channel */
-    if (len && app->conn->current_channel &&
+    if (len && app->conn && app->conn->current_channel &&
        app->conn->current_channel->on_channel == TRUE) {
       silc_print(app->client, "> %s", data);
       silc_client_packet_send_to_channel(app->client, 
index b018eaa12f22e6fc742ecc87b6687ae86eaf1479..94d172e427b3c4994606f50ccab3d6866c3cb60b 100644 (file)
@@ -152,7 +152,7 @@ void silc_server_command_process(SilcServer server,
      command routine receiving it. */
   ctx = silc_server_command_alloc();
   ctx->server = server;
-  ctx->sock = sock;
+  ctx->sock = silc_socket_dup(sock);
   ctx->packet = silc_packet_context_dup(packet); /* Save original packet */
   
   /* Parse the command payload in the packet */
@@ -209,6 +209,8 @@ void silc_server_command_free(SilcServerCommandContext ctx)
       silc_command_free_payload(ctx->payload);
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
+    if (ctx->sock)
+      silc_socket_free(ctx->sock); /* Decrease reference counter */
     silc_free(ctx);
   }
 }
@@ -566,7 +568,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
   }
 }
 
-static void
+static int
 silc_server_command_whois_from_client(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
@@ -575,7 +577,7 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   SilcClientEntry *clients = NULL, entry;
   SilcClientID **client_id = NULL;
   unsigned int client_id_count = 0;
-  int i;
+  int i, ret = 0;
 
   /* Protocol dictates that we must always send the received WHOIS request
      to our router if we are normal server, so let's do it now unless we
@@ -607,6 +609,7 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
     silc_command_set_ident(cmd->payload, old_ident);
 
     silc_buffer_free(tmpbuf);
+    ret = -1;
     goto out;
   }
 
@@ -617,7 +620,7 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count, 
                                       &nick, &server_name, &count,
                                       SILC_COMMAND_WHOIS))
-    return;
+    return 0;
 
   /* Get all clients matching that ID or nickname from local list */
   if (client_id_count) {
@@ -678,8 +681,10 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
      mandatory fields that WHOIS command reply requires. Check for these and
      make query from the server who owns the client if some fields are 
      missing. */
-  if (!silc_server_command_whois_check(cmd, clients, clients_count))
+  if (!silc_server_command_whois_check(cmd, clients, clients_count)) {
+    ret = -1;
     goto out;
+  }
 
   /* Send the command reply to the client */
   silc_server_command_whois_send_reply(cmd, clients, clients_count);
@@ -696,9 +701,11 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
     silc_free(nick);
   if (server_name)
     silc_free(server_name);
+
+  return ret;
 }
 
-static void
+static int
 silc_server_command_whois_from_server(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
@@ -707,13 +714,13 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
   SilcClientEntry *clients = NULL, entry;
   SilcClientID **client_id = NULL;
   unsigned int client_id_count = 0;
-  int i;
+  int i, ret = 0;
 
   /* Parse the whois request */
   if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count, 
                                       &nick, &server_name, &count,
                                       SILC_COMMAND_WHOIS))
-    return;
+    return 0;
 
   /* Process the command request. Let's search for the requested client and
      send reply to the requesting server. */
@@ -784,8 +791,10 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
      mandatory fields that WHOIS command reply requires. Check for these and
      make query from the server who owns the client if some fields are 
      missing. */
-  if (!silc_server_command_whois_check(cmd, clients, clients_count))
+  if (!silc_server_command_whois_check(cmd, clients, clients_count)) {
+    ret = -1;
     goto out;
+  }
 
   /* Send the command reply to the client */
   silc_server_command_whois_send_reply(cmd, clients, clients_count);
@@ -802,6 +811,8 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
     silc_free(nick);
   if (server_name)
     silc_free(server_name);
+
+  return ret;
 }
 
 /* Server side of command WHOIS. Processes user's query and sends found 
@@ -810,15 +821,18 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
 SILC_SERVER_CMD_FUNC(whois)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+  int ret = 0;
 
   SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_WHOIS, cmd, 1, 3328);
 
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
-    silc_server_command_whois_from_client(cmd);
-  else
-    silc_server_command_whois_from_server(cmd);
+    ret = silc_server_command_whois_from_client(cmd);
+  else if ((cmd->sock->type == SILC_SOCKET_TYPE_SERVER) ||
+          (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER))
+    ret = silc_server_command_whois_from_server(cmd);
 
-  silc_server_command_free(cmd);
+  if (!ret)
+    silc_server_command_free(cmd);
 }
 
 SILC_SERVER_CMD_FUNC(whowas)
@@ -966,7 +980,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
   }
 }
 
-static void
+static int
 silc_server_command_identify_from_client(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
@@ -975,7 +989,7 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   SilcClientEntry *clients = NULL, entry;
   SilcClientID **client_id = NULL;
   unsigned int client_id_count = 0;
-  int i;
+  int i, ret = 0;
 
   /* Protocol dictates that we must always send the received IDENTIFY request
      to our router if we are normal server, so let's do it now unless we
@@ -1007,6 +1021,7 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
     silc_command_set_ident(cmd->payload, old_ident);
 
     silc_buffer_free(tmpbuf);
+    ret = -1;
     goto out;
   }
 
@@ -1017,7 +1032,7 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
                                       &nick, &server_name, &count,
                                       SILC_COMMAND_IDENTIFY))
-    return;
+    return 0;
 
   /* Get all clients matching that ID or nickname from local list */
   if (client_id_count) { 
@@ -1075,8 +1090,10 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
 
   /* Check that all mandatory fields are present and request those data
      from the server who owns the client if necessary. */
-  if (!silc_server_command_identify_check(cmd, clients, clients_count))
+  if (!silc_server_command_identify_check(cmd, clients, clients_count)) {
+    ret = -1;
     goto out;
+  }
 
   /* Send the command reply to the client */
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
@@ -1093,9 +1110,11 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
     silc_free(nick);
   if (server_name)
     silc_free(server_name);
+
+  return ret;
 }
 
-static void
+static int
 silc_server_command_identify_from_server(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
@@ -1104,13 +1123,13 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
   SilcClientEntry *clients = NULL, entry;
   SilcClientID **client_id = NULL;
   unsigned int client_id_count = 0;
-  int i;
+  int i, ret = 0;
 
   /* Parse the IDENTIFY request */
   if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
                                       &nick, &server_name, &count,
                                       SILC_COMMAND_IDENTIFY))
-    return;
+    return 0;
 
   /* Process the command request. Let's search for the requested client and
      send reply to the requesting server. */
@@ -1178,8 +1197,10 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
 
   /* Check that all mandatory fields are present and request those data
      from the server who owns the client if necessary. */
-  if (!silc_server_command_identify_check(cmd, clients, clients_count))
+  if (!silc_server_command_identify_check(cmd, clients, clients_count)) {
+    ret = -1;
     goto out;
+  }
 
   /* Send the command reply */
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
@@ -1196,20 +1217,25 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
     silc_free(nick);
   if (server_name)
     silc_free(server_name);
+
+  return ret;
 }
 
 SILC_SERVER_CMD_FUNC(identify)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+  int ret = 0;
 
   SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_IDENTIFY, cmd, 1, 3328);
 
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
-    silc_server_command_identify_from_client(cmd);
-  else
-    silc_server_command_identify_from_server(cmd);
+    ret = silc_server_command_identify_from_client(cmd);
+  else if ((cmd->sock->type == SILC_SOCKET_TYPE_SERVER) |
+          (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER))
+    ret = silc_server_command_identify_from_server(cmd);
 
-  silc_server_command_free(cmd);
+  if (!ret)
+    silc_server_command_free(cmd);
 }
 
 /* Checks string for bad characters and returns TRUE if they are found. */
@@ -1718,7 +1744,7 @@ void silc_server_command_send_users(SilcServer server,
   }
   cmd->args = silc_command_get_args(cmd->payload);
   cmd->server = server;
-  cmd->sock = sock;
+  cmd->sock = silc_socket_dup(sock);
   cmd->packet = silc_packet_context_dup(packet);
   cmd->pending = FALSE;
 
@@ -1732,13 +1758,14 @@ void silc_server_command_send_users(SilcServer server,
                                silc_server_command_users,
                                silc_server_command_dup(cmd));
     cmd->pending = TRUE;
-    goto out;
+    silc_buffer_free(buffer);
+    silc_buffer_free(idp);
+    return;
   }
 
   /* Process USERS command. */
   silc_server_command_users((void *)cmd);
 
- out:
   silc_buffer_free(buffer);
   silc_buffer_free(idp);
   silc_packet_context_free(packet);
@@ -2036,7 +2063,7 @@ SILC_SERVER_CMD_FUNC(join)
                                      silc_server_command_join,
                                      silc_server_command_dup(cmd));
          cmd->pending = TRUE;
-         goto out;
+         return;
        }
        
        /* We are router and the channel does not seem exist so we will check
@@ -2923,7 +2950,7 @@ SILC_SERVER_CMD_FUNC(users)
       
       silc_buffer_free(tmpbuf);
       silc_free(id);
-      goto out;
+      return;
     }
 
     /* We are router and we will check the global list as well. */
index 8e99cb38158de0f0cc355a7e2459643fdf20cb72..5d6cd2991b8df4d5d0fb996619e233fd7bbe0238 100644 (file)
@@ -84,7 +84,7 @@ void silc_server_command_reply_process(SilcServer server,
      command reply routine receiving it. */
   ctx = silc_calloc(1, sizeof(*ctx));
   ctx->server = server;
-  ctx->sock = sock;
+  ctx->sock = silc_socket_dup(sock);
   ctx->payload = payload;
   ctx->args = silc_command_get_args(ctx->payload);
   ident = silc_command_get_ident(ctx->payload);
@@ -113,6 +113,8 @@ void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
 {
   if (cmd) {
     silc_command_free_payload(cmd->payload);
+    if (cmd->sock)
+      silc_socket_free(cmd->sock); /* Decrease the reference counter */
     silc_free(cmd);
   }
 }
index a9e591da06d587da9621432845363fea3877ad63..7f7c9841fabb6a813a79a425ade17dd29e1cfd2f 100644 (file)
@@ -1220,6 +1220,10 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
   /* Packet sending */
 
   if (type == SILC_TASK_WRITE) {
+    /* Do not send data to disconnected connection */
+    if (SILC_IS_DISCONNECTED(sock))
+      return;
+
     server->stat.packets_sent++;
 
     if (sock->outbuf->data - sock->outbuf->head)
@@ -1267,6 +1271,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
     }
       
     SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
+    SILC_SET_DISCONNECTING(sock);
 
     /* If the closed connection was our primary router connection the
        start re-connecting phase. */
@@ -1287,7 +1292,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
   /* If connection is disconnecting or disconnected we will ignore
      what we read. */
   if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
-    SILC_LOG_DEBUG(("Ignoring read data from invalid connection"));
+    SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
     return;
   }
 
index 245a81f9825f44056eade785168fa7d784834d05..e2e19573e96e50675e8822d4bf78b49a8a77a7af 100644 (file)
@@ -484,7 +484,8 @@ SILC_CLIENT_CMD_FUNC(invite)
                                silc_client_command_destructor,
                                silc_client_command_invite, 
                                silc_client_command_dup(cmd));
-    goto out;
+    cmd->pending = 1;
+    return;
   }
 
   /* Find channel entry */
@@ -1035,7 +1036,8 @@ SILC_CLIENT_CMD_FUNC(cumode)
                                silc_client_command_destructor,
                                silc_client_command_cumode, 
                                silc_client_command_dup(cmd));
-    goto out;
+    cmd->pending = 1;
+    return;
   }
   
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
@@ -1280,7 +1282,7 @@ SILC_CLIENT_CMD_FUNC(users)
                                silc_client_command_users, 
                                silc_client_command_dup(cmd));
     cmd->pending = TRUE;
-    goto out;
+    return;
   }
 
   if (cmd->pending) {