From 2b1d5c184f8e5d9993beebccb90c8cc4c28297f0 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 29 Jan 2001 15:16:11 +0000 Subject: [PATCH] updates. --- apps/silcd/command.c | 56 +++++++++++---- apps/silcd/command_reply.c | 135 +++++++++++++++++++++++++++++++++--- apps/silcd/packet_receive.c | 2 - apps/silcd/testi2.conf | 8 +-- lib/silcclient/command.c | 2 +- 5 files changed, 173 insertions(+), 30 deletions(-) diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 4cdb2ca4..a5137efb 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -1660,21 +1660,29 @@ void silc_server_command_send_names(SilcServer server, { SilcServerCommandContext cmd; SilcBuffer buffer, idp; + SilcPacketContext *packet = silc_packet_context_alloc(); idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL); buffer = silc_command_payload_encode_va(SILC_COMMAND_NAMES, 0, 1, 1, idp->data, idp->len); + packet->buffer = silc_buffer_copy(buffer); + packet->sock = sock; + packet->type = SILC_PACKET_COMMAND; + cmd = silc_calloc(1, sizeof(*cmd)); cmd->payload = silc_command_payload_parse(buffer); cmd->args = silc_command_get_args(cmd->payload); cmd->server = server; cmd->sock = sock; + cmd->packet = silc_packet_context_dup(packet); cmd->pending = FALSE; silc_server_command_names((void *)cmd); + silc_free(buffer); silc_free(idp); + silc_packet_context_free(packet); } /* Internal routine that is called after router has replied to server's @@ -2830,35 +2838,53 @@ SILC_SERVER_CMD_FUNC(names) SilcBuffer client_id_list; SilcBuffer client_mode_list; SilcBuffer idp; + unsigned short ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_NAMES, cmd, 1, 2); /* Get Channel ID */ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); if (!tmp) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE, + silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES, SILC_STATUS_ERR_NO_CHANNEL_ID); goto out; } id = silc_id_payload_parse_id(tmp, tmp_len); - /* Check whether the channel exists. If we are normal server and the - channel does not exist we will send this same command to our router - which will know if the channel exists. */ + if (server->server_type == SILC_SERVER && !server->standalone && + !cmd->pending) { + SilcBuffer tmpbuf; + + silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng)); + tmpbuf = silc_command_payload_encode_payload(cmd->payload); + + /* Send NAMES command */ + silc_server_packet_send(server, server->router->connection, + SILC_PACKET_COMMAND, cmd->packet->flags, + tmpbuf->data, tmpbuf->len, TRUE); + + /* Reprocess this packet after received reply */ + silc_server_command_pending(server, SILC_COMMAND_NAMES, + silc_command_get_ident(cmd->payload), + silc_server_command_names, (void *)cmd); + cmd->pending = TRUE; + silc_command_set_ident(cmd->payload, ident); + + silc_buffer_free(tmpbuf); + silc_free(id); + return; + } + + /* Get the channel entry */ channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL); if (!channel) { - if (server->server_type == SILC_SERVER && !server->standalone) { - /* XXX Send names command */ - - cmd->pending = TRUE; - silc_server_command_pending(server, SILC_COMMAND_NAMES, 0, - silc_server_command_names, context); - return; + channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL); + if (!channel) { + /* Channel really does not exist */ + silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES, + SILC_STATUS_ERR_NO_SUCH_CHANNEL); + goto out; } - - silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, - SILC_STATUS_ERR_NO_SUCH_CHANNEL); - goto out; } /* Assemble the lists now */ diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 15ce098c..4b69ce9a 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -25,6 +25,7 @@ #define COMMAND_CHECK_STATUS \ do { \ + SILC_LOG_DEBUG(("Start")); \ SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \ if (status != SILC_STATUS_OK) { \ silc_server_command_reply_free(cmd); \ @@ -34,6 +35,7 @@ do { \ #define COMMAND_CHECK_STATUS_LIST \ do { \ + SILC_LOG_DEBUG(("Start")); \ SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \ if (status != SILC_STATUS_OK && \ status != SILC_STATUS_LIST_START && \ @@ -220,8 +222,6 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcCommandStatus status; - SILC_LOG_DEBUG(("Start")); - COMMAND_CHECK_STATUS_LIST; if (!silc_server_command_reply_whois_save(cmd)) @@ -357,8 +357,6 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcCommandStatus status; - SILC_LOG_DEBUG(("Start")); - COMMAND_CHECK_STATUS_LIST; if (!silc_server_command_reply_identify_save(cmd)) @@ -406,8 +404,6 @@ SILC_SERVER_CMD_REPLY_FUNC(join) unsigned int mode, created; SilcBuffer keyp; - SILC_LOG_DEBUG(("Start")); - COMMAND_CHECK_STATUS; /* Get channel name */ @@ -493,9 +489,132 @@ SILC_SERVER_CMD_REPLY_FUNC(names) SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; SilcCommandStatus status; - - SILC_LOG_DEBUG(("Start")); + SilcChannelEntry channel; + SilcChannelID *channel_id = NULL; + SilcBuffer client_id_list; + SilcBuffer client_mode_list; + unsigned char *tmp; + char *name_list, *cp; + int i, len1, len2, list_count = 0; COMMAND_CHECK_STATUS; + /* Get channel ID */ + tmp = silc_argument_get_arg_type(cmd->args, 2, &len1); + if (!tmp) + goto out; + channel_id = silc_id_payload_parse_id(tmp, len1); + + /* Get the name list of the channel */ + name_list = silc_argument_get_arg_type(cmd->args, 3, &len1); + if (!name_list) + goto out; + + /* Get Client ID list */ + tmp = silc_argument_get_arg_type(cmd->args, 4, &len2); + if (!tmp) + goto out; + + client_id_list = silc_buffer_alloc(len2); + silc_buffer_pull_tail(client_id_list, len2); + silc_buffer_put(client_id_list, tmp, len2); + + /* Get client mode list */ + tmp = silc_argument_get_arg_type(cmd->args, 5, &len2); + if (!tmp) + goto out; + + client_mode_list = silc_buffer_alloc(len2); + silc_buffer_pull_tail(client_mode_list, len2); + silc_buffer_put(client_mode_list, tmp, len2); + + /* Get channel entry */ + channel = silc_idlist_find_channel_by_id(server->local_list, + channel_id, NULL); + if (!channel) { + channel = silc_idlist_find_channel_by_id(server->global_list, + channel_id, NULL); + if (!channel) + goto out; + } + + /* Remove commas from list */ + for (i = 0; i < len1; i++) + if (name_list[i] == ',') { + name_list[i] = ' '; + list_count++; + } + list_count++; + + /* Cache the received name list, client ID's and modes. This cache expires + whenever server sends notify message to channel. It means two things; + some user has joined or leaved the channel. XXX! */ + cp = name_list; + for (i = 0; i < list_count; i++) { + int nick_len = strcspn(name_list, " "); + unsigned short idp_len; + unsigned int mode; + char *nick, *nickname = silc_calloc(nick_len + 1, sizeof(*nickname)); + SilcClientID *client_id; + SilcClientEntry client; + + /* Nickname */ + memcpy(nickname, name_list, nick_len); + SILC_GET16_MSB(idp_len, client_id_list->data + 2); + idp_len += 4; + + /* Client ID */ + client_id = silc_id_payload_parse_id(client_id_list->data, idp_len); + silc_buffer_pull(client_id_list, idp_len); + + /* Mode */ + SILC_GET32_MSB(mode, client_mode_list->data); + silc_buffer_pull(client_mode_list, 4); + + /* Check if we have this client cached already. */ + client = silc_idlist_find_client_by_id(server->local_list, client_id, + NULL); + if (!client) + client = silc_idlist_find_client_by_id(server->global_list, + client_id, NULL); + if (!client) { + /* If router did not find such Client ID in its lists then this must + be bogus client or some router in the net is buggy. */ + if (server->server_type == SILC_ROUTER) + goto out; + + /* Take hostname out of nick string if it includes it. */ + if (strchr(nickname, '@')) { + int len = strcspn(nickname, "@"); + nick = silc_calloc(len + 1, sizeof(char)); + memcpy(nick, nickname, len); + } else { + nick = strdup(nickname); + } + + /* We don't have that client anywhere, add it. The client is added + to global list since server didn't have it in the lists so it must be + global. */ + silc_idlist_add_client(server->global_list, nick, NULL, NULL, + client_id, NULL, NULL); + } else { + /* We have the client already. */ + silc_free(client_id); + } + + silc_free(nickname); + + name_list += nick_len + 1; + } + + silc_buffer_free(client_id_list); + silc_buffer_free(client_mode_list); + + /* Execute any pending commands */ + SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_NAMES); + + out: + if (channel_id) + silc_free(channel_id); + silc_server_command_reply_free(cmd); } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index f7c59125..16513946 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1114,8 +1114,6 @@ void silc_server_new_channel_user(SilcServer server, packet->buffer->data, packet->buffer->len, FALSE); } - SILC_LOG_DEBUG(("Client ID: %s", silc_id_render(client_id, SILC_ID_CLIENT))); - /* Get client entry */ client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL); if (!client) { diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 984d93b2..4007fc60 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -16,10 +16,10 @@ sha1::64:20 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi [ServerInfo] -lassi.kuo.fi.ssh.com:212.146.8.246:Kuopio, Finland:1334 +lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334 [ListenPort] -212.146.8.246:212.146.8.246:1334 +10.2.1.7:10.2.1.7:1334 [Logging] infologfile:silcd2.log:10000 @@ -40,10 +40,10 @@ errorlogfile:silcd2.log:10000 [AdminConnection] [ServerConnection] -212.146.8.246:passwd:priikone:1333:1:1 +10.2.1.7:passwd:priikone:1333:1:1 [RouterConnection] -212.146.8.246:passwd:priikone:1335:1:1:0 +10.2.1.7:passwd:priikone:1335:1:1:0 [DenyConnection] [RedirectClient] diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index f039aac0..590ae71c 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -665,7 +665,7 @@ SILC_CLIENT_CMD_FUNC(join) idp = silc_id_payload_encode(conn->local_id, SILC_ID_CLIENT); /* Send JOIN command to the server */ - if (cmd->argc == 3) + if (cmd->argc == 2) buffer = silc_command_payload_encode_va(SILC_COMMAND_JOIN, 0, 2, 1, cmd->argv[1], cmd->argv_lens[1], -- 2.43.0