From a64c09e9059105cb0982892b40080718ea2fa4af Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 19 Feb 2001 14:49:33 +0000 Subject: [PATCH] updates. --- CHANGES | 21 +++++++++ apps/silc/silc.c | 4 +- apps/silcd/command.c | 87 +++++++++++++++++++++++++------------- apps/silcd/command_reply.c | 4 +- apps/silcd/server.c | 7 ++- lib/silcclient/command.c | 8 ++-- 6 files changed, 94 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index 2b5c1b28..c5b8a54f 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,27 @@ Mon Feb 19 14:26:49 EET 2001 Pekka Riikonen 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 * Changed the client operation API: channel_message operation's diff --git a/apps/silc/silc.c b/apps/silc/silc.c index 6a766e57..60aa5663 100644 --- a/apps/silc/silc.c +++ b/apps/silc/silc.c @@ -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, diff --git a/apps/silcd/command.c b/apps/silcd/command.c index b018eaa1..94d172e4 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -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. */ diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 8e99cb38..5d6cd299 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -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); } } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index a9e591da..7f7c9841 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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; } diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 245a81f9..e2e19573 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -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) { -- 2.24.0