From: Pekka Riikonen Date: Sat, 22 Jun 2002 10:06:41 +0000 (+0000) Subject: Send CMODE_CHANGE and CUMODE_CHANGE notifys to the original X-Git-Tag: silc.client.0.9.3~8 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=6b6b1b00eeea0a5a9faac129cba3f3a4e46fec16 Send CMODE_CHANGE and CUMODE_CHANGE notifys to the original sender too. Made better backup router support for standalone router. --- diff --git a/CHANGES b/CHANGES index 372a0141..8bc79681 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,37 @@ +Sat Jun 22 12:49:21 EEST 2002 Pekka Riikonen + + * All CMODE_CHANGE and CUMODE_CHANGE notifys are now sent back + to the sender of the notify too, to avoid situation where two + notifys are in the network at the same time going to oppsite + directions. Affected file silcd/packet_receice.c. + +Fri Jun 21 10:00:32 EEST 2002 Pekka Riikonen + + * Delete the client from channel even if the cilent->id is + NULL. It was possible that client was deleted without + removing from channels (theoretically at least). Affected + file silcd/server.c and silcd/server_util.c. + + * Free the client data too when resuming is not successful. + Affected file silcd/packet_receive.c. + + * Merged some code from c0ffee's silc-plugin. Affected files + irssi/src/silc/core/silc-channels.c and silc-expandos.c. + + * Added SILC_PRIMARY_ROUTE and SILC_BROADXAST macros to + silcd/server_internal.h. SILC_PRIMARY_ROUTE Returns pointer + to the primary router connection, the other one returns + TRUE if packet must be broadcasted to network. + + * All notifys that are destined to primary router (to network) + are now automatically sent to backup routers even if the + router is standalone (and has backup router). Affected files + in silcd/. + + * Added --without-irssi and --without-silcd configuration + options for disabling the compilation of these applications. + Affected file configure.in.pre and prepare. + Thu Jun 20 13:48:15 EEST 2002 Pekka Riikonen * Implemented SILC_STRING_BMP and SILC_STRING_UNIVERSAL for @@ -14,7 +48,7 @@ Thu Jun 20 13:48:15 EEST 2002 Pekka Riikonen * Added macro SILC_NOT_IMPLEMENTED to lib/silcutil/silclog.h. * Added function silc_get_command_name to the file - lib/silcutil/silcutil.[ch + lib/silcutil/silcutil.[ch]. * Improved the server debug output a bit. Affected files are in silcd/. diff --git a/TODO b/TODO index 497dea09..8df5432a 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ TODO/bugs in Irssi SILC client ============================== - o Do UTF-8 decoding on non-utf terminals with iconv() if available. - o Testing @@ -49,9 +47,6 @@ TODO/bugs In SILC Libraries o Remove ../lib/contrib/ from includes and use relative path instead. - o Remove default irssi/ silcd/ compilation on toolkit, add maybe - --without-silcd and --without-irssi. - o WIN32 silc_net_create_connection_async does not work the same way than on Unix. Do it with threads on WIN32. The function works but is not actually async currently (Fix this to 0.9.x). diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 1a5c7c5f..992402a8 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -902,7 +902,7 @@ silc_server_command_whois_send_router(SilcServerCommandContext cmd) /* Send WHOIS command to our router */ silc_server_packet_send(server, (SilcSocketConnection) - server->router->connection, + SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -1266,8 +1266,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd) tmpbuf = silc_command_payload_encode_payload(cmd->payload); /* Send WHOWAS command to our router */ - silc_server_packet_send(server, (SilcSocketConnection) - server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -1369,7 +1368,7 @@ silc_server_command_identify_send_router(SilcServerCommandContext cmd) /* Send IDENTIFY command to our router */ silc_server_packet_send(server, (SilcSocketConnection) - server->router->connection, + SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -2117,11 +2116,9 @@ SILC_SERVER_CMD_FUNC(nick) /* Send notify about nickname change to our router. We send the new ID and ask to replace it with the old one. If we are router the packet is broadcasted. Send NICK_CHANGE notify. */ - if (!server->standalone) - silc_server_send_notify_nick_change(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, client->id, - new_id, nick); + silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + new_id, nick); /* Check if anyone is watching the old nickname */ if (server->server_type == SILC_ROUTER) @@ -2316,7 +2313,7 @@ SILC_SERVER_CMD_FUNC(list) old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); tmpbuf = silc_command_payload_encode_payload(cmd->payload); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -2448,12 +2445,10 @@ SILC_SERVER_CMD_FUNC(topic) channel->topic = strdup(tmp); /* Send TOPIC_SET notify type to the network */ - if (!server->standalone) - silc_server_send_notify_topic_set(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - client->id, SILC_ID_CLIENT, - channel->topic); + silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + client->id, SILC_ID_CLIENT, + channel->topic); idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); @@ -2684,11 +2679,9 @@ SILC_SERVER_CMD_FUNC(invite) } /* Send notify to the primary router */ - if (!server->standalone) - silc_server_send_notify_invite(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - sender->id, add, del); + silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + sender->id, add, del); /* Send command reply */ tmp = silc_argument_get_arg_type(cmd->args, 1, &len); @@ -2978,7 +2971,7 @@ SILC_SERVER_CMD_FUNC(info) silc_command_set_ident(cmd->payload, ++server->cmd_ident); tmpbuf = silc_command_payload_encode_payload(cmd->payload); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -3111,7 +3104,7 @@ SILC_SERVER_CMD_FUNC(stats) packet = silc_command_payload_encode_va(SILC_COMMAND_STATS, ++server->cmd_ident, 1, 1, idp->data, idp->len); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, 0, packet->data, packet->len, FALSE); @@ -3456,10 +3449,8 @@ static void silc_server_command_join_channel(SilcServer server, if (!cmd->pending) { /* Send JOIN notify packet to our primary router */ - if (!server->standalone) - silc_server_send_notify_join(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, client->id); + silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, client->id); if (keyp) /* Distribute the channel key to all backup routers. */ @@ -3480,10 +3471,9 @@ static void silc_server_command_join_channel(SilcServer server, } /* Set CUMODE notify type to network */ - if (founder && !server->standalone) - silc_server_send_notify_cumode(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, + if (founder) + silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, chl->mode, client->id, SILC_ID_CLIENT, client->id, channel->founder_key); @@ -3611,7 +3601,7 @@ SILC_SERVER_CMD_FUNC(join) /* Send JOIN command to our router */ silc_server_packet_send(server, (SilcSocketConnection) - server->router->connection, + SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -3828,7 +3818,7 @@ SILC_SERVER_CMD_FUNC(motd) silc_command_set_ident(cmd->payload, ++server->cmd_ident); tmpbuf = silc_command_payload_encode_payload(cmd->payload); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -3929,9 +3919,9 @@ SILC_SERVER_CMD_FUNC(umode) client->mode = mask; /* Send UMODE change to primary router */ - if (!server->standalone) - silc_server_send_notify_umode(server, server->router->connection, TRUE, - client->id, client->mode); + silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + client->mode); /* Check if anyone is watching this nickname */ if (server->server_type == SILC_ROUTER) @@ -4321,12 +4311,10 @@ SILC_SERVER_CMD_FUNC(cmode) fkey, fkey_len); /* Set CMODE notify type to network */ - if (!server->standalone) - silc_server_send_notify_cmode(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - mode_mask, client->id, SILC_ID_CLIENT, - cipher, hmac, passphrase, founder_key); + silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + mode_mask, client->id, SILC_ID_CLIENT, + cipher, hmac, passphrase, founder_key); /* Send command reply to sender */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE, @@ -4680,13 +4668,10 @@ SILC_SERVER_CMD_FUNC(cumode) fkey, fkey_len); /* Set CUMODE notify type to network */ - if (!server->standalone) - silc_server_send_notify_cumode(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - target_mask, client->id, - SILC_ID_CLIENT, - target_client->id, founder_key); + silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + target_mask, client->id, SILC_ID_CLIENT, + target_client->id, founder_key); } /* Send command reply to sender */ @@ -4835,11 +4820,9 @@ SILC_SERVER_CMD_FUNC(kick) goto out; /* Send KICKED notify to primary route */ - if (!server->standalone) - silc_server_send_notify_kicked(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - target_client->id, client->id, comment); + silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + target_client->id, client->id, comment); if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { /* Re-generate channel key */ @@ -4941,9 +4924,9 @@ SILC_SERVER_CMD_FUNC(oper) server->stat.server_ops++; /* Send UMODE change to primary router */ - if (!server->standalone) - silc_server_send_notify_umode(server, server->router->connection, TRUE, - client->id, client->mode); + silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + client->mode); /* Check if anyone is watching this nickname */ if (server->server_type == SILC_ROUTER) @@ -4961,18 +4944,27 @@ SILC_SERVER_CMD_FUNC(oper) SILC_TASK_CALLBACK(silc_server_command_detach_cb) { QuitInternal q = (QuitInternal)context; - SilcClientEntry client = (SilcClientEntry)q->sock->user_data; + SilcClientID *client_id = (SilcClientID *)q->sock; + SilcClientEntry client; + SilcSocketConnection sock; - /* If there is pending outgoing data for the client then purge it - to the network before closing connection. */ - silc_server_packet_queue_purge(q->server, q->sock); + client = silc_idlist_find_client_by_id(q->server->local_list, client_id, + TRUE, NULL); + if (client && client->connection) { + sock = client->connection; - /* Close the connection on our side */ - client->router = NULL; - client->connection = NULL; - q->sock->user_data = NULL; - silc_server_close_connection(q->server, q->sock); + /* If there is pending outgoing data for the client then purge it + to the network before closing connection. */ + silc_server_packet_queue_purge(q->server, sock); + /* Close the connection on our side */ + client->router = NULL; + client->connection = NULL; + sock->user_data = NULL; + silc_server_close_connection(q->server, sock); + } + + silc_free(client_id); silc_free(q); } @@ -4983,11 +4975,12 @@ SILC_TASK_CALLBACK(silc_server_command_detach_timeout) SilcClientEntry client; client = silc_idlist_find_client_by_id(q->server->local_list, client_id, - FALSE, NULL); - - if (client && client->mode & SILC_UMODE_DETACHED) + TRUE, NULL); + if (client && client->mode & SILC_UMODE_DETACHED) { + SILC_LOG_DEBUG(("Detach timeout")); silc_server_free_client_data(q->server, NULL, client, TRUE, "Detach timeout"); + } silc_free(client_id); silc_free(q); @@ -5019,10 +5012,9 @@ SILC_SERVER_CMD_FUNC(detach) client->data.status &= ~SILC_IDLIST_STATUS_RESUMED; client->last_command = 0; client->fast_command = 0; - if (!server->standalone) - silc_server_send_notify_umode(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, client->id, client->mode); + silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + client->mode); server->stat.my_detached++; /* Check if anyone is watching this nickname */ @@ -5032,7 +5024,7 @@ SILC_SERVER_CMD_FUNC(detach) q = silc_calloc(1, sizeof(*q)); q->server = server; - q->sock = cmd->sock; + q->sock = silc_id_dup(client->id, SILC_ID_CLIENT); silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb, q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); @@ -5079,7 +5071,7 @@ SILC_SERVER_CMD_FUNC(watch) silc_command_set_ident(cmd->payload, ++server->cmd_ident); tmpbuf = silc_command_payload_encode_payload(cmd->payload); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -5318,9 +5310,9 @@ SILC_SERVER_CMD_FUNC(silcoper) server->stat.router_ops++; /* Send UMODE change to primary router */ - if (!server->standalone) - silc_server_send_notify_umode(server, server->router->connection, TRUE, - client->id, client->mode); + silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + client->mode); /* Check if anyone is watching this nickname */ if (server->server_type == SILC_ROUTER) @@ -5436,10 +5428,9 @@ SILC_SERVER_CMD_FUNC(ban) } /* Send the BAN notify type to our primary router. */ - if (!server->standalone && (add || del)) - silc_server_send_notify_ban(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, add, del); + if (add || del) + silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, add, del); /* Send the reply back to the client */ packet = @@ -5509,10 +5500,8 @@ SILC_SERVER_CMD_FUNC(leave) /* Notify routers that they should remove this client from their list of clients on the channel. Send LEAVE notify type. */ - if (!server->standalone) - silc_server_send_notify_leave(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, id_entry->id); + silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, id_entry->id); silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE, SILC_STATUS_OK, 0, 2, tmp, len); @@ -5601,7 +5590,7 @@ SILC_SERVER_CMD_FUNC(users) tmpbuf = silc_command_payload_encode_payload(cmd->payload); /* Send USERS command */ - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); @@ -5814,7 +5803,7 @@ SILC_SERVER_CMD_FUNC(getkey) silc_command_set_ident(cmd->payload, ++server->cmd_ident); tmpbuf = silc_command_payload_encode_payload(cmd->payload); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, cmd->packet->flags, tmpbuf->data, tmpbuf->len, TRUE); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index a904d3a5..63b528fc 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -601,7 +601,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) if (server->server_type != SILC_SERVER) goto error; - /* We don't have that server anywhere, add it. */ + /* We don't have that channel anywhere, add it. */ channel = silc_idlist_add_channel(server->global_list, strdup(name), SILC_CHANNEL_MODE_NONE, channel_id, server->router, NULL, NULL, 0); @@ -1061,7 +1061,7 @@ SILC_SERVER_CMD_REPLY_FUNC(users) goto out; idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL); - silc_server_send_command(server, server->router->connection, + silc_server_send_command(server, SILC_PRIMARY_ROUTE(server), SILC_COMMAND_IDENTIFY, ++server->cmd_ident, 1, 5, idp->data, idp->len); silc_buffer_free(idp); diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 8a4df9cf..3a8eb9d0 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -565,7 +565,7 @@ void silc_idlist_client_destructor(SilcIDCache cache, silc_free(client->id); silc_hash_table_free(client->channels); - memset(client, 'F', sizeof(*client)); + memset(client, 'A', sizeof(*client)); silc_free(client); } } @@ -587,7 +587,7 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, { SilcChannelEntry channel; - SILC_LOG_DEBUG(("Adding new channel entry")); + SILC_LOG_DEBUG(("Adding new channel %s", channel_name)); channel = silc_calloc(1, sizeof(*channel)); channel->channel_name = channel_name; @@ -638,9 +638,9 @@ static void silc_idlist_del_channel_foreach(void *key, void *context, int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) { - SILC_LOG_DEBUG(("Start")); - if (entry) { + SILC_LOG_DEBUG(("Deleting channel %s", entry->channel_name)); + /* Remove from cache */ if (!silc_idcache_del_by_context(id_list->channels, entry)) return FALSE; diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index f91d0aa1..f5b28e61 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -50,14 +50,11 @@ void silc_server_notify(SilcServer server, SilcUInt32 tmp_len; bool local; - SILC_LOG_DEBUG(("Start")); - if (sock->type == SILC_SOCKET_TYPE_CLIENT || - packet->src_id_type != SILC_ID_SERVER) - return; - - if (!packet->dst_id) + packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) { + SILC_LOG_DEBUG(("Bad notify packet received")); return; + } /* If the packet is destined directly to a client then relay the packet before processing it. */ @@ -98,7 +95,7 @@ void silc_server_notify(SilcServer server, goto out; if (!server->standalone) - silc_server_packet_send_dest(server, server->router->connection, + silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server), packet->type, packet->flags | SILC_PACKET_FLAG_BROADCAST, channel_id, SILC_ID_CHANNEL, @@ -112,7 +109,7 @@ void silc_server_notify(SilcServer server, } else { /* Packet is destined to client or server */ if (!server->standalone) - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), packet->type, packet->flags | SILC_PACKET_FLAG_BROADCAST, packet->buffer->data, packet->buffer->len, @@ -344,6 +341,7 @@ void silc_server_notify(SilcServer server, server->stat.cell_clients--; SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR); SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); + silc_schedule_task_del_by_context(server->schedule, client); /* Remove the client from all channels. */ silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE); @@ -353,6 +351,9 @@ void silc_server_notify(SilcServer server, silc_server_check_watcher_list(server, client, NULL, SILC_NOTIFY_TYPE_SIGNOFF); + /* Remove this client from watcher list if it is */ + silc_server_del_from_watcher_list(server, client); + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; cache->expire = SILC_ID_CACHE_EXPIRE_DEF; break; @@ -556,8 +557,10 @@ void silc_server_notify(SilcServer server, SILC_GET32_MSB(mode, tmp); /* Check if mode changed */ - if (channel->mode == mode) + if (channel->mode == mode) { + SILC_LOG_DEBUG(("Mode is changed already")); break; + } /* Get user's channel entry and check that mode change is allowed */ if (client) { @@ -583,11 +586,6 @@ void silc_server_notify(SilcServer server, } } - /* Send the same notify to the channel */ - silc_server_packet_send_to_channel(server, sock, channel, packet->type, - FALSE, packet->buffer->data, - packet->buffer->len, FALSE); - /* If the channel had private keys set and the mode was removed then we must re-generate and re-distribute a new channel key */ if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY && @@ -673,6 +671,11 @@ void silc_server_notify(SilcServer server, channel->passphrase, NULL); } + /* Send the same notify to the channel */ + silc_server_packet_send_to_channel(server, NULL, channel, packet->type, + FALSE, packet->buffer->data, + packet->buffer->len, FALSE); + /* Change mode */ channel->mode = mode; @@ -817,10 +820,20 @@ void silc_server_notify(SilcServer server, silc_hash_table_list(channel->user_list, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chl2)) if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) { - mode &= ~SILC_CHANNEL_UMODE_CHANFO; - silc_server_force_cumode_change(server, sock, channel, - chl, mode); - notify_sent = TRUE; + /* If the founder on the channel is not the one whom has set + the founder mode, then it's possible that this CUMODE_CHANGE + is correct. Due to netsplits it's possible that this + situation happens. */ + if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) || + (channel->founder_key && chl2->client->data.public_key && + silc_pkcs_public_key_compare( + channel->founder_key, + chl2->client->data.public_key))) { + mode &= ~SILC_CHANNEL_UMODE_CHANFO; + silc_server_force_cumode_change(server, sock, channel, + chl, mode); + notify_sent = TRUE; + } break; } silc_hash_table_list_reset(&htl); @@ -877,7 +890,7 @@ void silc_server_notify(SilcServer server, silc_pkcs_public_key_free(founder_key); } - if (server->server_type == SILC_ROUTER && chl->mode == mode) { + if (chl->mode == mode) { SILC_LOG_DEBUG(("Mode is changed already")); break; } @@ -889,7 +902,7 @@ void silc_server_notify(SilcServer server, /* Send the same notify to the channel */ if (!notify_sent) - silc_server_packet_send_to_channel(server, sock, channel, + silc_server_packet_send_to_channel(server, NULL, channel, packet->type, FALSE, packet->buffer->data, packet->buffer->len, FALSE); @@ -2173,11 +2186,9 @@ SilcClientEntry silc_server_new_client(SilcServer server, client_id, client, 0, NULL); /* Notify our router about new client on the SILC network */ - if (!server->standalone) - silc_server_send_new_id(server, (SilcSocketConnection) - server->router->connection, - server->server_type == SILC_ROUTER ? TRUE : FALSE, - client->id, SILC_ID_CLIENT, id_len); + silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + SILC_ID_CLIENT, id_len); /* Distribute to backup routers */ if (server->server_type == SILC_ROUTER) { @@ -2334,8 +2345,8 @@ SilcServerEntry silc_server_new_server(SilcServer server, to our router. If we are normal server we won't send anything since this connection must be our router connection. */ if (server->server_type == SILC_ROUTER && !server->standalone && - server->router->connection != sock) - silc_server_send_new_id(server, server->router->connection, + SILC_PRIMARY_ROUTE(server) != sock) + silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server), TRUE, new_server->id, SILC_ID_SERVER, silc_id_get_len(server_id, SILC_ID_SERVER)); @@ -2438,7 +2449,7 @@ static void silc_server_new_id_real(SilcServer server, id_type == SILC_ID_SERVER && server->id_entry->server_type != SILC_BACKUP_ROUTER) { id_list = server->global_list; - router_sock = server->router ? server->router->connection : sock; + router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock; } } else { void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len, @@ -2571,11 +2582,10 @@ static void silc_server_new_id_real(SilcServer server, sock->type == SILC_SOCKET_TYPE_SERVER && !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { SILC_LOG_DEBUG(("Broadcasting received New ID packet")); - if (!server->standalone) - silc_server_packet_send(server, server->router->connection, - packet->type, - packet->flags | SILC_PACKET_FLAG_BROADCAST, - buffer->data, buffer->len, FALSE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + buffer->data, buffer->len, FALSE); silc_server_backup_send(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, packet->buffer->data, packet->buffer->len, @@ -2619,12 +2629,11 @@ void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock, sock->type == SILC_SOCKET_TYPE_SERVER && !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { SILC_LOG_DEBUG(("Broadcasting received New ID List packet")); - if (!server->standalone) - silc_server_packet_send(server, server->router->connection, - packet->type, - packet->flags | SILC_PACKET_FLAG_BROADCAST, - packet->buffer->data, - packet->buffer->len, FALSE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + packet->buffer->data, + packet->buffer->len, FALSE); silc_server_backup_send(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, packet->buffer->data, packet->buffer->len, @@ -2929,12 +2938,11 @@ void silc_server_new_channel_list(SilcServer server, sock->type == SILC_SOCKET_TYPE_SERVER && !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { SILC_LOG_DEBUG(("Broadcasting received New Channel List packet")); - if (!server->standalone) - silc_server_packet_send(server, server->router->connection, - packet->type, - packet->flags | SILC_PACKET_FLAG_BROADCAST, - packet->buffer->data, - packet->buffer->len, FALSE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + packet->buffer->data, + packet->buffer->len, FALSE); silc_server_backup_send(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, packet->buffer->data, packet->buffer->len, @@ -3161,6 +3169,8 @@ SILC_SERVER_CMD_FUNC(resume_resolve) silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); goto out; } @@ -3177,6 +3187,8 @@ SILC_SERVER_CMD_FUNC(resume_resolve) silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); goto out; } } @@ -3187,6 +3199,8 @@ SILC_SERVER_CMD_FUNC(resume_resolve) silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); goto out; } } @@ -3223,8 +3237,6 @@ void silc_server_resume_client(SilcServer server, SilcChannelClientEntry chl; SilcServerResumeResolve r; - SILC_LOG_DEBUG(("Start")); - ret = silc_buffer_unformat(buffer, SILC_STR_UI16_NSTRING(&id_string, &id_len), SILC_STR_END); @@ -3249,6 +3261,9 @@ void silc_server_resume_client(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); return; } @@ -3270,7 +3285,7 @@ void silc_server_resume_client(SilcServer server, r->server = server; r->sock = silc_socket_dup(sock); r->packet = silc_packet_context_dup(packet); - r->data = silc_id_dup(client_id, SILC_ID_CLIENT); + r->data = client_id; silc_server_command_pending(server, SILC_COMMAND_WHOIS, server->cmd_ident, silc_server_command_resume_resolve, r); @@ -3280,6 +3295,9 @@ void silc_server_resume_client(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); } return; } @@ -3304,7 +3322,7 @@ void silc_server_resume_client(SilcServer server, r->server = server; r->sock = silc_socket_dup(sock); r->packet = silc_packet_context_dup(packet); - r->data = silc_id_dup(client_id, SILC_ID_CLIENT); + r->data = client_id; silc_server_command_pending(server, SILC_COMMAND_WHOIS, server->cmd_ident, silc_server_command_resume_resolve, r); @@ -3316,6 +3334,9 @@ void silc_server_resume_client(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); return; } } @@ -3324,9 +3345,14 @@ void silc_server_resume_client(SilcServer server, resolve it first. */ if (!detached_client->data.public_key) { if (server->server_type == SILC_SERVER && server->standalone) { + SILC_LOG_ERROR(("Detached client's public key not present, " + "closing connection")); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); } else { /* We must retrieve the detached client's public key by sending GETKEY command. Reprocess this packet after receiving the key */ @@ -3337,13 +3363,15 @@ void silc_server_resume_client(SilcServer server, SILC_LOG_DEBUG(("Resolving client public key")); silc_server_send_command(server, dest_sock ? dest_sock : - server->router->connection, + SILC_PRIMARY_ROUTE(server), SILC_COMMAND_GETKEY, ++server->cmd_ident, 1, 1, idp->data, idp->len); r = silc_calloc(1, sizeof(*r)); - if (!r) + if (!r) { + silc_free(client_id); return; + } r->server = server; r->sock = silc_socket_dup(sock); @@ -3354,14 +3382,20 @@ void silc_server_resume_client(SilcServer server, silc_buffer_free(idp); } + silc_free(client_id); return; } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key, idata->public_key)) { /* We require that the connection and resuming authentication data must be using same key pair. */ + SILC_LOG_ERROR(("Resuming attempted with wrong public key, " + "closing connection")); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); return; } @@ -3377,6 +3411,9 @@ void silc_server_resume_client(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_INCOMPLETE_INFORMATION, "Resuming not possible"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_free(client_id); return; } @@ -3403,10 +3440,9 @@ void silc_server_resume_client(SilcServer server, SILC_STR_END); /* Send to primary router */ - if (!server->standalone) - silc_server_packet_send(server, server->router->connection, - SILC_PACKET_RESUME_CLIENT, 0, - buf->data, buf->len, TRUE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + SILC_PACKET_RESUME_CLIENT, 0, + buf->data, buf->len, TRUE); /* As router we must deliver this packet directly to the original server whom this client was earlier. */ @@ -3430,6 +3466,7 @@ void silc_server_resume_client(SilcServer server, /* If the ID is not based in our ID then change it */ if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) { + silc_free(client_id); while (!silc_id_create_client_id(server, server->id, server->rng, server->md5hash, client->nickname, &client_id)) { @@ -3437,6 +3474,8 @@ void silc_server_resume_client(SilcServer server, if (nickfail > 9) { silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_BAD_NICKNAME, NULL); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); return; } snprintf(&client->nickname[strlen(client->nickname) - 1], 1, @@ -3447,10 +3486,10 @@ void silc_server_resume_client(SilcServer server, if (nick_change) { /* Notify about Client ID change, nickname doesn't actually change. */ - if (!server->standalone) - silc_server_send_notify_nick_change(server, server->router->connection, - FALSE, client->id, client_id, - client->nickname); + silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), + client->id, client_id, + client->nickname); } /* Resolve users on those channels that client has joined but we @@ -3462,7 +3501,7 @@ void silc_server_resume_client(SilcServer server, SILC_LOG_DEBUG(("Resolving users for %s channel", channel->channel_name)); if (channel->disabled || !channel->users_resolved) { - silc_server_send_command(server, server->router->connection, + silc_server_send_command(server, SILC_PRIMARY_ROUTE(server), SILC_COMMAND_USERS, ++server->cmd_ident, 1, 2, channel->channel_name, strlen(channel->channel_name)); @@ -3534,9 +3573,8 @@ void silc_server_resume_client(SilcServer server, silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, keyp->data, keyp->len, FALSE); - if (created && server->server_type == SILC_SERVER && - !server->standalone) - silc_server_packet_send(server, server->router->connection, + if (created && server->server_type == SILC_SERVER) + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_CHANNEL_KEY, 0, keyp->data, keyp->len, FALSE); @@ -3550,8 +3588,10 @@ void silc_server_resume_client(SilcServer server, SilcServerEntry server_entry; SilcServerID *server_id; - if (!client_id) + if (!client_id) { + SILC_LOG_DEBUG(("Malformed resuming packet")); return; + } /* Get entry to the client, and resolve it if we don't have it. */ detached_client = silc_idlist_find_client_by_id(server->local_list, @@ -3559,8 +3599,11 @@ void silc_server_resume_client(SilcServer server, if (!detached_client) { detached_client = silc_idlist_find_client_by_id(server->global_list, client_id, TRUE, NULL); - if (!detached_client) + if (!detached_client) { + SILC_LOG_DEBUG(("Resuming client is unknown")); + silc_free(client_id); return; + } } /* Check that the client has not been resumed already because it is @@ -3571,14 +3614,19 @@ void silc_server_resume_client(SilcServer server, /* The client is clearly attempting to resume more than once and perhaps playing around by resuming from several different places at the same time. */ + SILC_LOG_DEBUG(("Attempting to re-resume client, killing both")); silc_server_kill_client(server, detached_client, NULL, server->id, SILC_ID_SERVER); + silc_free(client_id); return; } /* Check whether client is detached at all */ - if (!(detached_client->mode & SILC_UMODE_DETACHED)) + if (!(detached_client->mode & SILC_UMODE_DETACHED)) { + SILC_LOG_DEBUG(("Client is not detached")); + silc_free(client_id); return; + } /* Client is detached, and now it is resumed. Remove the detached mode and mark that it is resumed. */ @@ -3588,8 +3636,10 @@ void silc_server_resume_client(SilcServer server, /* Get the new owner of the resumed client */ server_id = silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type); - if (!server_id) + if (!server_id) { + silc_free(client_id); return; + } /* Get server entry */ server_entry = silc_idlist_find_server_by_id(server->global_list, @@ -3601,6 +3651,7 @@ void silc_server_resume_client(SilcServer server, local = FALSE; if (!server_entry) { silc_free(server_id); + silc_free(client_id); return; } } @@ -3644,11 +3695,10 @@ void silc_server_resume_client(SilcServer server, sock->type == SILC_SOCKET_TYPE_SERVER && !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { SILC_LOG_DEBUG(("Broadcasting received Resume Client packet")); - if (!server->standalone) - silc_server_packet_send(server, server->router->connection, - packet->type, - packet->flags | SILC_PACKET_FLAG_BROADCAST, - buffer->data, buffer->len, FALSE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + buffer->data, buffer->len, FALSE); silc_server_backup_send(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, packet->buffer->data, packet->buffer->len, diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 8e947fd7..ed048624 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -85,11 +85,13 @@ void silc_server_packet_send(SilcServer server, { void *dst_id = NULL; SilcIdType dst_id_type = SILC_ID_NONE; - SilcIDListData idata = (SilcIDListData)sock->user_data; + SilcIDListData idata; if (!sock) return; + idata = (SilcIDListData)sock->user_data; + /* If disconnecting, ignore the data */ if (SILC_IS_DISCONNECTING(sock)) return; @@ -140,7 +142,7 @@ void silc_server_packet_send_dest(SilcServer server, { SilcPacketContext packetdata; const SilcBufferStruct packet; - SilcIDListData idata = (SilcIDListData)sock->user_data; + SilcIDListData idata; SilcCipher cipher = NULL; SilcHmac hmac = NULL; SilcUInt32 sequence = 0; @@ -149,9 +151,11 @@ void silc_server_packet_send_dest(SilcServer server, int block_len = 0; /* If disconnecting, ignore the data */ - if (SILC_IS_DISCONNECTING(sock)) + if (!sock || SILC_IS_DISCONNECTING(sock)) return; + idata = (SilcIDListData)sock->user_data; + /* If entry is disabled do not sent anything. */ if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED) return; @@ -243,6 +247,9 @@ void silc_server_packet_send_srcdest(SilcServer server, SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type))); + if (!sock) + return; + /* Get data used in the packet sending, keys and stuff */ idata = (SilcIDListData)sock->user_data; @@ -315,6 +322,9 @@ void silc_server_packet_broadcast(SilcServer server, SilcIDListData idata; void *id; + if (!sock) + return; + SILC_LOG_DEBUG(("Broadcasting received broadcast packet")); /* If the packet is originated from our primary route we are @@ -549,8 +559,6 @@ void silc_server_packet_send_to_channel(SilcServer server, /* This doesn't send channel message packets */ assert(type != SILC_PACKET_CHANNEL_MESSAGE); - SILC_LOG_DEBUG(("Sending packet to channel")); - /* Set the packet context pointers. */ packetdata.flags = 0; packetdata.type = type; @@ -574,7 +582,6 @@ void silc_server_packet_send_to_channel(SilcServer server, if (sock != sender) { SILC_LOG_DEBUG(("Sending packet to router for routing")); - silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, @@ -584,6 +591,13 @@ void silc_server_packet_send_to_channel(SilcServer server, } } + if (!silc_hash_table_count(channel->user_list)) { + SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name)); + goto out; + } + + SILC_LOG_DEBUG(("Sending packet to channel %s", channel->channel_name)); + routed = silc_calloc(silc_hash_table_count(channel->user_list), sizeof(*routed)); @@ -655,8 +669,9 @@ void silc_server_packet_send_to_channel(SilcServer server, data, data_len, FALSE, force_send); } - silc_hash_table_list_reset(&htl); + + out: silc_free(routed); silc_free(packetdata.src_id); silc_free(packetdata.dst_id); @@ -1055,9 +1070,10 @@ void silc_server_send_notify(SilcServer server, packet->data, packet->len, FALSE); /* Send to backup routers if this is being broadcasted to primary - router. */ - if (server->router && server->router->connection && - sock == server->router->connection && broadcast) + router. The silc_server_backup_send checks further whether to + actually send it or not. */ + if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) || + (broadcast && !sock && !SILC_PRIMARY_ROUTE(server))) silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0, packet->data, packet->len, FALSE, TRUE); @@ -1513,10 +1529,12 @@ void silc_server_send_notify_on_channels(SilcServer server, bool force_send = FALSE; va_list ap; - SILC_LOG_DEBUG(("Start")); - - if (!silc_hash_table_count(client->channels)) + if (!silc_hash_table_count(client->channels)) { + SILC_LOG_DEBUG(("Client is not joined to any channels")); return; + } + + SILC_LOG_DEBUG(("Sending notify to joined channels")); va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 1cd96bbb..6ac9508c 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1147,11 +1147,11 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) /* If we are router then announce our possible servers. */ if (server->server_type == SILC_ROUTER) silc_server_announce_servers(server, FALSE, 0, - server->router->connection); + SILC_PRIMARY_ROUTE(server)); /* Announce our clients and channels to the router */ - silc_server_announce_clients(server, 0, server->router->connection); - silc_server_announce_channels(server, 0, server->router->connection); + silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server)); + silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server)); #ifdef BACKUP_SINGLE_ROUTER /* If we are backup router then this primary router is whom we are @@ -1549,11 +1549,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) if (!silc_server_connection_allowed(server, sock, ctx->conn_type, &server->config->param, conn->param, ctx->ske)) { - SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, - sock->ip)); - silc_server_disconnect_remote(server, sock, - SILC_STATUS_ERR_BANNED_FROM_SERVER, - NULL); server->stat.auth_failures++; goto out; } @@ -1608,11 +1603,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) &server->config->param, rconn ? rconn->param : NULL, ctx->ske)) { - SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, - sock->ip)); - silc_server_disconnect_remote(server, sock, - SILC_STATUS_ERR_BANNED_FROM_SERVER, - NULL); server->stat.auth_failures++; goto out; } @@ -1637,11 +1627,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) &server->config->param, sconn ? sconn->param : NULL, ctx->ske)) { - SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, - sock->ip)); - silc_server_disconnect_remote(server, sock, - SILC_STATUS_ERR_BANNED_FROM_SERVER, - NULL); server->stat.auth_failures++; goto out; } @@ -1987,19 +1972,17 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) /* Parse the incoming packet type */ silc_server_packet_parse_type(server, sock, packet); - if (server->server_type == SILC_ROUTER) { - /* Broadcast packet if it is marked as broadcast packet and it is - originated from router and we are router. */ - if (sock->type == SILC_SOCKET_TYPE_ROUTER && - packet->flags & SILC_PACKET_FLAG_BROADCAST && - !server->standalone) { - /* Broadcast to our primary route */ - silc_server_packet_broadcast(server, server->router->connection, packet); - - /* If we have backup routers then we need to feed all broadcast - data to those servers. */ - silc_server_backup_broadcast(server, sock, packet); - } + /* Broadcast packet if it is marked as broadcast packet and it is + originated from router and we are router. */ + if (server->server_type == SILC_ROUTER && + sock->type == SILC_SOCKET_TYPE_ROUTER && + packet->flags & SILC_PACKET_FLAG_BROADCAST) { + /* Broadcast to our primary route */ + silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet); + + /* If we have backup routers then we need to feed all broadcast + data to those servers. */ + silc_server_backup_broadcast(server, sock, packet); } out: @@ -2564,6 +2547,7 @@ void silc_server_close_connection(SilcServer server, /* If any protocol is active cancel its execution. It will call the final callback which will finalize the disconnection. */ if (sock->protocol) { + SILC_LOG_DEBUG(("Cancelling protocol, calling final callback")); silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; silc_protocol_execute_final(sock->protocol, server->schedule); @@ -2656,6 +2640,18 @@ void silc_server_free_client_data(SilcServer server, { FreeClientInternal i = silc_calloc(1, sizeof(*i)); + SILC_LOG_DEBUG(("Freeing client data")); + +#if 1 + if (!client->router && !client->connection && + !(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) { + SILC_LOG_ERROR(("****** freeing data for already unregistered client -s")); + SILC_LOG_ERROR(("****** Contact Pekka")); + SILC_LOG_ERROR(("****** freeing data for already unregistered client -e")); + return; + } +#endif + /* If there is pending outgoing data for the client then purge it to the network before removing the client entry. */ silc_server_packet_queue_purge(server, sock); @@ -2667,23 +2663,23 @@ void silc_server_free_client_data(SilcServer server, SILC_NOTIFY_TYPE_SIGNOFF); /* Send SIGNOFF notify to routers. */ - if (notify && !server->standalone && server->router) - silc_server_send_notify_signoff(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, client->id, signoff); - - /* Remove client from all channels */ if (notify) - silc_server_remove_from_channels(server, NULL, client, - TRUE, (char *)signoff, TRUE); - else - silc_server_remove_from_channels(server, NULL, client, - FALSE, NULL, FALSE); - - /* Remove this client from watcher list if it is */ - silc_server_del_from_watcher_list(server, client); + silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), client->id, + signoff); } + /* Remove client from all channels */ + if (notify) + silc_server_remove_from_channels(server, NULL, client, + TRUE, (char *)signoff, TRUE); + else + silc_server_remove_from_channels(server, NULL, client, + FALSE, NULL, FALSE); + + /* Remove this client from watcher list if it is */ + silc_server_del_from_watcher_list(server, client); + /* Update statistics */ server->stat.my_clients--; server->stat.clients--; @@ -2715,8 +2711,6 @@ void silc_server_free_sock_user_data(SilcServer server, SilcSocketConnection sock, const char *signoff_message) { - SILC_LOG_DEBUG(("Start")); - switch (sock->type) { case SILC_SOCKET_TYPE_CLIENT: { @@ -2731,6 +2725,8 @@ void silc_server_free_sock_user_data(SilcServer server, SilcServerEntry user_data = (SilcServerEntry)sock->user_data; SilcServerEntry backup_router = NULL; + SILC_LOG_DEBUG(("Freeing server data")); + if (user_data->id) backup_router = silc_server_backup_get(server, user_data->id); @@ -2848,6 +2844,8 @@ void silc_server_free_sock_user_data(SilcServer server, { SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data; + SILC_LOG_DEBUG(("Freeing unknown connection data")); + silc_idlist_del_data(user_data); silc_free(user_data); break; @@ -2856,6 +2854,7 @@ void silc_server_free_sock_user_data(SilcServer server, /* If any protocol is active cancel its execution */ if (sock->protocol) { + SILC_LOG_DEBUG(("Cancelling protocol, calling final callback")); silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; silc_protocol_execute_final(sock->protocol, server->schedule); @@ -2879,17 +2878,22 @@ void silc_server_remove_from_channels(SilcServer server, SilcChannelEntry channel; SilcChannelClientEntry chl; SilcHashTableList htl; - SilcBuffer clidp; - - SILC_LOG_DEBUG(("Start")); + SilcBuffer clidp = NULL; - if (!client || !client->id) + if (!client) return; - clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); - if (!clidp) + SILC_LOG_DEBUG(("Removing client from joined channels")); + + if (notify && !client->id) notify = FALSE; + if (notify) { + clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); + if (!clidp) + notify = FALSE; + } + /* Remove the client from all channels. The client is removed from the channels' user list. */ silc_hash_table_list(client->channels, &htl); @@ -2966,7 +2970,8 @@ void silc_server_remove_from_channels(SilcServer server, } silc_hash_table_list_reset(&htl); - silc_buffer_free(clidp); + if (clidp) + silc_buffer_free(clidp); } /* Removes client from one channel. This is used for example when client @@ -3109,7 +3114,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, SilcCipher key; SilcHmac newhmac; - SILC_LOG_DEBUG(("Creating new channel")); + SILC_LOG_DEBUG(("Creating new channel %s", channel_name)); if (!cipher) cipher = SILC_DEFAULT_CIPHER; @@ -3161,8 +3166,8 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, /* Notify other routers about the new channel. We send the packet to our primary route. */ - if (broadcast && server->standalone == FALSE) - silc_server_send_new_channel(server, server->router->connection, TRUE, + if (broadcast) + silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE, channel_name, entry->id, silc_id_get_len(entry->id, SILC_ID_CHANNEL), entry->mode); @@ -3207,7 +3212,7 @@ silc_server_create_new_channel_with_id(SilcServer server, SilcCipher key; SilcHmac newhmac; - SILC_LOG_DEBUG(("Creating new channel")); + SILC_LOG_DEBUG(("Creating new channel %s", channel_name)); if (!cipher) cipher = SILC_DEFAULT_CIPHER; @@ -3246,8 +3251,8 @@ silc_server_create_new_channel_with_id(SilcServer server, /* Notify other routers about the new channel. We send the packet to our primary route. */ - if (broadcast && server->standalone == FALSE) - silc_server_send_new_channel(server, server->router->connection, TRUE, + if (broadcast) + silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE, channel_name, entry->id, silc_id_get_len(entry->id, SILC_ID_CHANNEL), entry->mode); @@ -4408,7 +4413,7 @@ silc_server_get_client_route(SilcServer server, silc_free(id); if (idata) *idata = (SilcIDListData)server->router; - return server->router->connection; + return SILC_PRIMARY_ROUTE(server); } /* We are router and we will perform route lookup for the destination @@ -4544,7 +4549,7 @@ SilcClientEntry silc_server_get_client_resolve(SilcServer server, server->cmd_ident, 1, 4, idp->data, idp->len); silc_server_packet_send(server, client ? client->router->connection : - server->router->connection, + SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, 0, buffer->data, buffer->len, FALSE); silc_buffer_free(idp); @@ -4653,7 +4658,7 @@ SILC_TASK_CALLBACK(silc_server_get_stats) packet = silc_command_payload_encode_va(SILC_COMMAND_STATS, ++server->cmd_ident, 1, 1, idp->data, idp->len); - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), SILC_PACKET_COMMAND, 0, packet->data, packet->len, FALSE); silc_buffer_free(packet); diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index f0984f40..f2a14100 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -155,6 +155,13 @@ typedef struct { /* Macros */ +/* Return pointer to the primary router connection */ +#define SILC_PRIMARY_ROUTE(server) \ + (!server->standalone && server->router ? server->router->connection : NULL) + +/* Return TRUE if a packet must be broadcasted (router broadcasts) */ +#define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER) + /* 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. */ diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index fbb0c7fd..54ed8e13 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -38,18 +38,15 @@ silc_server_remove_clients_channels(SilcServer server, SilcChannelEntry channel; SilcChannelClientEntry chl, chl2; SilcHashTableList htl, htl2; - SilcBuffer clidp; SILC_LOG_DEBUG(("Start")); - if (!client || !client->id) + if (!client) return; if (silc_hash_table_find(clients, client, NULL, NULL)) silc_hash_table_del(clients, client); - clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); - /* Remove the client from all channels. The client is removed from the channels' user list. */ silc_hash_table_list(client->channels, &htl); @@ -120,7 +117,6 @@ silc_server_remove_clients_channels(SilcServer server, silc_hash_table_add(channels, channel, channel); } silc_hash_table_list_reset(&htl); - silc_buffer_free(clidp); } /* This function is used to remove all client entries by the server `entry'. @@ -208,15 +204,15 @@ bool silc_server_remove_clients_by_server(SilcServer server, SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR); SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); - /* Remove the client entry */ silc_server_remove_clients_channels(server, entry, clients, client, channels); + silc_server_del_from_watcher_list(server, client); + + /* Remove the client entry */ if (!server_signoff) { client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; } else { - /* Remove this client from watcher list if it is */ - silc_server_del_from_watcher_list(server, client); silc_idlist_del_client(server->local_list, client); } @@ -268,9 +264,11 @@ bool silc_server_remove_clients_by_server(SilcServer server, SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR); SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); - /* Remove the client entry */ silc_server_remove_clients_channels(server, entry, clients, client, channels); + silc_server_del_from_watcher_list(server, client); + + /* Remove the client entry */ if (!server_signoff) { client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; @@ -290,21 +288,16 @@ bool silc_server_remove_clients_by_server(SilcServer server, SilcBuffer args, not; /* Send SERVER_SIGNOFF notify to our primary router */ - if (!server->standalone && server->router && - server->router != entry) { + if (server->router != entry) { args = silc_argument_payload_encode(1, argv, argv_lens, argv_types); - silc_server_send_notify_args(server, - server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, + silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), SILC_NOTIFY_TYPE_SERVER_SIGNOFF, argc, args); silc_buffer_free(args); } - - /* Send to local clients. We also send the list of client ID's that is to be removed for those servers that would like to use that list. */ args = silc_argument_payload_encode(argc, argv, argv_lens, @@ -1277,10 +1270,9 @@ void silc_server_kill_client(SilcServer server, killer->data, killer->len); /* Send KILLED notify to primary route */ - if (!server->standalone) - silc_server_send_notify_killed(server, server->router->connection, TRUE, - remote_client->id, comment, - killer_id, killer_id_type); + silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), remote_client->id, + comment, killer_id, killer_id_type); /* Send KILLED notify to the client directly */ if (remote_client->connection || remote_client->router) @@ -1369,7 +1361,7 @@ bool silc_server_check_watcher_list(SilcServer server, WatcherNotifyContext n; SILC_LOG_DEBUG(("Checking watcher list %s", - client->nickname ? client->nickname : "")); + client->nickname ? client->nickname : (unsigned char *)"")); /* If the watching is rejected by the client do nothing */ if (client->mode & SILC_UMODE_REJECT_WATCHING) @@ -1414,8 +1406,9 @@ bool silc_server_del_from_watcher_list(SilcServer server, if (entry == client) { silc_hash_table_del_by_context(server->watcher_list, key, client); - SILC_LOG_DEBUG(("Removing %s from WATCH list", - silc_id_render(client->id, SILC_ID_CLIENT))); + if (client->id) + SILC_LOG_DEBUG(("Removing %s from WATCH list", + silc_id_render(client->id, SILC_ID_CLIENT))); /* Now check whether there still exists entries with this key, if not then free the key to not leak memory. */ @@ -1442,7 +1435,7 @@ bool silc_server_force_cumode_change(SilcServer server, SilcBuffer idp1, idp2; unsigned char cumode[4]; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Enforcing sender to change mode")); if (sock) silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode, diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index 4b49cafa..12802ef7 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -318,50 +318,56 @@ typedef struct { } DebugLevel; static DebugLevel debug_levels[] = { - /* Basic stuff from silcd/ */ - { 5, "silc_server_*" }, + /* Very basic stuff from silcd/ */ + { 3, "silcd\\.c,server\\.c" }, + + /* More stuff from silcd/ */ + { 7, "silcd\\.c,server\\.c,command\\.c" }, + + /* All basic stuff from silcd/ */ + { 10, "silc_server_*" }, /* All from silcd/ */ - { 10, "*silcd*,*serverid*,silc_server_*,*idlist*" }, + { 15, "*silcd*,*serverid*,silc_server_*,*idlist*" }, /* All from silcd/ and basic stuff from libs */ - { 15, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,*silcske*" }, + { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,*silcske*" }, /* All from silcd/ and more stuff from libs */ - { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*" }, /* All from silcd/ and even more stuff from libs */ - { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" }, /* All from silcd/ and even more stuff from libs + all from silccore */ - { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 35, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" "*silcid*,*argument*" }, /* All from silcd/, all from silccore, silccrypt and silcmath */ - { 35, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*" }, /* All from silcd/, all from silccore, silccrypt and silcmath + stuff from silcutil */ - { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 45, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" "*sockconn*" }, /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff from silcutil */ - { 45, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 50, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" "*sockconn*,*net*" }, /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff from silcutil */ - { 50, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + { 55, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" "*sockconn*,*net*,*log*,*config*" },