+Sat Jun 22 21:34:59 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+ * 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 <priikone@silcnet.org>
* Don't send or handle TOPIC_SET if topic is already set and
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 */
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.
/* 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,
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,
/* 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;
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;
}
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;
}
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,
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,
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)
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));
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,
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,
server->stat.auth_failures++;
goto out;
}
+ entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
/* Statistics */
server->stat.my_clients++;
server->stat.auth_failures++;
goto out;
}
+ entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
/* Statistics */
if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
return;
}
- server->stat.packets_received++;
-
/* Get keys and stuff from ID entry */
idata = (SilcIDListData)sock->user_data;
if (idata) {
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);
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--;
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--;
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;
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;
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;
/*
/* 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. */
#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--; \
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++; \
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--;
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--;
} 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 */