From 2f93ad66ac16ad7c8bde97d1298bb78aad5b4f35 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 3 Dec 2001 20:29:51 +0000 Subject: [PATCH] updates. --- CHANGES | 31 ++++++++ TODO | 19 ++--- apps/irssi/src/silc/core/client_ops.c | 75 +++++++++++++++++-- apps/irssi/src/silc/core/silc-servers.h | 1 + apps/silcd/command.c | 14 +++- apps/silcd/command_reply.c | 98 +++++++++++++++++++------ apps/silcd/idlist.c | 20 ++--- apps/silcd/idlist.h | 7 +- apps/silcd/packet_receive.c | 29 ++++++-- apps/silcd/packet_send.c | 26 +++++++ apps/silcd/packet_send.h | 8 ++ apps/silcd/server.c | 40 ++++++---- apps/silcd/server_util.c | 8 +- lib/LIBINDEX | 2 +- lib/silcclient/client.c | 4 +- lib/silcclient/client_notify.c | 2 +- lib/silcclient/command.c | 2 +- lib/silcclient/command_reply.c | 5 +- lib/silcclient/idlist.c | 4 +- lib/silccore/silcidcache.c | 8 +- lib/silccore/silcidcache.h | 9 ++- prepare | 2 +- silc_optimize | 4 + 23 files changed, 325 insertions(+), 93 deletions(-) diff --git a/CHANGES b/CHANGES index e261a9c7..af0fee61 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,34 @@ +Mon Dec 3 18:49:45 EET 2001 Pekka Riikonen + + * Do not print "you are now server operator" or similar when + giving /away command. Affected files are + irssi/src/silc/core/client_ops.c, silc-servers.h. + + * Made the silc_server_command_pending_error_check to send + the same command reply payload it received back to the + original sender of the command. This way all arguments + that was received by the server will be received by the + client too. Affected file silcd/command.c. + + * Added the silc_idcache_add to return the created cache entry + to a pointer. Affected file lib/silccore/silcidcache.[ch]. + + * Add global clients to expire if they are not on any channel. + This is because normal server will never know if they signoff + if they are not on any channel. The cache expiry will take + case of these entries. This is done by normal servers only. + The affected files are silcd/command_reply.c, + silcd/idlist.[ch], silcd/server and silcd/packet_receive.c. + + * If server receives invalid ID notification for WHOIS or + IDENTIFY and the ID exists in the lists, it is removed. + Affected file silcd/command_reply.c. + + * If NO_SUCH_CLIENT_ID is received for WHOIS or IDENTIFY command + in client then client entry that it matches is searched and + the nickname is printed on the screen for user. Affected + file irssi/src/silc/core/client_ops.c. + Mon Dec 3 11:56:59 EET 2001 Pekka Riikonen * Use cache entry expire time in the LIST command reply to diff --git a/TODO b/TODO index 22dbc70a..0d1cdb58 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,6 @@ TODO/bugs in Irssi SILC client ============================== - o Setting /away prints server/router operator modes as well. - Print modes that was just set only. - o Add local command to switch the channel's private key when channel has several private keys. Currently sending channel messages with many keys is not possible because changing the key is not possible by the @@ -33,17 +30,21 @@ TODO/bugs in Irssi SILC client TODO/bugs In SILC Client Library ================================ - o N/A + o Process the NO_SUCH_CLIENT_ID for WHOIS and IDENTIFY, since it can + be received for example after sending MSG to non-existent client. + It actually should be done always when it is received and the old + entry should be removed. + + Doing this now however causes that /msg nick might give "no such nick" + for the first time, and then after the entry is removed /msg nick + may actually to go any nick client, which is not desired behaviour. + The /msg must be fixed to use the specific nickname user typed + (nick must not match nick@host). TODO/bugs In SILC Server ======================== - o Make the silc_server_command_pending_error_check function to - take all arguments it received and put them to the reply it is - sending. Otherwise for example WHOIS on normal server for bogus - nickname does not print anything in the client. - o Backup router related issues o Channel user mode changes are notified unnecessarely when diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 9d7d7d86..76be0744 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -406,15 +406,33 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, SilcBuffer channels; SilcClientEntry client_entry; - if (status == SILC_STATUS_ERR_NO_SUCH_NICK || - status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { - char *tmp; - tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload), - 3, NULL); + if (status == SILC_STATUS_ERR_NO_SUCH_NICK) { + /* Print the unknown nick for user */ + unsigned char *tmp = + silc_argument_get_arg_type(silc_command_get_args(cmd_payload), + 3, NULL); if (tmp) silc_say_error("%s: %s", tmp, silc_client_command_status_message(status)); break; + } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + /* Try to find the entry for the unknown client ID, since we + might have, and print the nickname of it for user. */ + uint32 tmp_len; + unsigned char *tmp = + silc_argument_get_arg_type(silc_command_get_args(cmd_payload), + 2, &tmp_len); + if (tmp) { + SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len); + if (client_id) { + client_entry = silc_client_get_client_by_id(client, conn, + client_id); + if (client_entry && client_entry->nickname) + silc_say_error("%s: %s", client_entry->nickname, + silc_client_command_status_message(status)); + silc_free(client_id); + } + } } if (!success) @@ -499,6 +517,45 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, } break; + case SILC_COMMAND_IDENTIFY: + { + SilcClientEntry client_entry; + + /* Identify command is used only internally by the client library + but it still might send some interesting stuff for user interface + so let's print errors. */ + + if (status == SILC_STATUS_ERR_NO_SUCH_NICK) { + /* Print the unknown nick for user */ + unsigned char *tmp = + silc_argument_get_arg_type(silc_command_get_args(cmd_payload), + 3, NULL); + if (tmp) + silc_say_error("%s: %s", tmp, + silc_client_command_status_message(status)); + break; + } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + /* Try to find the entry for the unknown client ID, since we + might have, and print the nickname of it for user. */ + uint32 tmp_len; + unsigned char *tmp = + silc_argument_get_arg_type(silc_command_get_args(cmd_payload), + 2, &tmp_len); + if (tmp) { + SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len); + if (client_id) { + client_entry = silc_client_get_client_by_id(client, conn, + client_id); + if (client_entry && client_entry->nickname) + silc_say_error("%s: %s", client_entry->nickname, + silc_client_command_status_message(status)); + silc_free(client_id); + } + } + } + } + break; + case SILC_COMMAND_WHOWAS: { char *nickname, *username, *realname; @@ -662,13 +719,17 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, mode = va_arg(vp, uint32); - if (mode & SILC_UMODE_SERVER_OPERATOR) + if (mode & SILC_UMODE_SERVER_OPERATOR && + !(server->umode & SILC_UMODE_SERVER_OPERATOR)) printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, SILCTXT_SERVER_OPER); - if (mode & SILC_UMODE_ROUTER_OPERATOR) + if (mode & SILC_UMODE_ROUTER_OPERATOR && + !(server->umode & SILC_UMODE_ROUTER_OPERATOR)) printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, SILCTXT_ROUTER_OPER); + + server->umode = mode; } break; diff --git a/apps/irssi/src/silc/core/silc-servers.h b/apps/irssi/src/silc/core/silc-servers.h index 7add2f55..c90b84f3 100644 --- a/apps/irssi/src/silc/core/silc-servers.h +++ b/apps/irssi/src/silc/core/silc-servers.h @@ -56,6 +56,7 @@ typedef struct { gpointer chanqueries; SilcClientConnection conn; + uint32 umode; } SILC_SERVER_REC; SILC_SERVER_REC *silc_server_connect(SILC_SERVER_CONNECT_REC *conn); diff --git a/apps/silcd/command.c b/apps/silcd/command.c index ae85305a..a1e5e16c 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -439,8 +439,16 @@ silc_server_command_pending_error_check(SilcServerCommandContext cmd, status != SILC_STATUS_LIST_START && status != SILC_STATUS_LIST_ITEM && status != SILC_STATUS_LIST_END) { - /* Send the error message */ - silc_server_command_send_status_reply(cmd, command, status); + SilcBuffer buffer; + + /* Send the same command reply payload */ + silc_command_set_ident(cmdr->payload, + silc_command_get_ident(cmd->payload)); + buffer = silc_command_payload_encode_payload(cmdr->payload); + silc_server_packet_send(cmd->server, cmd->sock, + SILC_PACKET_COMMAND_REPLY, 0, + buffer->data, buffer->len, FALSE); + silc_buffer_free(buffer); return TRUE; } @@ -2018,7 +2026,7 @@ SILC_SERVER_CMD_FUNC(nick) /* Update client cache */ silc_idcache_add(server->local_list->clients, client->nickname, - client->id, (void *)client, FALSE); + client->id, (void *)client, 0, NULL); nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 5bf79b6a..56c22226 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -140,6 +140,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) char global = FALSE; char *nick; uint32 mode = 0, len, id_len, flen; + int expire = 0; id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len); nickname = silc_argument_get_arg_type(cmd->args, 3, &len); @@ -188,7 +189,8 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) client = silc_idlist_add_client(server->global_list, nick, strdup(username), strdup(realname), client_id, - cmd->sock->user_data, NULL); + cmd->sock->user_data, NULL, + time(NULL) + 300); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); return FALSE; @@ -224,10 +226,16 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + /* If client is global and is not on any channel then add that we'll + expire the entry after a while. */ + if (global && !silc_hash_table_count(client->channels) && + server->server_type == SILC_SERVER) + expire = time(NULL) + 300; + /* Create new cache entry */ silc_idcache_add(global ? server->global_list->clients : server->local_list->clients, nick, client->id, - client, FALSE); + client, expire, NULL); silc_free(client_id); } @@ -246,6 +254,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(whois) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; + SilcServer server = cmd->server; SilcCommandStatus status; COMMAND_CHECK_STATUS_LIST; @@ -261,6 +270,27 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) } out: + /* If we received notify for invalid ID we'll remove the ID if we + have it cached. */ + if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && + cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { + SilcClientEntry client; + uint32 tmp_len; + unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (tmp) { + SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len); + if (client_id) { + SILC_LOG_DEBUG(("Received invalid client ID notification, deleting " + "the entry from cache")); + client = silc_idlist_find_client_by_id(server->global_list, + client_id, FALSE, NULL); + if (client) + silc_idlist_del_client(server->global_list, client); + silc_free(client_id); + } + } + } + SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_WHOIS); SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_WHOIS); silc_server_command_reply_free(cmd); @@ -318,16 +348,14 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) client = silc_idlist_add_client(server->global_list, nick, strdup(username), strdup(realname), silc_id_dup(client_id, SILC_ID_CLIENT), - cmd->sock->user_data, NULL); + cmd->sock->user_data, NULL, + SILC_ID_CACHE_EXPIRE_DEF); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); return FALSE; } client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; - client = silc_idlist_find_client_by_id(server->global_list, - client_id, TRUE, &cache); - cache->expire = SILC_ID_CACHE_EXPIRE_DEF; client->servername = servername; } else { /* We have the client already, update the data */ @@ -347,7 +375,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) server->local_list->clients, client); silc_idcache_add(global ? server->global_list->clients : server->local_list->clients, nick, client->id, - client, FALSE); + client, 0, NULL); } silc_free(client_id); @@ -400,6 +428,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) char *nick = NULL; SilcIDPayload idp = NULL; SilcIdType id_type; + int expire = 0; id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len); if (!id_data) @@ -443,7 +472,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) global. */ client = silc_idlist_add_client(server->global_list, nick, info ? strdup(info) : NULL, NULL, - client_id, cmd->sock->user_data, NULL); + client_id, cmd->sock->user_data, NULL, + time(NULL) + 300); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); goto error; @@ -477,10 +507,16 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; if (name) { + /* If client is global and is not on any channel then add that we'll + expire the entry after a while. */ + if (global && !silc_hash_table_count(client->channels) && + server->server_type == SILC_SERVER) + expire = time(NULL) + 300; + /* Add new cache entry */ silc_idcache_add(global ? server->global_list->clients : server->local_list->clients, nick, client->id, - client, FALSE); + client, expire, NULL); } silc_free(client_id); @@ -550,8 +586,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) /* We don't have that server anywhere, add it. */ channel = silc_idlist_add_channel(server->global_list, strdup(name), SILC_CHANNEL_MODE_NONE, channel_id, - server->router, - NULL, NULL); + server->router, NULL, NULL, 0); if (!channel) { silc_free(channel_id); goto error; @@ -579,6 +614,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(identify) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; + SilcServer server = cmd->server; SilcCommandStatus status; COMMAND_CHECK_STATUS_LIST; @@ -594,6 +630,27 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) } out: + /* If we received notify for invalid ID we'll remove the ID if we + have it cached. */ + if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && + cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { + SilcClientEntry client; + uint32 tmp_len; + unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (tmp) { + SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len); + if (client_id) { + SILC_LOG_DEBUG(("Received invalid client ID notification, deleting " + "the entry from cache")); + client = silc_idlist_find_client_by_id(server->global_list, + client_id, FALSE, NULL); + if (client) + silc_idlist_del_client(server->global_list, client); + silc_free(client_id); + } + } + } + SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_IDENTIFY); SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_IDENTIFY); silc_server_command_reply_free(cmd); @@ -821,7 +878,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) /* Add the channel to our local list. */ entry = silc_idlist_add_channel(server->local_list, strdup(channel_name), SILC_CHANNEL_MODE_NONE, id, - server->router, NULL, hmac); + server->router, NULL, hmac, 0); if (!entry) { silc_free(id); goto out; @@ -1100,6 +1157,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list) uint32 len; unsigned char *tmp, *name, *topic; uint32 usercount = 0; + bool global_list = FALSE; COMMAND_CHECK_STATUS_LIST; @@ -1117,9 +1175,11 @@ SILC_SERVER_CMD_REPLY_FUNC(list) /* Add the channel entry if we do not have it already */ channel = silc_idlist_find_channel_by_name(server->local_list, name, &cache); - if (!channel) + if (!channel) { channel = silc_idlist_find_channel_by_name(server->global_list, name, &cache); + global_list = TRUE; + } if (!channel) { /* If router did not find such channel in its lists then this must be bogus channel or some router in the net is buggy. */ @@ -1128,19 +1188,15 @@ SILC_SERVER_CMD_REPLY_FUNC(list) channel = silc_idlist_add_channel(server->global_list, strdup(name), SILC_CHANNEL_MODE_NONE, channel_id, - server->router, NULL, NULL); + server->router, NULL, NULL, + time(NULL) + 60); if (!channel) goto out; - - /* Update cache entry expiry */ - if (silc_idlist_find_channel_by_id(server->global_list, channel_id, - &cache)) - cache->expire = time(NULL) + 60; - channel_id = NULL; } else { /* Found, update expiry */ - cache->expire = time(NULL) + 60; + if (global_list && server->server_type == SILC_SERVER) + cache->expire = time(NULL) + 60; } if (topic) { diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index fa084ec6..502744eb 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -88,7 +88,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge) silc_idcache_purge(i->cache); silc_schedule_task_add(i->schedule, 0, silc_idlist_purge, - (void *)i, 600, 0, + (void *)i, i->timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } @@ -121,7 +121,7 @@ silc_idlist_add_server(SilcIDList id_list, server->connection = connection; if (!silc_idcache_add(id_list->servers, server->server_name, - (void *)server->id, (void *)server, FALSE)) { + (void *)server->id, (void *)server, 0, NULL)) { silc_free(server); return NULL; } @@ -270,7 +270,7 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id, server->id = new_id; silc_idcache_add(id_list->servers, server->server_name, server->id, - server, FALSE); + server, 0, NULL); SILC_LOG_DEBUG(("Found")); @@ -319,7 +319,8 @@ int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry) SilcClientEntry silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, char *userinfo, SilcClientID *id, - SilcServerEntry router, void *connection) + SilcServerEntry router, void *connection, + int expire) { SilcClientEntry client; @@ -336,7 +337,7 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, NULL, NULL, NULL, NULL, TRUE); if (!silc_idcache_add(id_list->clients, nickname, (void *)client->id, - (void *)client, FALSE)) { + (void *)client, expire, NULL)) { silc_hash_table_free(client->channels); silc_free(client); return NULL; @@ -522,7 +523,7 @@ silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id, silc_free(client->id); client->id = new_id; - silc_idcache_add(id_list->clients, NULL, client->id, client, FALSE); + silc_idcache_add(id_list->clients, NULL, client->id, client, 0, NULL); SILC_LOG_DEBUG(("Replaced")); @@ -561,7 +562,8 @@ void silc_idlist_client_destructor(SilcIDCache cache, SilcChannelEntry silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, SilcChannelID *id, SilcServerEntry router, - SilcCipher channel_key, SilcHmac hmac) + SilcCipher channel_key, SilcHmac hmac, + int expire) { SilcChannelEntry channel; @@ -585,7 +587,7 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, NULL, NULL, NULL, TRUE); if (!silc_idcache_add(id_list->channels, channel->channel_name, - (void *)channel->id, (void *)channel, FALSE)) { + (void *)channel->id, (void *)channel, expire, NULL)) { silc_hmac_free(channel->hmac); silc_hash_table_free(channel->user_list); silc_free(channel); @@ -731,7 +733,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id, channel->id = new_id; silc_idcache_add(id_list->channels, channel->channel_name, channel->id, - channel, FALSE); + channel, 0, NULL); SILC_LOG_DEBUG(("Replaced")); diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index 37d3e9bb..74d054f7 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -31,6 +31,7 @@ typedef struct SilcChannelEntryStruct *SilcChannelEntry; typedef struct { SilcIDCache cache; SilcSchedule schedule; + uint32 timeout; } *SilcIDListPurge; /* Channel key re-key context. */ @@ -579,7 +580,8 @@ int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry); SilcClientEntry silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, char *userinfo, SilcClientID *id, - SilcServerEntry router, void *connection); + SilcServerEntry router, void *connection, + int expire); int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry); int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname, char *server, @@ -600,7 +602,8 @@ void silc_idlist_client_destructor(SilcIDCache cache, SilcChannelEntry silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, SilcChannelID *id, SilcServerEntry router, - SilcCipher channel_key, SilcHmac hmac); + SilcCipher channel_key, SilcHmac hmac, + int expire); int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry); SilcChannelEntry silc_idlist_find_channel_by_name(SilcIDList id_list, char *name, diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 248442d7..92616389 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -180,7 +180,7 @@ void silc_server_notify(SilcServer server, client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL, silc_id_dup(client_id, SILC_ID_CLIENT), - sock->user_data, NULL); + sock->user_data, NULL, 0); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); silc_free(client_id); @@ -1220,9 +1220,22 @@ void silc_server_private_message(SilcServer server, if (!idp) return; - silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY, - SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0, 1, - 2, idp, idp->len); + if (packet->src_id_type == SILC_ID_CLIENT) { + SilcClientID *client_id = silc_id_str2id(packet->src_id, + packet->src_id_len, + packet->src_id_type); + silc_server_send_dest_command_reply(server, sock, + client_id, SILC_ID_CLIENT, + SILC_COMMAND_IDENTIFY, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + 0, 1, 2, idp->data, idp->len); + silc_free(client_id); + } else { + silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + 0, 1, 2, idp->data, idp->len); + } + silc_buffer_free(idp); return; } @@ -1611,7 +1624,7 @@ SilcClientEntry silc_server_new_client(SilcServer server, /* Add the client again to the ID cache */ silc_idcache_add(server->local_list->clients, client->nickname, - client_id, client, FALSE); + client_id, client, 0, NULL); /* Notify our router about new client on the SILC network */ if (!server->standalone) @@ -1779,7 +1792,7 @@ SilcServerEntry silc_server_new_server(SilcServer server, /* Add again the entry to the ID cache. */ silc_idcache_add(local ? server->local_list->servers : server->global_list->servers, server_name, server_id, - new_server, FALSE); + new_server, 0, NULL); /* Distribute the information about new server in the SILC network to our router. If we are normal server we won't send anything @@ -1925,7 +1938,7 @@ static void silc_server_new_id_real(SilcServer server, global list. Cell wide information however is kept in the local list. */ entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, - id, router, NULL); + id, router, NULL, 0); if (!entry) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); @@ -2164,7 +2177,7 @@ void silc_server_new_channel(SilcServer server, sock->hostname)); silc_idlist_add_channel(server->global_list, strdup(channel_name), - 0, channel_id, sock->user_data, NULL, NULL); + 0, channel_id, sock->user_data, NULL, NULL, 0); server->stat.channels++; } } else { diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 0278ff1c..b67071a6 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -1769,6 +1769,32 @@ void silc_server_send_command_reply(SilcServer server, va_end(ap); } +/* Generic function to send any command reply. The arguments must be sent + already encoded into correct form in correct order. */ + +void silc_server_send_dest_command_reply(SilcServer server, + SilcSocketConnection sock, + void *dst_id, + SilcIdType dst_id_type, + SilcCommand command, + SilcCommandStatus status, + uint16 ident, + uint32 argc, ...) +{ + SilcBuffer packet; + va_list ap; + + va_start(ap, argc); + + packet = silc_command_reply_payload_encode_vap(command, status, ident, + argc, ap); + silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0, + dst_id, dst_id_type, packet->data, + packet->len, TRUE); + silc_buffer_free(packet); + va_end(ap); +} + /* Send the heartbeat packet. */ void silc_server_send_heartbeat(SilcServer server, diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index 412799b1..0bf83541 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -232,6 +232,14 @@ void silc_server_send_command_reply(SilcServer server, SilcCommandStatus status, uint16 ident, uint32 argc, ...); +void silc_server_send_dest_command_reply(SilcServer server, + SilcSocketConnection sock, + void *dst_id, + SilcIdType dst_id_type, + SilcCommand command, + SilcCommandStatus status, + uint16 ident, + uint32 argc, ...); void silc_server_send_heartbeat(SilcServer server, SilcSocketConnection sock); void silc_server_relay_packet(SilcServer server, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 8f58188e..2dfbbbbb 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -329,18 +329,20 @@ int silc_server_init(SilcServer server) purge = silc_calloc(1, sizeof(*purge)); purge->cache = server->local_list->clients; purge->schedule = server->schedule; + purge->timeout = 600; silc_schedule_task_add(purge->schedule, 0, silc_idlist_purge, - (void *)purge, 600, 0, + (void *)purge, purge->timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); /* Clients global list */ purge = silc_calloc(1, sizeof(*purge)); purge->cache = server->global_list->clients; purge->schedule = server->schedule; + purge->timeout = 300; silc_schedule_task_add(purge->schedule, 0, silc_idlist_purge, - (void *)purge, 300, 0, + (void *)purge, purge->timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); SILC_LOG_DEBUG(("Server initialized")); @@ -1319,7 +1321,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) and other information is created after we have received NEW_CLIENT packet from client. */ client = silc_idlist_add_client(server->local_list, - NULL, NULL, NULL, NULL, NULL, sock); + NULL, NULL, NULL, NULL, NULL, sock, 0); if (!client) { SILC_LOG_ERROR(("Could not add new client to cache")); silc_free(sock->user_data); @@ -2773,7 +2775,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, } entry = silc_idlist_add_channel(server->local_list, channel_name, SILC_CHANNEL_MODE_NONE, channel_id, - NULL, key, newhmac); + NULL, key, newhmac, 0); if (!entry) { silc_free(channel_name); silc_cipher_free(key); @@ -2844,7 +2846,7 @@ silc_server_create_new_channel_with_id(SilcServer server, /* Create the channel */ entry = silc_idlist_add_channel(server->local_list, channel_name, SILC_CHANNEL_MODE_NONE, channel_id, - NULL, key, newhmac); + NULL, key, newhmac, 0); if (!entry) { silc_free(channel_name); return NULL; @@ -3666,13 +3668,14 @@ void silc_server_save_users_on_channel(SilcServer server, uint32 user_count) { int i; + uint16 idp_len; + uint32 mode; + SilcClientID *client_id; + SilcClientEntry client; + SilcIDCacheEntry cache; + bool global; for (i = 0; i < user_count; i++) { - uint16 idp_len; - uint32 mode; - SilcClientID *client_id; - SilcClientEntry client; - /* Client ID */ SILC_GET16_MSB(idp_len, user_list->data + 2); idp_len += 4; @@ -3689,14 +3692,18 @@ void silc_server_save_users_on_channel(SilcServer server, silc_free(client_id); continue; } + + global = FALSE; /* Check if we have this client cached already. */ client = silc_idlist_find_client_by_id(server->local_list, client_id, - server->server_type, NULL); - if (!client) + server->server_type, &cache); + if (!client) { client = silc_idlist_find_client_by_id(server->global_list, client_id, server->server_type, - NULL); + &cache); + global = TRUE; + } 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. */ @@ -3710,7 +3717,7 @@ void silc_server_save_users_on_channel(SilcServer server, global. */ client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL, silc_id_dup(client_id, SILC_ID_CLIENT), - sock->user_data, NULL); + sock->user_data, NULL, 0); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); silc_free(client_id); @@ -3718,6 +3725,11 @@ void silc_server_save_users_on_channel(SilcServer server, } client->data.status |= SILC_IDLIST_STATUS_REGISTERED; + } else { + /* Found, if it is from global list we'll assure that we won't + expire it now that the entry is on channel. */ + if (global) + cache->expire = 0; } silc_free(client_id); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index a29c2fd3..1f21972e 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -371,7 +371,7 @@ silc_server_update_clients_by_real_server(SilcServer server, SILC_LOG_DEBUG(("Moving client to local list")); silc_idcache_add(server->local_list->clients, client_cache->name, client_cache->id, client_cache->context, - client_cache->expire); + client_cache->expire, NULL); silc_idcache_del_by_context(server->global_list->clients, client); } server_entry = server_entry->router; @@ -382,7 +382,7 @@ silc_server_update_clients_by_real_server(SilcServer server, SILC_LOG_DEBUG(("Moving client to local list")); silc_idcache_add(server->local_list->clients, client_cache->name, client_cache->id, client_cache->context, - client_cache->expire); + client_cache->expire, NULL); silc_idcache_del_by_context(server->global_list->clients, client); } } @@ -418,7 +418,7 @@ silc_server_update_clients_by_real_server(SilcServer server, SILC_LOG_DEBUG(("Moving client to global list")); silc_idcache_add(server->global_list->clients, client_cache->name, client_cache->id, client_cache->context, - client_cache->expire); + client_cache->expire, NULL); silc_idcache_del_by_context(server->local_list->clients, client); } server_entry = server_entry->router; @@ -429,7 +429,7 @@ silc_server_update_clients_by_real_server(SilcServer server, SILC_LOG_DEBUG(("Moving client to global list")); silc_idcache_add(server->global_list->clients, client_cache->name, client_cache->id, client_cache->context, - client_cache->expire); + client_cache->expire, NULL); silc_idcache_del_by_context(server->local_list->clients, client); } } diff --git a/lib/LIBINDEX b/lib/LIBINDEX index e19fcbaf..4a5f7cd0 100644 --- a/lib/LIBINDEX +++ b/lib/LIBINDEX @@ -6,7 +6,7 @@ SILC Toolkit Reference Manual
Copyright (C) GNU GPL 2001 The SILC Project
-Version: 0.6.3
+Version: 0.7
Updated: @DATE@

Note that this document is still under work and does not diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 58bcad2b..4676dc51 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -1478,7 +1478,7 @@ void silc_client_receive_new_id(SilcClient client, /* Put it to the ID cache */ silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, - (void *)conn->local_entry, FALSE); + (void *)conn->local_entry, 0, NULL); if (connecting) { /* Issue INFO comqmand to fetch the real server name and server information @@ -1518,7 +1518,7 @@ SilcChannelEntry silc_client_new_channel_id(SilcClient client, /* Put it to the ID cache */ silc_idcache_add(conn->channel_cache, channel->channel_name, - (void *)channel->id, (void *)channel, FALSE); + (void *)channel->id, (void *)channel, 0, NULL); return channel; } diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index d819b972..b4d4a78e 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -724,7 +724,7 @@ void silc_client_notify_by_server(SilcClient client, /* Add the channel entry again to ID cache */ silc_idcache_add(conn->channel_cache, channel->channel_name, - channel->id, channel, FALSE); + channel->id, channel, 0, NULL); /* Notify application */ client->ops->notify(client, conn, type, channel, channel); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index dd329441..d1cf1f69 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -370,7 +370,7 @@ SILC_CLIENT_CMD_FUNC(nick_change) conn->nickname = strdup(cmd->argv[1]); conn->local_entry->nickname = conn->nickname; silc_idcache_add(conn->client_cache, strdup(cmd->argv[1]), - conn->local_entry->id, conn->local_entry, FALSE); + conn->local_entry->id, conn->local_entry, 0, NULL); COMMAND; } else { COMMAND_ERROR; diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 5b5ef427..a9d3ba70 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -492,7 +492,8 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd, /* Add server to cache */ silc_idcache_add(conn->server_cache, server_entry->server_name, - server_entry->server_id, (void *)server_entry, FALSE); + server_entry->server_id, (void *)server_entry, + 0, NULL); } else { server_entry = (SilcServerEntry)id_cache->context; } @@ -837,7 +838,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) /* Add it to the cache */ silc_idcache_add(conn->server_cache, server->server_name, - server->server_id, (void *)server, FALSE); + server->server_id, (void *)server, 0, NULL); if (SILC_ID_SERVER_COMPARE(server_id, conn->remote_id)) goto out; diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index 02f54cee..da646b52 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -587,7 +587,7 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn, /* Add client to cache, the non-formatted nickname is saved to cache */ if (!silc_idcache_add(conn->client_cache, nick, client_entry->id, - (void *)client_entry, FALSE)) { + (void *)client_entry, 0, NULL)) { silc_free(client_entry->nickname); silc_free(client_entry->username); silc_free(client_entry->hostname); @@ -629,7 +629,7 @@ void silc_client_update_client(SilcClient client, /* Remove the old cache entry and create a new one */ silc_idcache_del_by_context(conn->client_cache, client_entry); silc_idcache_add(conn->client_cache, nick, client_entry->id, - client_entry, FALSE); + client_entry, 0, NULL); } } diff --git a/lib/silccore/silcidcache.c b/lib/silccore/silcidcache.c index c4b658e8..5cf2533a 100644 --- a/lib/silccore/silcidcache.c +++ b/lib/silccore/silcidcache.c @@ -142,10 +142,9 @@ void silc_idcache_free(SilcIDCache cache) the entry never expires from the cache. */ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, - void *context, int expire) + void *context, int expire, SilcIDCacheEntry *ret) { SilcIDCacheEntry c; - uint32 curtime = time(NULL); SILC_LOG_DEBUG(("Adding cache entry")); @@ -153,7 +152,7 @@ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, c = silc_calloc(1, sizeof(*c)); c->id = id; c->name = name; - c->expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0); + c->expire = expire; c->context = context; /* Add the new entry to the hash tables */ @@ -173,6 +172,9 @@ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, silc_hash_table_rehash(cache->context_table, 0); } + if (ret) + *ret = c; + return TRUE; } diff --git a/lib/silccore/silcidcache.h b/lib/silccore/silcidcache.h index cadda8c0..e5c86a51 100644 --- a/lib/silccore/silcidcache.h +++ b/lib/silccore/silcidcache.h @@ -172,12 +172,15 @@ void silc_idcache_free(SilcIDCache cache); * Add new entry to the cache. Returns TRUE if the entry was added and * FALSE if it could not be added. The `name' is the name associated with * the ID, the `id' the actual ID and the `context' a used specific context. - * If the `expire' is TRUE the entry expires in default time and if FALSE - * the entry never expires from the cache. + * If the `expire' is non-zero the entry expires in that specified time. + * If zero the entry never expires from the cache. + * + * If the `ret' is non-NULL the created ID Cache entry is returned to + * that pointer. * ***/ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, - void *context, int expire); + void *context, int expire, SilcIDCacheEntry *ret); /****f* silccore/SilcIDCacheAPI/silc_idcache_del * diff --git a/prepare b/prepare index 9d1d8e08..bbd966f4 100755 --- a/prepare +++ b/prepare @@ -37,7 +37,7 @@ # SILC Distribution versions. Set here or give the version on the command # line as argument. # -SILC_VERSION=0.6.2 # Base version +SILC_VERSION=0.7 # Base version ############################################################################# diff --git a/silc_optimize b/silc_optimize index 655ac714..94ec41a0 100644 --- a/silc_optimize +++ b/silc_optimize @@ -45,6 +45,10 @@ o Library when necessary. This way we can move the data handling in one place. + o Add silc_id_str2id to accept the destination buffer as argument + and thus not require any memory allocation. Same will happen + with silc_id_payload_* functions. + o Server o When processing the decrypted and parsed packet we call the -- 2.24.0