X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fcommand_reply.c;h=9b18d11afb11e7eccc6b295c8d8384b705a91319;hp=eec802895db6798bc068583f0ec960f86613af60;hb=e5d8d3db6caa344b3d419b884556c21b15e7d123;hpb=9f970cc72baeeb416f7fbdb32b36ffaf88d0ea4b diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index eec80289..9b18d11a 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -93,8 +93,10 @@ void silc_server_command_reply_process(SilcServer server, ident = silc_command_get_ident(ctx->payload); /* Check for pending commands and mark to be exeucted */ - silc_server_command_pending_check(server, ctx, - silc_command_get(ctx->payload), ident); + ctx->callbacks = + silc_server_command_pending_check(server, ctx, + silc_command_get(ctx->payload), + ident, &ctx->callbacks_count); /* Execute command reply */ command = silc_command_get(ctx->payload); @@ -107,7 +109,7 @@ void silc_server_command_reply_process(SilcServer server, return; } - cmd->cb(ctx); + cmd->cb(ctx, NULL); } /* Free command reply context and its internals. */ @@ -115,9 +117,10 @@ void silc_server_command_reply_process(SilcServer server, void silc_server_command_reply_free(SilcServerCommandReplyContext cmd) { if (cmd) { - silc_command_free_payload(cmd->payload); + silc_command_payload_free(cmd->payload); if (cmd->sock) silc_socket_free(cmd->sock); /* Decrease the reference counter */ + silc_free(cmd->callbacks); silc_free(cmd); } } @@ -132,7 +135,6 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) char *nickname, *username, *realname, *servername = NULL; SilcClientID *client_id; SilcClientEntry client; - SilcIDCacheEntry cache = NULL; char global = FALSE; char *nick; uint32 mode = 0, len, id_len; @@ -159,42 +161,38 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) /* Check if we have this client cached already. */ - client = silc_idlist_find_client_by_id(server->local_list, client_id, - &cache); + client = silc_idlist_find_client_by_id(server->local_list, client_id, + FALSE, NULL); if (!client) { - client = silc_idlist_find_client_by_id(server->global_list, - client_id, &cache); + client = silc_idlist_find_client_by_id(server->global_list, client_id, + FALSE, NULL); 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) + if (server->server_type != SILC_SERVER) 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)); - servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char)); - memcpy(nick, nickname, len); - memcpy(servername, nickname + len + 1, strlen(nickname) - len); - } else { - nick = strdup(nickname); - } + silc_parse_userfqdn(nickname, &nick, &servername); /* 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, strlen(nick), + client = silc_idlist_add_client(server->global_list, nick, strdup(username), strdup(realname), client_id, cmd->sock->user_data, NULL); - if (!client) + if (!client) { + SILC_LOG_ERROR(("Could not add new client to the ID Cache")); return FALSE; + } - client->data.registered = TRUE; + client->data.status |= + (SILC_IDLIST_STATUS_REGISTERED | SILC_IDLIST_STATUS_RESOLVED); + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; client->mode = mode; client->servername = servername; } else { @@ -203,36 +201,29 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) SILC_LOG_DEBUG(("Updating client 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)); - servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char)); - memcpy(nick, nickname, len); - memcpy(servername, nickname + len + 1, strlen(nickname) - len); - } else { - nick = strdup(nickname); - } + silc_parse_userfqdn(nickname, &nick, &servername); - if (client->nickname) - silc_free(client->nickname); - if (client->username) - silc_free(client->username); - if (client->userinfo) - silc_free(client->userinfo); + /* Remove the old cache entry */ + silc_idcache_del_by_context(global ? server->global_list->clients : + server->local_list->clients, client); + + silc_free(client->nickname); + silc_free(client->username); + silc_free(client->userinfo); + silc_free(client->servername); client->nickname = nick; client->username = strdup(username); client->userinfo = strdup(realname); - client->mode = mode; client->servername = servername; + client->mode = mode; + client->data.status |= SILC_IDLIST_STATUS_RESOLVED; + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; - if (cache) { - cache->data = nick; - cache->data_len = strlen(nick); - silc_idcache_sort_by_data(global ? server->global_list->clients : - server->local_list->clients); - } - + /* Create new cache entry */ + silc_idcache_add(global ? server->global_list->clients : + server->local_list->clients, nick, client->id, + client, FALSE); silc_free(client_id); } @@ -298,74 +289,58 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) /* Check if we have this client cached already. */ client = silc_idlist_find_client_by_id(server->local_list, client_id, - &cache); + FALSE, &cache); if (!client) { client = silc_idlist_find_client_by_id(server->global_list, - client_id, &cache); + client_id, FALSE, &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) + if (server->server_type != SILC_SERVER) 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)); - servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char)); - memcpy(nick, nickname, len); - memcpy(servername, nickname + len + 1, strlen(nickname) - len); - } else { - nick = strdup(nickname); - } + silc_parse_userfqdn(nickname, &nick, &servername); /* 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, strlen(nick), + 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) + if (!client) { + SILC_LOG_ERROR(("Could not add new client to the ID Cache")); return FALSE; + } - client->data.registered = FALSE; + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; client = silc_idlist_find_client_by_id(server->global_list, - client_id, &cache); + client_id, TRUE, &cache); cache->expire = SILC_ID_CACHE_EXPIRE_DEF; client->servername = servername; } 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)); - servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char)); - memcpy(nick, nickname, len); - memcpy(servername, nickname + len + 1, strlen(nickname) - len); - } else { - nick = strdup(nickname); - } + silc_parse_userfqdn(nickname, &nick, &servername); - if (client->nickname) - silc_free(client->nickname); - if (client->username) - silc_free(client->username); + silc_free(client->nickname); + silc_free(client->username); client->nickname = nick; client->username = strdup(username); client->servername = servername; - if (cache) { - cache->data = nick; - cache->data_len = strlen(nick); - silc_idcache_sort_by_data(global ? server->global_list->clients : - server->local_list->clients); - } + /* Remove the old cache entry and create a new one */ + silc_idcache_del_by_context(global ? server->global_list->clients : + server->local_list->clients, client); + silc_idcache_add(global ? server->global_list->clients : + server->local_list->clients, nick, client->id, + client, FALSE); } silc_free(client_id); @@ -407,95 +382,180 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) SilcServer server = cmd->server; uint32 len, id_len; unsigned char *id_data; - char *nickname, *username; - SilcClientID *client_id; + char *name, *info; + SilcClientID *client_id = NULL; + SilcServerID *server_id = NULL; + SilcChannelID *channel_id = NULL; SilcClientEntry client; - SilcIDCacheEntry cache = NULL; + SilcServerEntry server_entry; + SilcChannelEntry channel; char global = FALSE; char *nick = NULL; + SilcIDPayload idp = NULL; + SilcIdType id_type; 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) return FALSE; - - client_id = silc_id_payload_parse_id(id_data, id_len); - if (!client_id) + idp = silc_id_payload_parse_data(id_data, id_len); + if (!idp) return FALSE; - /* Check if we have this client cached already. */ + name = silc_argument_get_arg_type(cmd->args, 3, &len); + info = silc_argument_get_arg_type(cmd->args, 4, &len); - 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; - } + id_type = silc_id_payload_get_type(idp); - 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; + switch (id_type) { + case SILC_ID_CLIENT: + client_id = silc_id_payload_get_id(idp); + if (!client_id) + goto error; - /* Take hostname out of nick string if it includes it. */ - if (nickname) { - if (strchr(nickname, '@')) { - int len = strcspn(nickname, "@"); - nick = silc_calloc(len + 1, sizeof(char)); - memcpy(nick, nickname, len); - } else { - nick = strdup(nickname); - } + SILC_LOG_DEBUG(("Received client information")); + + client = silc_idlist_find_client_by_id(server->local_list, + client_id, FALSE, NULL); + if (!client) { + client = silc_idlist_find_client_by_id(server->global_list, client_id, + FALSE, NULL); + 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_SERVER) + goto error; + + /* Take nickname */ + if (name) + silc_parse_userfqdn(name, &nick, NULL); + + /* 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, + info ? strdup(info) : NULL, NULL, + client_id, cmd->sock->user_data, NULL); + if (!client) { + SILC_LOG_ERROR(("Could not add new client to the ID Cache")); + goto error; + } + client->data.status |= SILC_IDLIST_STATUS_REGISTERED; + client->data.status |= SILC_IDLIST_STATUS_RESOLVED; + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + } else { + /* We have the client already, update the data */ + + SILC_LOG_DEBUG(("Updating client data")); + + /* Take nickname */ + if (name) { + silc_parse_userfqdn(name, &nick, NULL); - /* 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, strlen(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 */ + /* Remove the old cache entry */ + silc_idcache_del_by_context(global ? server->global_list->clients : + server->local_list->clients, client); - SILC_LOG_DEBUG(("Updating client data")); + silc_free(client->nickname); + client->nickname = nick; + } + + if (info) { + silc_free(client->username); + client->username = strdup(info); + } - /* Take hostname out of nick string if it includes it. */ - if (nickname) { - if (strchr(nickname, '@')) { - int len = strcspn(nickname, "@"); - nick = silc_calloc(len + 1, sizeof(char)); - memcpy(nick, nickname, len); - } else { - nick = strdup(nickname); + client->data.status |= SILC_IDLIST_STATUS_RESOLVED; + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + + if (name) { + /* Add new cache entry */ + silc_idcache_add(global ? server->global_list->clients : + server->local_list->clients, nick, client->id, + client, FALSE); } + + silc_free(client_id); } - if (nickname && client->nickname) - silc_free(client->nickname); + break; + + case SILC_ID_SERVER: + server_id = silc_id_payload_get_id(idp); + if (!server_id) + goto error; - if (nickname) - client->nickname = nick; + SILC_LOG_DEBUG(("Received server information")); - if (username && client->username) { - silc_free(client->username); - client->username = strdup(username); + server_entry = silc_idlist_find_server_by_id(server->local_list, + server_id, FALSE, NULL); + if (!server_entry) + server_entry = silc_idlist_find_server_by_id(server->global_list, + server_id, FALSE, NULL); + if (!server_entry) { + /* If router did not find such Server ID in its lists then this must + be bogus server or some router in the net is buggy. */ + if (server->server_type != SILC_SERVER) + goto error; + + /* We don't have that server anywhere, add it. */ + server_entry = silc_idlist_add_server(server->global_list, + strdup(name), 0, + server_id, NULL, NULL); + if (!server_entry) { + silc_free(server_id); + goto error; + } + server_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED; + server_entry->data.status |= SILC_IDLIST_STATUS_RESOLVED; + server_entry->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + server_id = NULL; } - 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); + silc_free(server_id); + break; + + case SILC_ID_CHANNEL: + channel_id = silc_id_payload_get_id(idp); + if (!channel_id) + goto error; + + SILC_LOG_DEBUG(("Received channel information")); + + 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) { + /* If router did not find such Channel ID in its lists then this must + be bogus channel or some router in the net is buggy. */ + if (server->server_type != SILC_SERVER) + goto error; + + /* 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->connection, + NULL, NULL); + if (!channel) { + silc_free(channel_id); + goto error; + } + channel_id = NULL; } - silc_free(client_id); + silc_free(channel_id); + break; } + silc_id_payload_free(idp); return TRUE; + + error: + silc_id_payload_free(idp); + return FALSE; } /* Received reply for forwarded IDENTIFY command. We have received the @@ -553,10 +613,11 @@ SILC_SERVER_CMD_REPLY_FUNC(info) if (tmp_len > 256) goto out; - entry = silc_idlist_find_server_by_id(server->local_list, server_id, NULL); + entry = silc_idlist_find_server_by_id(server->local_list, server_id, + FALSE, NULL); if (!entry) { entry = silc_idlist_find_server_by_id(server->global_list, server_id, - NULL); + FALSE, NULL); if (!entry) { /* Add the server to global list */ server_id = silc_id_dup(server_id, SILC_ID_SERVER); @@ -566,6 +627,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info) silc_free(server_id); goto out; } + entry->data.status |= SILC_IDLIST_STATUS_REGISTERED; } } @@ -604,10 +666,11 @@ SILC_SERVER_CMD_REPLY_FUNC(motd) if (!server_id) goto out; - entry = silc_idlist_find_server_by_id(server->local_list, server_id, NULL); + entry = silc_idlist_find_server_by_id(server->local_list, server_id, + TRUE, NULL); if (!entry) { entry = silc_idlist_find_server_by_id(server->global_list, server_id, - NULL); + TRUE, NULL); if (!entry) goto out; } @@ -735,6 +798,13 @@ SILC_SERVER_CMD_REPLY_FUNC(join) (created == 0 ? "existing" : "created"), channel_name, silc_id_render(id, SILC_ID_CHANNEL))); + /* If the channel is found from global list we must move it to the + local list. */ + entry = silc_idlist_find_channel_by_name(server->global_list, + channel_name, &cache); + if (entry) + silc_idlist_del_channel(server->global_list, entry); + /* Add the channel to our local list. */ entry = silc_idlist_add_channel(server->local_list, strdup(channel_name), SILC_CHANNEL_MODE_NONE, id, @@ -820,8 +890,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_JOIN); SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_JOIN); - if (client_id) - silc_free(client_id); + silc_free(client_id); silc_server_command_reply_free(cmd); if (client_id_list) @@ -859,8 +928,26 @@ SILC_SERVER_CMD_REPLY_FUNC(users) if (!channel) { channel = silc_idlist_find_channel_by_id(server->global_list, channel_id, NULL); - if (!channel) - goto out; + if (!channel) { + SilcBuffer idp; + + if (server->server_type != SILC_SERVER) + goto out; + + idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL); + silc_server_send_command(server, server->router->connection, + SILC_COMMAND_IDENTIFY, ++server->cmd_ident, + 1, 5, idp->data, idp->len); + silc_buffer_free(idp); + + /* Register pending command callback. After we've received the channel + information we will reprocess this command reply by re-calling this + USERS command reply callback. */ + silc_server_command_pending(server, SILC_COMMAND_IDENTIFY, + server->cmd_ident, + NULL, silc_server_command_reply_users, cmd); + return; + } } /* Get the list count */ @@ -950,10 +1037,10 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) client_id = silc_id_payload_get_id(idp); client = silc_idlist_find_client_by_id(server->local_list, client_id, - NULL); + TRUE, NULL); if (!client) { client = silc_idlist_find_client_by_id(server->global_list, - client_id, NULL); + client_id, TRUE, NULL); if (!client) goto out; } @@ -963,10 +1050,10 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) server_id = silc_id_payload_get_id(idp); server_entry = silc_idlist_find_server_by_id(server->local_list, server_id, - NULL); + TRUE, NULL); if (!server_entry) { server_entry = silc_idlist_find_server_by_id(server->global_list, - server_id, NULL); + server_id, TRUE, NULL); if (!server_entry) goto out; }