X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserver_query.c;h=6475c57301b06b7dcde972704472061994bf0c7a;hp=895ee44d78f5cca562eafbbdf1aaa0ff3c4cd3af;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=653b9bc9d64cfeb1d72b9f2e0c1234d0ab211b0a diff --git a/apps/silcd/server_query.c b/apps/silcd/server_query.c index 895ee44d..6475c573 100644 --- a/apps/silcd/server_query.c +++ b/apps/silcd/server_query.c @@ -388,8 +388,8 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query) if (!tmp) continue; - id = silc_id_payload_parse_id(tmp, tmp_len, NULL); - if (!id) { + id = silc_id_payload_parse_id(tmp, tmp_len, &id_type); + if (!id || id_type != SILC_ID_CLIENT) { silc_server_query_add_error(server, query, TRUE, i + 4, SILC_STATUS_ERR_BAD_CLIENT_ID); continue; @@ -407,6 +407,8 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query) for (i = 0; i < query->ids_count; i++) silc_free(query->ids[i].id); silc_free(query->ids); + query->ids = NULL; + query->ids_count = 0; silc_free(id); return; } @@ -426,8 +428,16 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query) /* Get requested attributes if set */ tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len); - if (tmp && tmp_len <= SILC_ATTRIBUTE_MAX_REQUEST_LEN) + if (tmp && tmp_len <= SILC_ATTRIBUTE_MAX_REQUEST_LEN) { query->attrs = silc_attribute_payload_parse(tmp, tmp_len); + + /* When Requested Attributes is present we will assure that this + client cannot execute the WHOIS command too fast. This would be + same as having SILC_CF_LAG_STRICT. */ + if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT && + cmd->sock->user_data) + ((SilcClientEntry)cmd->sock->user_data)->fast_command = 6; + } break; case SILC_COMMAND_WHOWAS: @@ -506,18 +516,33 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query) /* Normal server must check whether this ID exist, and if not then send the query to router, unless done so already */ if (server->server_type == SILC_SERVER && !query->resolved) { - if (!silc_idlist_find_client_by_id(server->local_list, - id, TRUE, NULL)) { - if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || - !silc_idlist_find_client_by_id(server->global_list, + if (id_type == SILC_ID_CLIENT) { + if (!silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL)) { - silc_server_query_send_router(server, query); - for (i = 0; i < query->ids_count; i++) - silc_free(query->ids[i].id); - silc_free(query->ids); - silc_free(id); - return; + if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || + !silc_idlist_find_client_by_id(server->global_list, + id, TRUE, NULL)) { + silc_server_query_send_router(server, query); + for (i = 0; i < query->ids_count; i++) + silc_free(query->ids[i].id); + silc_free(query->ids); + query->ids = NULL; + query->ids_count = 0; + silc_free(id); + return; + } } + } else { + /* For now all other ID's except Client ID's are explicitly + sent to router for resolving. */ + silc_server_query_send_router(server, query); + for (i = 0; i < query->ids_count; i++) + silc_free(query->ids[i].id); + silc_free(query->ids); + query->ids = NULL; + query->ids_count = 0; + silc_free(id); + return; } } @@ -867,6 +892,21 @@ void silc_server_query_resolve(SilcServer server, SilcServerQuery query, for (i = 0; i < query->querylist_count; i++) { r = &query->querylist[i]; + /* If Requested Attributes were present put them to this resolving */ + if (query->attrs && query->querycmd == SILC_COMMAND_WHOIS) { + len = r->argc + 1; + r->arg = silc_realloc(r->arg, sizeof(*r->arg) * len); + r->arg_lens = silc_realloc(r->arg_lens, sizeof(*r->arg_lens) * len); + r->arg_types = silc_realloc(r->arg_types, sizeof(*r->arg_types) * len); + + tmp = silc_argument_get_arg_type(cmd->args, 3, &len); + if (tmp) + r->arg[r->argc] = silc_memdup(tmp, len); + r->arg_lens[r->argc] = len; + r->arg_types[r->argc] = 3; + r->argc++; + } + /* Send WHOIS command */ res_cmd = silc_command_payload_encode(SILC_COMMAND_WHOIS, r->argc, r->arg, r->arg_lens, @@ -916,7 +956,7 @@ void silc_server_query_resolve(SilcServer server, SilcServerQuery query, case SILC_COMMAND_WHOIS: case SILC_COMMAND_IDENTIFY: /* Take existing query context if exist for this connection */ - for (i = 0; i < query->queries_count; i++) + for (i = 0; i < query->querylist_count; i++) if (query->querylist[i].sock == sock) { r = &query->querylist[i]; break; @@ -936,21 +976,6 @@ void silc_server_query_resolve(SilcServer server, SilcServerQuery query, r->timeout = 3; } - /* If Requested Attributes were present put them to this resolving */ - if (query->attrs && query->querycmd == SILC_COMMAND_WHOIS) { - len = r->argc + 1; - r->arg = silc_realloc(r->arg, sizeof(*r->arg) * len); - r->arg_lens = silc_realloc(r->arg_lens, sizeof(*r->arg_lens) * len); - r->arg_types = silc_realloc(r->arg_types, sizeof(*r->arg_types) * len); - - tmp = silc_argument_get_arg_type(cmd->args, 3, &len); - if (tmp) - r->arg[r->argc] = silc_memdup(tmp, len); - r->arg_lens[r->argc] = len; - r->arg_types[r->argc] = 3; - r->argc++; - } - len = r->argc + 1; r->arg = silc_realloc(r->arg, sizeof(*r->arg) * len); r->arg_lens = silc_realloc(r->arg_lens, sizeof(*r->arg_lens) * len); @@ -1243,7 +1268,7 @@ void silc_server_query_send_reply(SilcServer server, attributes we will reply to them on behalf of the client. */ len = 0; if (query->attrs) { - if (!entry->attrs) { + if (!entry->attrs && SILC_IS_LOCAL(entry)) { tmpattrs = silc_server_query_reply_attrs(server, query, entry); entry->attrs = silc_memdup(tmpattrs->data, tmpattrs->len); entry->attrs_len = tmpattrs->len; @@ -1529,7 +1554,7 @@ SilcBuffer silc_server_query_reply_attrs(SilcServer server, SilcAttributeObjPk pk; SilcAttributeObjService service; unsigned char *tmp; - unsigned char sign[2048]; + unsigned char sign[2048 + 1]; SilcUInt32 sign_len; SILC_LOG_DEBUG(("Constructing Requested Attributes")); @@ -1548,6 +1573,8 @@ SilcBuffer silc_server_query_reply_attrs(SilcServer server, silc_strncat(service.address, sizeof(service.address), server->server_name, strlen(server->server_name)); service.status = !(client_entry->mode & SILC_UMODE_DETACHED); + if (client_entry->connection) + service.idle = time(NULL) - client_entry->data.last_receive; buffer = silc_attribute_payload_encode(buffer, attribute, SILC_ATTRIBUTE_FLAG_VALID, &service, sizeof(service));