From: Pekka Riikonen Date: Sat, 22 Jun 2002 20:53:46 +0000 (+0000) Subject: Fixed KILLED notify handling in normal server. X-Git-Tag: silc.client.0.9.3~2 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=a93321c8c98c4a84f5b3aefbb4f013d8978ec9b8 Fixed KILLED notify handling in normal server. --- diff --git a/CHANGES b/CHANGES index 8885307a..01fbdc4a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,33 @@ +Sat Jun 22 21:34:59 EEST 2002 Pekka Riikonen + + * Added silc_client_udpate_server function to update changed + server info. Affected file lib/silcclient/idlist.[ch]. + + * Added check for server entries that are being resolved when + notify is received. If being resolved, handle the received + notify only after it's resolved so that all notifys are + handled in same order as received from the server. + + Added similar resolver check to channel entries. Every + notify that cause resolving of any information that affects + channel entry marks the channel entry in waiting state. + After whatever resolving is over the waiters are signalled + and only then the notifys are handled in the same order + as delivered from the server. + + Affected files are lib/silcclient/idlist.[ch], and + client_notify.c. + + * Fixed KILLED notify handling in normal server. Affected + file silcd/packet_receive.c. + + * Added SILC_IDLIST_STATUS_LOCAL which indicates that entry + is locally connected, or was locally connected (but may + be detached and connection is not active). Added also + SILC_IS_LOCAL for checking this status. Affected files + silcd/idlist.h, silcd/packet_receive.c, silcd/server_util.c, + silcd/server.c and silcd/server_internal.h. + Sat Jun 22 17:06:58 EEST 2002 Pekka Riikonen * Don't send or handle TOPIC_SET if topic is already set and diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 3a8eb9d0..c9599deb 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -76,6 +76,14 @@ void silc_idlist_del_data(void *entry) silc_hash_free(idata->hash); if (idata->public_key) silc_pkcs_public_key_free(idata->public_key); + + idata->send_key = NULL; + idata->receive_key = NULL; + idata->rekey = NULL; + idata->hmac_send = NULL; + idata->hmac_receive = NULL; + idata->hash = NULL; + idata->public_key = NULL; } /* Purges ID cache */ diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index e2acc329..d7be2791 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -63,6 +63,7 @@ typedef SilcUInt8 SilcIDListStatus; with WHOIS or IDENTIFY */ #define SILC_IDLIST_STATUS_DISABLED 0x08 /* Entry is disabled */ #define SILC_IDLIST_STATUS_RESUMED 0x10 /* Entry is resumed */ +#define SILC_IDLIST_STATUS_LOCAL 0x20 /* Entry locally connected */ /* Generic ID list data structure. diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index bf4a1675..95486d8f 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1160,6 +1160,13 @@ void silc_server_notify(SilcServer server, /* Re-announce our clients on the channel as the ID has changed now */ silc_server_announce_get_channel_users(server, channel, &modes, &users, &users_modes); + if (users) { + silc_buffer_push(users, users->data - users->head); + silc_server_packet_send(server, sock, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + users->data, users->len, FALSE); + silc_buffer_free(users); + } if (modes) { silc_buffer_push(modes, modes->data - modes->head); silc_server_packet_send_dest(server, sock, @@ -1168,13 +1175,6 @@ void silc_server_notify(SilcServer server, modes->data, modes->len, FALSE); silc_buffer_free(modes); } - if (users) { - silc_buffer_push(users, users->data - users->head); - silc_server_packet_send(server, sock, - SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, - users->data, users->len, FALSE); - silc_buffer_free(users); - } if (users_modes) { silc_buffer_push(users_modes, users_modes->data - users_modes->head); silc_server_packet_send_dest(server, sock, @@ -1416,10 +1416,10 @@ void silc_server_notify(SilcServer server, /* If the the client is not in local list we check global list */ client = silc_idlist_find_client_by_id(server->global_list, - client_id, TRUE, NULL); + client_id, TRUE, &cache); if (!client) { client = silc_idlist_find_client_by_id(server->local_list, - client_id, TRUE, NULL); + client_id, TRUE, &cache); if (!client) { silc_free(client_id); goto out; @@ -1463,7 +1463,8 @@ void silc_server_notify(SilcServer server, silc_free(client_id); /* Killer must be router operator */ - if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) { + if (server->server_type != SILC_SERVER && + !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) { SILC_LOG_DEBUG(("Killing is not allowed")); goto out; } @@ -1482,10 +1483,25 @@ void silc_server_notify(SilcServer server, FALSE); /* Check if anyone is watching this nickname */ - if (server->server_type == SILC_ROUTER) - silc_server_check_watcher_list(server, client, NULL, - SILC_NOTIFY_TYPE_KILLED); + silc_server_check_watcher_list(server, client, NULL, + SILC_NOTIFY_TYPE_KILLED); + /* Update statistics */ + server->stat.clients--; + if (server->stat.cell_clients) + server->stat.cell_clients--; + SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR); + SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); + + if (SILC_IS_LOCAL(client)) { + server->stat.my_clients--; + silc_schedule_task_del_by_context(server->schedule, client); + silc_idlist_del_data(client); + client->mode = 0; + } + + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; + cache->expire = SILC_ID_CACHE_EXPIRE_DEF; break; } @@ -2956,6 +2972,13 @@ void silc_server_new_channel(SilcServer server, users on the channel "joining" the channel. */ silc_server_announce_get_channel_users(server, channel, &modes, &users, &users_modes); + if (users) { + silc_buffer_push(users, users->data - users->head); + silc_server_packet_send(server, sock, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + users->data, users->len, FALSE); + silc_buffer_free(users); + } if (modes) { silc_buffer_push(modes, modes->data - modes->head); silc_server_packet_send_dest(server, sock, @@ -2964,13 +2987,6 @@ void silc_server_new_channel(SilcServer server, modes->data, modes->len, FALSE); silc_buffer_free(modes); } - if (users) { - silc_buffer_push(users, users->data - users->head); - silc_server_packet_send(server, sock, - SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, - users->data, users->len, FALSE); - silc_buffer_free(users); - } if (users_modes) { silc_buffer_push(users_modes, users_modes->data - users_modes->head); silc_server_packet_send_dest(server, sock, @@ -3753,6 +3769,7 @@ void silc_server_resume_client(SilcServer server, server->global_list->clients, detached_client->nickname, detached_client->id, detached_client, FALSE, NULL); + detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL; /* Change the owner of the client if needed */ if (detached_client->router != server_entry) diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 18c4011d..818ec0f0 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -596,7 +596,8 @@ void silc_server_packet_send_to_channel(SilcServer server, goto out; } - SILC_LOG_DEBUG(("Sending packet to channel %s", channel->channel_name)); + SILC_LOG_DEBUG(("Sending %s packet to channel %s", + silc_get_packet_name(type), channel->channel_name)); routed = silc_calloc(silc_hash_table_count(channel->user_list), sizeof(*routed)); @@ -636,6 +637,10 @@ void silc_server_packet_send_to_channel(SilcServer server, gone = TRUE; } + SILC_LOG_DEBUG(("Sending packet to client %s", + client->nickname ? client->nickname : + (unsigned char *)"")); + /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, @@ -661,6 +666,10 @@ void silc_server_packet_send_to_channel(SilcServer server, if (!sock || (sender && sock == sender)) continue; + SILC_LOG_DEBUG(("Sending packet to client %s", + client->nickname ? client->nickname : + (unsigned char *)"")); + /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index ee5765ee..b622ed87 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1573,6 +1573,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) server->stat.auth_failures++; goto out; } + entry->data.status |= SILC_IDLIST_STATUS_LOCAL; /* Statistics */ server->stat.my_clients++; @@ -1677,6 +1678,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) server->stat.auth_failures++; goto out; } + entry->data.status |= SILC_IDLIST_STATUS_LOCAL; /* Statistics */ if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) { @@ -1875,8 +1877,6 @@ SILC_TASK_CALLBACK(silc_server_packet_process) return; } - server->stat.packets_received++; - /* Get keys and stuff from ID entry */ idata = (SilcIDListData)sock->user_data; if (idata) { @@ -1917,6 +1917,8 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) SilcIDListData idata = (SilcIDListData)sock->user_data; int ret; + server->stat.packets_received++; + /* Parse the packet */ if (parse_ctx->normal) ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL); @@ -2924,7 +2926,7 @@ void silc_server_remove_from_channels(SilcServer server, silc_free(chl); /* Update statistics */ - if (client->connection) + if (SILC_IS_LOCAL(client)) server->stat.my_chanclients--; if (server->server_type == SILC_ROUTER) { server->stat.cell_chanclients--; @@ -3022,7 +3024,7 @@ bool silc_server_remove_from_one_channel(SilcServer server, silc_free(chl); /* Update statistics */ - if (client->connection) + if (SILC_IS_LOCAL(client)) server->stat.my_chanclients--; if (server->server_type == SILC_ROUTER) { server->stat.cell_chanclients--; @@ -3992,6 +3994,20 @@ void silc_server_announce_channels(SilcServer server, silc_buffer_free(channels); } + if (channel_users) { + silc_buffer_push(channel_users, channel_users->data - channel_users->head); + SILC_LOG_HEXDUMP(("channel users"), channel_users->data, + channel_users->len); + + /* Send the packet */ + silc_server_packet_send(server, remote, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + channel_users->data, channel_users->len, + FALSE); + + silc_buffer_free(channel_users); + } + if (channel_modes) { int i; @@ -4014,20 +4030,6 @@ void silc_server_announce_channels(SilcServer server, silc_free(channel_modes); } - if (channel_users) { - silc_buffer_push(channel_users, channel_users->data - channel_users->head); - SILC_LOG_HEXDUMP(("channel users"), channel_users->data, - channel_users->len); - - /* Send the packet */ - silc_server_packet_send(server, remote, - SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, - channel_users->data, channel_users->len, - FALSE); - - silc_buffer_free(channel_users); - } - if (channel_users_modes) { int i; diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index f2a14100..1d679b0b 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -55,8 +55,8 @@ typedef struct { SilcUInt32 conn_failures; /* Connection failure */ SilcUInt32 auth_attempts; /* Authentication attempts */ SilcUInt32 auth_failures; /* Authentication failures */ - SilcUInt32 packets_sent; /* Sent packets */ - SilcUInt32 packets_received; /* Received packets */ + SilcUInt32 packets_sent; /* Sent SILC packets */ + SilcUInt32 packets_received; /* Received SILC packets */ } SilcServerStatistics; /* @@ -162,6 +162,11 @@ typedef struct { /* Return TRUE if a packet must be broadcasted (router broadcasts) */ #define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER) +/* Return TRUE if entry is locally connected or local to us */ +#define SILC_IS_LOCAL(entry) \ + ((entry)->connection ? TRUE : \ + (entry)->data.status & SILC_IDLIST_STATUS_LOCAL ? TRUE : FALSE) + /* Registers generic task for file descriptor for reading from network and writing to network. As being generic task the actual task is allocated only once and after that the same task applies to all registered fd's. */ @@ -187,7 +192,7 @@ do { \ #define SILC_OPER_STATS_UPDATE(c, type, mod) \ do { \ if ((c)->mode & (mod)) { \ - if ((c)->connection) \ + if (SILC_IS_LOCAL((c))) \ server->stat.my_ ## type ## _ops--; \ if (server->server_type == SILC_ROUTER) \ server->stat. type ## _ops--; \ @@ -199,14 +204,14 @@ do { \ do { \ if (client->mode & (mod)) { \ if (!(mode & (mod))) { \ - if (client->connection) \ + if (SILC_IS_LOCAL(client)) \ server->stat.my_ ## oper ## _ops--; \ if (server->server_type == SILC_ROUTER) \ server->stat. oper ## _ops--; \ } \ } else { \ if (mode & (mod)) { \ - if (client->connection) \ + if (SILC_IS_LOCAL(client)) \ server->stat.my_ ## oper ## _ops++; \ if (server->server_type == SILC_ROUTER) \ server->stat. oper ## _ops++; \ diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 713b8528..6e3056c7 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -77,7 +77,7 @@ silc_server_remove_clients_channels(SilcServer server, silc_free(chl); /* Update statistics */ - if (client->connection) + if (SILC_IS_LOCAL(client)) server->stat.my_chanclients--; if (server->server_type == SILC_ROUTER) { server->stat.cell_chanclients--; @@ -762,7 +762,7 @@ bool silc_server_channel_delete(SilcServer server, channel->user_count--; /* Update statistics */ - if (chl->client->connection) + if (SILC_IS_LOCAL(chl->client)) server->stat.my_chanclients--; if (server->server_type == SILC_ROUTER) { server->stat.cell_chanclients--; @@ -1307,12 +1307,17 @@ void silc_server_kill_client(SilcServer server, } else { /* Update statistics */ server->stat.clients--; - server->stat.my_clients--; if (server->stat.cell_clients) server->stat.cell_clients--; SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR); SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR); + if (SILC_IS_LOCAL(remote_client)) { + server->stat.my_clients--; + silc_schedule_task_del_by_context(server->schedule, remote_client); + silc_idlist_del_data(remote_client); + } + /* Remove remote client */ if (!silc_idlist_del_client(server->global_list, remote_client)) { /* Remove this client from watcher list if it is */