From 20de1ca042541a59d9e41f70346154d7554e2e6c Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 20 Mar 2001 22:18:12 +0000 Subject: [PATCH] updates. --- CHANGES | 30 +++ TODO | 8 +- apps/silc/client_ops.c | 6 +- apps/silc/local_command.c | 4 +- apps/silcd/command.c | 282 +++++++++++++++++++------- apps/silcd/command_reply.c | 193 +++++++++++++++++- apps/silcd/command_reply.h | 4 +- apps/silcd/idlist.c | 40 +++- apps/silcd/idlist.h | 9 + apps/silcd/packet_receive.c | 23 ++- apps/silcd/server.c | 28 ++- apps/silcd/testi2.conf | 26 ++- doc/draft-riikonen-silc-spec-01.nroff | 4 +- lib/silcclient/client.c | 10 +- lib/silcclient/client_prvmsg.c | 4 +- lib/silcclient/command_reply.c | 13 +- lib/silccore/idcache.c | 12 +- lib/silccore/idcache.h | 7 +- 18 files changed, 575 insertions(+), 128 deletions(-) diff --git a/CHANGES b/CHANGES index 76b0bca5..af5bc741 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,33 @@ +Tue Mar 20 21:05:57 EET 2001 Pekka Riikonen + + * The client entry's data.registered must be TRUE even with + global client entry on global client list. The data.registered + is used to check whether the client is anymore in the network, + for example with WHOWAS command so it must be valid. + + * Fixed the WHOWAS command in the server. It now actually works + in router environment. Added function into silcd/command_reply.c + silc_server_command_reply_whowas_save. + + * Added silc_idlist_purge function to the silcd/idlist.c + to peridiocally purge the ID Cache. + + * Fixed INFO command in the server. It works now in router + environment. Added argument to the INFO command + reply. Updated the protocol specs. + + * Fixed minor bug in silc_idcache_purge to not purge if the + expire value is zero. + + * Fixed various bugs in WHOIS and IDENTIFY command handling as + they were buggy because of the WHOWAS information. + + * Fixed local command MSG to handle the async resolving of + the remote client properly. It used to fail the first MSG. + Affected file silc/local_command.c. + + * Added `data_len' field to SilcIDCache context. + Tue Mar 20 16:29:00 EET 2001 Pekka Riikonen * Update TODO. Todo in commands in the server. diff --git a/TODO b/TODO index be0898e9..482f0055 100644 --- a/TODO +++ b/TODO @@ -105,8 +105,6 @@ TODO In SILC Server o LIST is not implemented o RESTART is not implemented o INVITE is probably not working correctly - o INFO works only with local server. It must work with any - server in the network, implement the sending to other servers. o PING works only with local server. It must work with any server in the network, implement the sending to other servers. o MOTD works only with local server. It must work with any @@ -116,6 +114,12 @@ TODO In SILC Server Some of the modes may still not be implemented or is implemented the wrong way. Also, setting ban and invite lists does not work at all and requires some thinking how to do them. + o In servers all command reply funtions should still call the + pending command reply even if the reply was error. In client + it is not called but in server, I think, it must be called. + When implementing this check that all commands handle the + situation correctly when it is called as pending command + (it should most likely the that cmd->pending == TRUE/FALSE). o Packet processing can be made faster. All packet function in the packet_receive.c has same prototypes. Instead of calling those from diff --git a/apps/silc/client_ops.c b/apps/silc/client_ops.c index 2c3ac83d..0a9eb74d 100644 --- a/apps/silc/client_ops.c +++ b/apps/silc/client_ops.c @@ -413,7 +413,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, unsigned int idle, mode; SilcBuffer channels; - if (status == SILC_STATUS_ERR_NO_SUCH_NICK) { + 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); @@ -503,7 +504,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, char buf[1024], *nickname, *username, *realname; int len; - if (status == SILC_STATUS_ERR_NO_SUCH_NICK) { + 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); diff --git a/apps/silc/local_command.c b/apps/silc/local_command.c index 065da938..03293665 100644 --- a/apps/silc/local_command.c +++ b/apps/silc/local_command.c @@ -128,8 +128,8 @@ SILC_CLIENT_LCMD_FUNC(msg) if (!client_entry) { /* Client entry not found, it was requested thus mark this to be pending command. */ - silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 0, NULL, - silc_client_local_command_msg, context); + silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, + NULL, silc_client_local_command_msg, context); return; } diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 146c96a7..7fac79e7 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -487,6 +487,9 @@ silc_server_command_whois_check(SilcServerCommandContext cmd, for (i = 0; i < clients_count; i++) { entry = clients[i]; + if (entry->data.registered == FALSE) + continue; + if (!entry->nickname || !entry->username || !entry->userinfo) { SilcBuffer tmpbuf; unsigned short old_ident; @@ -544,12 +547,14 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd, for (i = 0; i < clients_count; i++) { entry = clients[i]; - if (entry->connection && entry->data.registered == FALSE) { - if (clients_count == 1) + if (entry->data.registered == FALSE) { + if (clients_count == 1) { + SilcBuffer idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT); silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS, - SILC_STATUS_ERR_NO_SUCH_NICK, - 3, entry->nickname, - strlen(entry->nickname)); + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + 2, idp->data, idp->len); + silc_buffer_free(idp); + } continue; } @@ -700,13 +705,13 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd) } } } else { - clients = silc_idlist_get_clients_by_nickname(server->local_list, - nick, server_name, - &clients_count); + clients = silc_idlist_get_clients_by_hash(server->local_list, + nick, server->md5hash, + &clients_count); if (!clients) - clients = silc_idlist_get_clients_by_hash(server->local_list, - nick, server->md5hash, - &clients_count); + clients = silc_idlist_get_clients_by_nickname(server->local_list, + nick, server_name, + &clients_count); } /* Check global list as well */ @@ -723,13 +728,13 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd) } } } else { - clients = silc_idlist_get_clients_by_nickname(server->global_list, - nick, server_name, - &clients_count); + clients = silc_idlist_get_clients_by_hash(server->global_list, + nick, server->md5hash, + &clients_count); if (!clients) - clients = silc_idlist_get_clients_by_hash(server->global_list, - nick, server->md5hash, - &clients_count); + clients = silc_idlist_get_clients_by_nickname(server->global_list, + nick, server_name, + &clients_count); } } @@ -810,13 +815,13 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd) } } } else { - clients = silc_idlist_get_clients_by_nickname(server->local_list, - nick, server_name, - &clients_count); + clients = silc_idlist_get_clients_by_hash(server->local_list, + nick, server->md5hash, + &clients_count); if (!clients) - clients = silc_idlist_get_clients_by_hash(server->local_list, - nick, server->md5hash, - &clients_count); + clients = silc_idlist_get_clients_by_nickname(server->local_list, + nick, server_name, + &clients_count); } /* If we are router we will check our global list as well. */ @@ -833,13 +838,13 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd) } } } else { - clients = silc_idlist_get_clients_by_nickname(server->global_list, - nick, server_name, - &clients_count); + clients = silc_idlist_get_clients_by_hash(server->global_list, + nick, server->md5hash, + &clients_count); if (!clients) - clients = silc_idlist_get_clients_by_hash(server->global_list, - nick, server->md5hash, - &clients_count); + clients = silc_idlist_get_clients_by_nickname(server->global_list, + nick, server_name, + &clients_count); } } @@ -950,6 +955,52 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd, return TRUE; } +static char +silc_server_command_whowas_check(SilcServerCommandContext cmd, + SilcClientEntry *clients, + unsigned int clients_count) +{ + SilcServer server = cmd->server; + int i; + SilcClientEntry entry; + + for (i = 0; i < clients_count; i++) { + entry = clients[i]; + + if (!entry->nickname || !entry->username) { + SilcBuffer tmpbuf; + unsigned short old_ident; + + if (!entry->router) + continue; + + old_ident = silc_command_get_ident(cmd->payload); + silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng)); + tmpbuf = silc_command_payload_encode_payload(cmd->payload); + + /* Send WHOWAS command */ + silc_server_packet_send(server, entry->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_WHOWAS, + silc_command_get_ident(cmd->payload), + silc_server_command_destructor, + silc_server_command_whowas, + silc_server_command_dup(cmd)); + cmd->pending = TRUE; + + silc_command_set_ident(cmd->payload, old_ident); + + silc_buffer_free(tmpbuf); + return FALSE; + } + } + + return TRUE; +} + static void silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, SilcClientEntry *clients, @@ -963,6 +1014,7 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, SilcCommandStatus status; unsigned short ident = silc_command_get_ident(cmd->payload); char found = FALSE; + char nh[256], uh[256]; status = SILC_STATUS_OK; if (clients_count > 1) @@ -999,27 +1051,25 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT); tmp = silc_argument_get_first_arg(cmd->args, NULL); - { - char nh[256], uh[256]; - - memset(uh, 0, sizeof(uh)); - memset(nh, 0, sizeof(nh)); + memset(uh, 0, sizeof(uh)); + memset(nh, 0, sizeof(nh)); - strncat(nh, entry->nickname, strlen(entry->nickname)); - if (!strchr(entry->nickname, '@')) { - strncat(nh, "@", 1); - len = entry->router ? strlen(entry->router->server_name) : - strlen(server->server_name); - strncat(nh, entry->router ? entry->router->server_name : - server->server_name, len); - } + strncat(nh, entry->nickname, strlen(entry->nickname)); + if (!strchr(entry->nickname, '@')) { + strncat(nh, "@", 1); + len = entry->router ? strlen(entry->router->server_name) : + strlen(server->server_name); + strncat(nh, entry->router ? entry->router->server_name : + server->server_name, len); + } - strncat(uh, entry->username, strlen(entry->username)); - if (!strchr(entry->username, '@')) { - strncat(uh, "@", 1); - strcat(uh, "*private*"); - } + strncat(uh, entry->username, strlen(entry->username)); + if (!strchr(entry->username, '@')) { + strncat(uh, "@", 1); + strcat(uh, "*private*"); + } + if (entry->userinfo) packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS, status, ident, 4, @@ -1028,8 +1078,14 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, 4, uh, strlen(uh), 5, entry->userinfo, strlen(entry->userinfo)); - } - + else + packet = + silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS, + status, ident, 3, + 2, idp->data, idp->len, + 3, nh, strlen(nh), + 4, uh, strlen(uh)); + silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -1076,7 +1132,7 @@ silc_server_command_whowas_from_client(SilcServerCommandContext cmd) silc_server_command_pending(server, SILC_COMMAND_WHOWAS, silc_command_get_ident(cmd->payload), silc_server_command_destructor, - silc_server_command_whois, + silc_server_command_whowas, silc_server_command_dup(cmd)); cmd->pending = TRUE; @@ -1114,11 +1170,8 @@ silc_server_command_whowas_from_client(SilcServerCommandContext cmd) &clients_count); } - if (!clients) { - /* Such client(s) really does not exist in the SILC network. */ - silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS, - SILC_STATUS_ERR_NO_SUCH_NICK, - 3, nick, strlen(nick)); + if (!silc_server_command_whowas_check(cmd, clients, clients_count)) { + ret = -1; goto out; } @@ -1234,6 +1287,9 @@ silc_server_command_identify_check(SilcServerCommandContext cmd, for (i = 0; i < clients_count; i++) { entry = clients[i]; + if (entry->data.registered == FALSE) + continue; + if (!entry->nickname) { SilcBuffer tmpbuf; unsigned short old_ident; @@ -1293,12 +1349,14 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, for (i = 0; i < clients_count; i++) { entry = clients[i]; - if (entry->connection && entry->data.registered == FALSE) { - if (clients_count == 1) + if (entry->data.registered == FALSE) { + if (clients_count == 1) { + SilcBuffer idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT); silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, - SILC_STATUS_ERR_NO_SUCH_NICK, - 3, entry->nickname, - strlen(entry->nickname)); + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + 2, idp->data, idp->len); + silc_buffer_free(idp); + } continue; } @@ -1709,7 +1767,8 @@ SILC_SERVER_CMD_FUNC(nick) /* Update client cache */ silc_idcache_add(server->local_list->clients, client->nickname, - SILC_ID_CLIENT, client->id, (void *)client, TRUE, FALSE); + strlen(client->nickname), SILC_ID_CLIENT, client->id, + (void *)client, TRUE, FALSE); nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); @@ -2164,7 +2223,9 @@ SILC_SERVER_CMD_FUNC(info) SilcServerCommandContext cmd = (SilcServerCommandContext)context; SilcServer server = cmd->server; SilcBuffer packet, idp; - char info_string[256], *dest_server; + char *dest_server, *server_info = NULL, *server_name; + unsigned short ident = silc_command_get_ident(cmd->payload); + SilcServerEntry entry = NULL; SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 1); @@ -2178,6 +2239,8 @@ SILC_SERVER_CMD_FUNC(info) if (!strncasecmp(dest_server, server->server_name, strlen(dest_server))) { /* Send our reply */ + char info_string[256]; + memset(info_string, 0, sizeof(info_string)); snprintf(info_string, sizeof(info_string), "location: %s server: %s admin: %s <%s>", @@ -2186,30 +2249,93 @@ SILC_SERVER_CMD_FUNC(info) server->config->admin_info->admin_name, server->config->admin_info->admin_email); - idp = silc_id_payload_encode(server->id, SILC_ID_SERVER); - - packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO, - SILC_STATUS_OK, 0, 2, - 2, idp->data, idp->len, - 3, info_string, - strlen(info_string)); - silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, - packet->data, packet->len, FALSE); - - silc_buffer_free(packet); - silc_buffer_free(idp); + server_info = info_string; + entry = server->id_entry; } else { - /* Send this command to the requested server */ + /* Check whether we have this server cached */ + entry = silc_idlist_find_server_by_name(server->global_list, + dest_server, NULL); + if (!entry) { + entry = silc_idlist_find_server_by_name(server->local_list, + dest_server, NULL); + } - if (server->server_type == SILC_SERVER && !server->standalone) { + if (server->server_type == SILC_ROUTER && entry && !entry->server_info) { + /* Send to the server */ + SilcBuffer tmpbuf; + unsigned short old_ident; + old_ident = silc_command_get_ident(cmd->payload); + silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng)); + tmpbuf = silc_command_payload_encode_payload(cmd->payload); + + silc_server_packet_send(server, entry->connection, + SILC_PACKET_COMMAND, cmd->packet->flags, + tmpbuf->data, tmpbuf->len, TRUE); + + /* Reprocess this packet after received reply from router */ + silc_server_command_pending(server, SILC_COMMAND_INFO, + silc_command_get_ident(cmd->payload), + silc_server_command_destructor, + silc_server_command_info, + silc_server_command_dup(cmd)); + cmd->pending = TRUE; + silc_command_set_ident(cmd->payload, old_ident); + silc_buffer_free(tmpbuf); + return; } - if (server->server_type == SILC_ROUTER) { + if (!entry && !cmd->pending && !server->standalone) { + /* Send to the primary router */ + SilcBuffer tmpbuf; + unsigned short old_ident; + old_ident = silc_command_get_ident(cmd->payload); + silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng)); + tmpbuf = silc_command_payload_encode_payload(cmd->payload); + + 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 from router */ + silc_server_command_pending(server, SILC_COMMAND_INFO, + silc_command_get_ident(cmd->payload), + silc_server_command_destructor, + silc_server_command_info, + silc_server_command_dup(cmd)); + cmd->pending = TRUE; + silc_command_set_ident(cmd->payload, old_ident); + silc_buffer_free(tmpbuf); + return; } } - + + if (!entry) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO, + SILC_STATUS_ERR_NO_SUCH_SERVER); + goto out; + } + + idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER); + if (!server_info) + server_info = entry->server_info; + server_name = dest_server; + + /* Send the reply */ + packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO, + SILC_STATUS_OK, ident, 3, + 2, idp->data, idp->len, + 3, server_name, + strlen(server_name), + 4, server_info, + strlen(server_info)); + silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, + packet->data, packet->len, FALSE); + + silc_buffer_free(packet); + silc_buffer_free(idp); + out: silc_server_command_free(cmd); } diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 45d0c460..6dac16d1 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -50,9 +50,11 @@ do { \ they are never sent by server. More maybe added later if need appears. */ SilcServerCommandReply silc_command_reply_list[] = { - SILC_SERVER_CMD_REPLY(join, JOIN), SILC_SERVER_CMD_REPLY(whois, WHOIS), + SILC_SERVER_CMD_REPLY(whowas, WHOWAS), SILC_SERVER_CMD_REPLY(identify, IDENTIFY), + SILC_SERVER_CMD_REPLY(info, INFO), + SILC_SERVER_CMD_REPLY(join, JOIN), SILC_SERVER_CMD_REPLY(users, USERS), { NULL, 0 }, @@ -192,6 +194,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) if (!client) return FALSE; + client->data.registered = TRUE; client->mode = mode; } else { /* We have the client already, update the data */ @@ -221,6 +224,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) if (cache) { cache->data = nick; + cache->data_len = strlen(nick); silc_idcache_sort_by_data(global ? server->global_list->clients : server->local_list->clients); } @@ -255,6 +259,127 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) silc_server_command_reply_free(cmd); } +/* Caches the received WHOWAS information for a short period of time. */ + +static char +silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) +{ + SilcServer server = cmd->server; + int len, id_len; + unsigned char *id_data; + char *nickname, *username, *realname; + SilcClientID *client_id; + SilcClientEntry client; + SilcIDCacheEntry cache = NULL; + char *nick; + int global = FALSE; + + id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len); + nickname = silc_argument_get_arg_type(cmd->args, 3, &len); + username = silc_argument_get_arg_type(cmd->args, 4, &len); + if (!id_data || !nickname || !username) + return FALSE; + + realname = silc_argument_get_arg_type(cmd->args, 5, &len); + + client_id = silc_id_payload_parse_id(id_data, id_len); + if (!client_id) + return FALSE; + + /* Check if we have this client cached already. */ + + client = silc_idlist_find_client_by_id(server->local_list, client_id, + &cache); + if (!client) { + client = silc_idlist_find_client_by_id(server->global_list, + client_id, &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. */ + if (server->server_type == SILC_ROUTER) + return FALSE; + + /* 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. */ + 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); + if (!client) + return FALSE; + + client->data.registered = FALSE; + client = silc_idlist_find_client_by_id(server->global_list, + client_id, &cache); + cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + } else { + /* We have the client already, update the data */ + + /* 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); + } + + if (client->nickname) + silc_free(client->nickname); + if (client->username) + silc_free(client->username); + + client->nickname = nick; + client->username = strdup(username); + + if (cache) { + cache->data = nick; + cache->data_len = strlen(nick); + silc_idcache_sort_by_data(global ? server->global_list->clients : + server->local_list->clients); + } + } + + silc_free(client_id); + + return TRUE; +} + +/* Received reply for WHOWAS command. Cache the client information only for + a short period of time. */ + +SILC_SERVER_CMD_REPLY_FUNC(whowas) +{ + SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; + SilcCommandStatus status; + + COMMAND_CHECK_STATUS_LIST; + + if (!silc_server_command_reply_whowas_save(cmd)) + goto out; + + /* Execute any pending commands */ + SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_WHOWAS); + + out: + SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_WHOWAS); + silc_server_command_reply_free(cmd); +} + /* Caches the received IDENTIFY information. */ static char @@ -310,9 +435,10 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) /* 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, - username ? strdup(username) : NULL, NULL, - client_id, cmd->sock->user_data, NULL); + client = silc_idlist_add_client(server->global_list, nick, + username ? strdup(username) : NULL, NULL, + client_id, cmd->sock->user_data, NULL); + client->data.registered = TRUE; } else { /* We have the client already, update the data */ @@ -342,6 +468,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) if (nickname && cache) { cache->data = nick; + cache->data_len = strlen(nick); silc_idcache_sort_by_data(global ? server->global_list->clients : server->local_list->clients); } @@ -375,6 +502,64 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) silc_server_command_reply_free(cmd); } +/* Received reply fro INFO command. Cache the server and its information */ + +SILC_SERVER_CMD_REPLY_FUNC(info) +{ + SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; + SilcServer server = cmd->server; + SilcCommandStatus status; + SilcServerEntry entry; + SilcServerID *server_id; + unsigned int tmp_len; + unsigned char *tmp, *name; + + COMMAND_CHECK_STATUS; + + /* Get Server ID */ + tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (!tmp) + goto out; + server_id = silc_id_payload_parse_id(tmp, tmp_len); + if (!server_id) + goto out; + + /* Get the info string */ + name = silc_argument_get_arg_type(cmd->args, 3, &tmp_len); + if (tmp_len > 256) + goto out; + + entry = silc_idlist_find_server_by_id(server->local_list, server_id, NULL); + if (!entry) { + entry = silc_idlist_find_server_by_id(server->global_list, server_id, + NULL); + if (!entry) { + /* Add the server to global list */ + server_id = silc_id_dup(server_id, SILC_ID_SERVER); + entry = silc_idlist_add_server(server->global_list, name, 0, + server_id, NULL, NULL); + if (!entry) { + silc_free(server_id); + goto out; + } + } + } + + /* Get the info string */ + tmp = silc_argument_get_arg_type(cmd->args, 4, &tmp_len); + if (tmp_len > 256) + tmp = NULL; + + entry->server_info = tmp ? strdup(tmp) : NULL; + + /* Execute any pending commands */ + SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_INFO); + + out: + SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_INFO); + silc_server_command_reply_free(cmd); +} + /* Received reply for forwarded JOIN command. Router has created or joined the client to the channel. We save some channel information locally for future use. */ diff --git a/apps/silcd/command_reply.h b/apps/silcd/command_reply.h index 23c1fe6b..0726f108 100644 --- a/apps/silcd/command_reply.h +++ b/apps/silcd/command_reply.h @@ -61,9 +61,11 @@ void silc_server_command_reply_free(SilcServerCommandReplyContext cmd); void silc_server_command_reply_process(SilcServer server, SilcSocketConnection sock, SilcBuffer buffer); -SILC_SERVER_CMD_REPLY_FUNC(join); SILC_SERVER_CMD_REPLY_FUNC(whois); +SILC_SERVER_CMD_REPLY_FUNC(whowas); SILC_SERVER_CMD_REPLY_FUNC(identify); +SILC_SERVER_CMD_REPLY_FUNC(info); +SILC_SERVER_CMD_REPLY_FUNC(join); SILC_SERVER_CMD_REPLY_FUNC(users); #endif diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index aca1c281..6d0b9030 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -68,6 +68,21 @@ void silc_idlist_del_data(void *entry) silc_pkcs_public_key_free(idata->public_key); } +/* Purges ID cache */ + +SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge) +{ + SilcIDListPurge i = (SilcIDListPurge)context; + + SILC_LOG_DEBUG(("Start")); + + silc_idcache_purge(i->cache); + silc_task_register(i->timeout_queue, 0, + silc_idlist_purge, + (void *)i, 600, 0, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); +} + /****************************************************************************** Server entry functions @@ -96,8 +111,10 @@ silc_idlist_add_server(SilcIDList id_list, server->router = router; server->connection = connection; - if (!silc_idcache_add(id_list->servers, server->server_name, SILC_ID_SERVER, - (void *)server->id, (void *)server, TRUE, FALSE)) { + if (!silc_idcache_add(id_list->servers, server->server_name, + server->server_name ? strlen(server->server_name) : 0, + SILC_ID_SERVER, (void *)server->id, + (void *)server, TRUE, FALSE)) { silc_free(server); return NULL; } @@ -151,6 +168,8 @@ silc_idlist_find_server_by_name(SilcIDList id_list, char *name, if (ret_entry) *ret_entry = id_cache; + SILC_LOG_DEBUG(("Found")); + return server; } @@ -225,6 +244,8 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id, server->id = new_id; id_cache->id = (void *)new_id; + SILC_LOG_DEBUG(("Found")); + return server; } @@ -283,8 +304,10 @@ silc_idlist_add_client(SilcIDList id_list, unsigned char *nickname, silc_list_init(client->channels, struct SilcChannelClientEntryStruct, client_list); - if (!silc_idcache_add(id_list->clients, nickname, SILC_ID_CLIENT, - (void *)client->id, (void *)client, TRUE, FALSE)) { + if (!silc_idcache_add(id_list->clients, nickname, + nickname ? strlen(nickname) : 0, + SILC_ID_CLIENT, (void *)client->id, + (void *)client, TRUE, FALSE)) { silc_free(client); return NULL; } @@ -335,6 +358,8 @@ silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname, SilcClientEntry *clients; int i; + SILC_LOG_DEBUG(("Start")); + if (!silc_idcache_find_by_data(id_list->clients, nickname, &list)) return NULL; @@ -369,6 +394,8 @@ silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname, unsigned char hash[32]; int i; + SILC_LOG_DEBUG(("Start")); + silc_hash_make(md5hash, nickname, strlen(nickname), hash); if (!silc_idcache_find_by_data(id_list->clients, hash, &list)) @@ -608,8 +635,9 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, channel_list); if (!silc_idcache_add(id_list->channels, channel->channel_name, - SILC_ID_CHANNEL, (void *)channel->id, - (void *)channel, TRUE, FALSE)) { + channel->channel_name ? strlen(channel->channel_name) : + 0, SILC_ID_CHANNEL, + (void *)channel->id, (void *)channel, TRUE, FALSE)) { silc_free(channel); return NULL; } diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index bcd3c3f1..59d6282d 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -26,6 +26,13 @@ typedef struct SilcServerEntryStruct *SilcServerEntry; typedef struct SilcClientEntryStruct *SilcClientEntry; typedef struct SilcChannelEntryStruct *SilcChannelEntry; +/* Context for holding cache information to periodically purge + the cache. */ +typedef struct { + SilcIDCache cache; + void *timeout_queue; +} *SilcIDListPurge; + /* Generic ID list data structure. @@ -126,6 +133,7 @@ struct SilcServerEntryStruct { char *server_name; int server_type; SilcServerID *id; + char *server_info; /* Pointer to the router */ SilcServerEntry router; @@ -460,6 +468,7 @@ typedef struct { /* Prototypes */ void silc_idlist_add_data(void *entry, SilcIDListData idata); void silc_idlist_del_data(void *entry); +SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge); SilcServerEntry silc_idlist_add_server(SilcIDList id_list, char *server_name, int server_type, diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index e01f55f6..98fb540b 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -42,6 +42,7 @@ void silc_server_notify(SilcServer server, SilcChannelEntry channel; SilcClientEntry client; SilcChannelClientEntry chl; + SilcIDCacheEntry cache; unsigned int mode; unsigned char *tmp; unsigned int tmp_len; @@ -154,6 +155,8 @@ void silc_server_notify(SilcServer server, silc_free(client_id); goto out; } + + client->data.registered = TRUE; } } @@ -251,10 +254,10 @@ void silc_server_notify(SilcServer server, /* Get client entry */ client = silc_idlist_find_client_by_id(server->global_list, - client_id, NULL); + client_id, &cache); if (!client) { client = silc_idlist_find_client_by_id(server->local_list, - client_id, NULL); + client_id, &cache); if (!client) { silc_free(client_id); goto out; @@ -270,9 +273,14 @@ void silc_server_notify(SilcServer server, /* Remove the client from all channels */ silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE); + client->data.registered = FALSE; + cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + +#if 0 /* Remove the client entry */ if (!silc_idlist_del_client(server->global_list, client)) silc_idlist_del_client(server->local_list, client); +#endif break; case SILC_NOTIFY_TYPE_TOPIC_SET: @@ -1142,7 +1150,7 @@ SilcServerEntry silc_server_new_server(SilcServer server, SilcServerID *server_id; SilcIDListData idata; unsigned char *server_name, *id_string; - unsigned short id_len; + unsigned short id_len, name_len; int ret; SILC_LOG_DEBUG(("Creating new server")); @@ -1165,7 +1173,8 @@ SilcServerEntry silc_server_new_server(SilcServer server, /* Parse the incoming packet */ ret = silc_buffer_unformat(buffer, SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len), - SILC_STR_UI16_STRING_ALLOC(&server_name), + SILC_STR_UI16_NSTRING_ALLOC(&server_name, + &name_len), SILC_STR_END); if (ret == -1) { if (id_string) @@ -1181,6 +1190,9 @@ SilcServerEntry silc_server_new_server(SilcServer server, return NULL; } + if (name_len > 256) + server_name[255] = '\0'; + /* Get Server ID */ server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER); if (!server_id) { @@ -1289,13 +1301,14 @@ static void silc_server_new_id_real(SilcServer server, list. The client is put to global list and we will take the hash value of the Client ID and save it to the ID Cache system for fast searching in the future. */ - hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), + hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), sizeof(unsigned char)); memcpy(hash, ((SilcClientID *)id)->hash, sizeof(((SilcClientID *)id)->hash)); entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, router, NULL); entry->nickname = NULL; + entry->data.registered = TRUE; if (sock->type == SILC_SOCKET_TYPE_SERVER) server->stat.cell_clients++; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 87ceee96..999c24b6 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -113,6 +113,7 @@ int silc_server_init(SilcServer server) int *sock = NULL, sock_count = 0, i; SilcServerID *id; SilcServerEntry id_entry; + SilcIDListPurge purge; SILC_LOG_DEBUG(("Initializing server")); assert(server); @@ -335,6 +336,27 @@ int silc_server_init(SilcServer server) if (server->config->servers) server->server_type = SILC_ROUTER; + /* Register the ID Cache purge task. This periodically purges the ID cache + and removes the expired cache entries. */ + + /* Clients local list */ + purge = silc_calloc(1, sizeof(*purge)); + purge->cache = server->local_list->clients; + purge->timeout_queue = server->timeout_queue; + silc_task_register(purge->timeout_queue, 0, + silc_idlist_purge, + (void *)purge, 600, 0, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); + + /* Clients global list */ + purge = silc_calloc(1, sizeof(*purge)); + purge->cache = server->global_list->clients; + purge->timeout_queue = server->timeout_queue; + silc_task_register(purge->timeout_queue, 0, + silc_idlist_purge, + (void *)purge, 300, 0, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); + SILC_LOG_DEBUG(("Server initialized")); /* We are done here, return succesfully */ @@ -3087,6 +3109,8 @@ void silc_server_save_users_on_channel(SilcServer server, silc_free(client_id); continue; } + + client->data.registered = TRUE; } silc_free(client_id); @@ -3215,6 +3239,8 @@ SilcBuffer silc_server_get_client_channel_list(SilcServer server, silc_free(cid); } - silc_buffer_push(buffer, buffer->data - buffer->head); + if (buffer) + silc_buffer_push(buffer, buffer->data - buffer->head); + return buffer; } diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 9948361e..7140f118 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -1,17 +1,23 @@ [Cipher] -rc6:../lib/silcsim/modules/rc6.sim.so:16:16 -twofish:../lib/silcsim/modules/twofish.sim.so:16:16 -mars:../lib/silcsim/modules/mars.sim.so:16:16 +aes-256-cbc:../lib/silcsim/modules/aes.sim.so:32:16 +aes-192-cbc:../lib/silcsim/modules/aes.sim.so:24:16 +aes-128-cbc:../lib/silcsim/modules/aes.sim.so:16:16 +twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16 +twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16 +twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16 +mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16 +mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16 +mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16 none:../lib/silcsim/modules/none.sim.so:0:0 -[Hash] +[Hash] md5::64:16 sha1::64:20 [hmac] hmac-sha1-96:sha1:12 hmac-md5-96:md5:12 -hmac-sha1:sha1:20 +hmac-sha1:sha1:20 hmac-md5:md5:16 #[PKCS] @@ -25,10 +31,10 @@ nobody:nobody Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi [ServerInfo] -lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334 +silc:212.146.42.253:Kuopio, Finland:1334 [ListenPort] -10.2.1.7:10.2.1.7:1334 +212.146.42.253:212.146.42.253:1334 [Logging] infologfile:silcd2.log:10000 @@ -47,13 +53,13 @@ errorlogfile:silcd2.log:10000 :::1336:1 [AdminConnection] -*:silc:silc:passwd:testi +*:priikone:*:passwd:testi [ServerConnection] -10.2.1.7:passwd:priikone:1333:1:1 +212.146.42.253:passwd:priikone:1336:1:1 [RouterConnection] -10.2.1.7:passwd:priikone:1335:1:1:0 +212.146.42.253:passwd:priikone:1335:1:1:0 [DenyConnection] [RedirectClient] diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index 5a4799bd..8c238d8c 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -2362,9 +2362,9 @@ List of all defined commands in SILC follows. Reply messages to the command: - Max Arguments: 3 + Max Arguments: 4 Arguments: (1) (2) - (3) + (3) (4) This command replies with the Server ID of the server and a string which tells the information about the server. diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index ed9bc13a..ae08c2ff 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -1128,8 +1128,9 @@ void silc_client_receive_new_id(SilcClient client, conn->local_entry->id = conn->local_id; /* Put it to the ID cache */ - silc_idcache_add(conn->client_cache, conn->nickname, SILC_ID_CLIENT, - conn->local_id, (void *)conn->local_entry, TRUE, FALSE); + silc_idcache_add(conn->client_cache, conn->nickname, strlen(conn->nickname), + SILC_ID_CLIENT, conn->local_id, (void *)conn->local_entry, + TRUE, FALSE); /* Notify application of successful connection. We do it here now that we've received the Client ID and are allowed to send traffic. */ @@ -1161,8 +1162,9 @@ SilcChannelEntry silc_client_new_channel_id(SilcClient client, conn->current_channel = channel; /* Put it to the ID cache */ - silc_idcache_add(conn->channel_cache, channel_name, SILC_ID_CHANNEL, - (void *)channel->id, (void *)channel, TRUE, FALSE); + silc_idcache_add(conn->channel_cache, channel_name, strlen(channel_name), + SILC_ID_CHANNEL, (void *)channel->id, (void *)channel, + TRUE, FALSE); return channel; } diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 3fe00aaf..c9d198c4 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -177,8 +177,8 @@ void silc_client_private_message(SilcClient client, /* Save the client to cache */ silc_idcache_add(conn->client_cache, remote_client->nickname, - SILC_ID_CLIENT, remote_client->id, remote_client, - TRUE, TRUE); + strlen(remote_client->nickname), SILC_ID_CLIENT, + remote_client->id, remote_client, TRUE, TRUE); } else { remote_client = (SilcClientEntry)id_cache->context; } diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index ec64040b..91579710 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -264,6 +264,7 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd, /* Add client to cache */ silc_idcache_add(conn->client_cache, client_entry->nickname, + strlen(client_entry->nickname), SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE, FALSE); } else { @@ -287,6 +288,7 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd, client_entry->realname = strdup(realname); id_cache->data = client_entry->nickname; + id_cache->data_len = strlen(client_entry->nickname); silc_idcache_sort_by_data(conn->client_cache); silc_free(client_id); @@ -462,6 +464,7 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd, /* Add client to cache */ silc_idcache_add(conn->client_cache, client_entry->nickname, + strlen(client_entry->nickname), SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE, FALSE); } else { @@ -482,6 +485,7 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd, client_entry->username = strdup(username); id_cache->data = client_entry->nickname; + id_cache->data_len = strlen(client_entry->nickname); silc_idcache_sort_by_data(conn->client_cache); silc_free(client_id); @@ -749,11 +753,16 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) /* XXX save server id */ - /* Get server info */ + /* Get server name */ tmp = silc_argument_get_arg_type(cmd->args, 3, NULL); if (!tmp) goto out; + /* Get server info */ + tmp = silc_argument_get_arg_type(cmd->args, 4, NULL); + if (!tmp) + goto out; + client->ops->say(cmd->client, conn, "Info: %s", tmp); /* Notify application */ @@ -970,7 +979,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) /* No, we don't have it, add entry for it. */ client_entry = silc_calloc(1, sizeof(*client_entry)); client_entry->id = silc_id_dup(client_id, SILC_ID_CLIENT); - silc_idcache_add(conn->client_cache, NULL, SILC_ID_CLIENT, + silc_idcache_add(conn->client_cache, NULL, 0, SILC_ID_CLIENT, client_entry->id, (void *)client_entry, FALSE, FALSE); } else { /* Yes, we have it already */ diff --git a/lib/silccore/idcache.c b/lib/silccore/idcache.c index 6c836514..5d8d793c 100644 --- a/lib/silccore/idcache.c +++ b/lib/silccore/idcache.c @@ -200,7 +200,7 @@ int silc_idcache_find_by_data(SilcIDCache cache, unsigned char *data, break; if (cache->cache[i].data && - !memcmp(cache->cache[i].data, data, strlen(cache->cache[i].data))) + !memcmp(cache->cache[i].data, data, cache->cache[i].data_len)) silc_idcache_list_add(list, &(cache->cache[i])); } @@ -236,7 +236,7 @@ int silc_idcache_find_by_data_one(SilcIDCache cache, unsigned char *data, for (i = i; i < cache->cache_count; i++) if (cache->cache[i].data && - !memcmp(cache->cache[i].data, data, strlen(cache->cache[i].data))) { + !memcmp(cache->cache[i].data, data, cache->cache[i].data_len)) { if (ret) *ret = &(cache->cache[i]); return TRUE; @@ -391,8 +391,8 @@ int silc_idcache_find_by_context(SilcIDCache cache, void *context, however, it is not mandatory. */ int silc_idcache_add(SilcIDCache cache, unsigned char *data, - SilcIdType id_type, void *id, void *context, int sort, - int expire) + unsigned int data_len, SilcIdType id_type, void *id, + void *context, int sort, int expire) { int i; unsigned int count; @@ -420,6 +420,7 @@ int silc_idcache_add(SilcIDCache cache, unsigned char *data, for (i = 0; i < count; i++) { if (c[i].data == NULL && c[i].id == NULL) { c[i].data = data; + c[i].data_len = data_len; c[i].type = id_type; c[i].id = id; c[i].expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0); @@ -435,6 +436,7 @@ int silc_idcache_add(SilcIDCache cache, unsigned char *data, c[i].id = NULL; } c[count].data = data; + c[count].data_len = data_len; c[count].type = id_type; c[count].id = id; c[count].expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0); @@ -521,7 +523,7 @@ int silc_idcache_purge(SilcIDCache cache) c = cache->cache; for (i = 0; i < cache->cache_count; i++) { - if (c[i].data && c[i].expire < curtime) { + if (c[i].data && c[i].expire && c[i].expire < curtime) { /* Call the destructor */ if (cache->destructor) diff --git a/lib/silccore/idcache.h b/lib/silccore/idcache.h index 492ecfb7..84682bb0 100644 --- a/lib/silccore/idcache.h +++ b/lib/silccore/idcache.h @@ -30,6 +30,7 @@ allocate any of these fields nor free them. unsigned char *data + unsigned int data_len; The data that is usually used to find the data from the cache. For example for Client ID's this is nickname. @@ -56,6 +57,7 @@ */ typedef struct { unsigned char *data; + unsigned int data_len; SilcIdType type; void *id; unsigned long expire; @@ -78,6 +80,7 @@ typedef void (*SilcIDCacheDestructor)(SilcIDCache cache, #define SILC_ID_CACHE_ANY ((void *)1) #define SILC_ID_CACHE_EXPIRE 3600 +#define SILC_ID_CACHE_EXPIRE_DEF (time(NULL) + SILC_ID_CACHE_EXPIRE) /* Prototypes */ SilcIDCache silc_idcache_alloc(unsigned int count, @@ -97,8 +100,8 @@ int silc_idcache_find_by_id_one(SilcIDCache cache, void *id, SilcIdType type, int silc_idcache_find_by_context(SilcIDCache cache, void *context, SilcIDCacheEntry *ret); int silc_idcache_add(SilcIDCache cache, unsigned char *data, - SilcIdType id_type, void *id, void *context, int sort, - int expire); + unsigned int data_len, SilcIdType id_type, void *id, + void *context, int sort, int expire); int silc_idcache_del(SilcIDCache cache, SilcIDCacheEntry old); int silc_idcache_del_by_data(SilcIDCache cache, unsigned char *data); int silc_idcache_del_by_id(SilcIDCache cache, SilcIdType type, void *id); -- 2.43.0