X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fpacket_receive.c;h=e49fafb59e7fb9a6d34595eff5748831a191b5a3;hp=fbb5a9d0badb8c9c2740340781030b1223050572;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=bbc2071bac65ded8d5bc07831d768de254c55842 diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index fbb5a9d0..e49fafb5 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -362,7 +362,8 @@ void silc_server_notify(SilcServer server, 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); + silc_server_remove_from_channels(server, NULL, client, TRUE, + tmp, FALSE, FALSE); /* Check if anyone is watching this nickname */ if (server->server_type == SILC_ROUTER) @@ -1076,7 +1077,7 @@ void silc_server_notify(SilcServer server, /* Get invite list */ tmp = silc_argument_get_arg_type(args, 5, &tmp_len); - if (!tmp) + if (!tmp || tmp_len < 2) goto out; /* Parse the arguments to see they are constructed correctly */ @@ -1086,9 +1087,10 @@ void silc_server_notify(SilcServer server, goto out; if (action == 0 && !channel->invite_list) - channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr, - NULL, NULL, NULL, - NULL, NULL, TRUE); + channel->invite_list = + silc_hash_table_alloc(0, silc_hash_ptr, + NULL, NULL, NULL, + silc_server_inviteban_destruct, channel, TRUE); /* Proces the invite action */ silc_server_inviteban_process(server, channel->invite_list, action, @@ -1280,7 +1282,7 @@ void silc_server_notify(SilcServer server, /* Remove the client from all channels. */ silc_server_remove_from_channels(server, NULL, client, - TRUE, NULL, FALSE); + TRUE, NULL, FALSE, FALSE); /* Check if anyone is watching this nickname */ if (server->server_type == SILC_ROUTER) @@ -1304,9 +1306,22 @@ void silc_server_notify(SilcServer server, } silc_free(server_id); - /* Sending SERVER_SIGNOFF is not right way to signoff local connection */ - if (SILC_IS_LOCAL(server_entry)) + /* For local entrys SERVER_SIGNOFF is processed only on backup router. + It is possible that router sends server signoff for a server. If + backup router has it as local connection it will be closed. */ + if (SILC_IS_LOCAL(server_entry)) { + if (server->server_type == SILC_BACKUP_ROUTER) { + sock = server_entry->connection; + SILC_LOG_DEBUG(("Closing connection %s after SERVER_SIGNOFF", + sock->hostname)); + SILC_SET_DISCONNECTING(sock); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_server_close_connection(server, sock); + } + break; + } /* Remove all servers that are originated from this server, and remove the clients of those servers too. */ @@ -1383,41 +1398,53 @@ void silc_server_notify(SilcServer server, if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) goto out; - /* From protocol version 1.1 we get the kicker's ID as well. */ + /* Get the kicker's Client ID */ tmp = silc_argument_get_arg_type(args, 3, &tmp_len); - if (tmp) { - client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); - if (!client_id) - goto out; + if (!tmp) + goto out; + client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); + if (!client_id) + goto out; - /* If the the client is not in local list we check global list */ - client2 = silc_idlist_find_client_by_id(server->global_list, + /* If the the client is not in local list we check global list */ + client2 = silc_idlist_find_client_by_id(server->global_list, + client_id, TRUE, NULL); + if (!client2) { + client2 = silc_idlist_find_client_by_id(server->local_list, client_id, TRUE, NULL); if (!client2) { - client2 = silc_idlist_find_client_by_id(server->local_list, - client_id, TRUE, NULL); - if (!client2) { - silc_free(client_id); - goto out; - } - } - silc_free(client_id); - - /* Kicker must be operator on channel */ - if (!silc_server_client_on_channel(client2, channel, &chl)) - goto out; - if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) && - !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) { - SILC_LOG_DEBUG(("Kicking is not allowed")); + silc_free(client_id); goto out; } } + silc_free(client_id); + + /* Kicker must be operator on channel */ + if (!silc_server_client_on_channel(client2, channel, &chl)) + goto out; + if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) && + !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) { + SILC_LOG_DEBUG(("Kicking is not allowed")); + goto out; + } /* Send to channel */ silc_server_packet_send_to_channel(server, sock, channel, packet->type, FALSE, packet->buffer->data, packet->buffer->len, FALSE); + /* Remove the client from channel's invite list */ + if (channel->invite_list && silc_hash_table_count(channel->invite_list)) { + SilcBuffer ab; + SilcArgumentPayload iargs; + tmp = silc_argument_get_arg_type(args, 1, &tmp_len); + ab = silc_argument_payload_encode_one(NULL, tmp, tmp_len, 3); + iargs = silc_argument_payload_parse(ab->data, ab->len, 1); + silc_server_inviteban_process(server, channel->invite_list, 1, iargs); + silc_buffer_free(ab); + silc_argument_payload_free(iargs); + } + /* Remove the client from channel */ silc_server_remove_from_one_channel(server, sock, channel, client, FALSE); @@ -1468,34 +1495,34 @@ void silc_server_notify(SilcServer server, if (comment_len > 128) comment_len = 127; - /* From protocol version 1.1 we get the killer's ID as well. */ + /* Get the killer's Client ID */ tmp = silc_argument_get_arg_type(args, 3, &tmp_len); - if (tmp) { - client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type); - if (!client_id) - goto out; + if (!tmp) + goto out; + client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type); + if (!client_id) + goto out; - if (id_type == SILC_ID_CLIENT) { - /* If the the client is not in local list we check global list */ - client2 = silc_idlist_find_client_by_id(server->global_list, + if (id_type == SILC_ID_CLIENT) { + /* If the the client is not in local list we check global list */ + client2 = silc_idlist_find_client_by_id(server->global_list, + client_id, TRUE, NULL); + if (!client2) { + client2 = silc_idlist_find_client_by_id(server->local_list, client_id, TRUE, NULL); if (!client2) { - client2 = silc_idlist_find_client_by_id(server->local_list, - client_id, TRUE, NULL); - if (!client2) { - silc_free(client_id); - goto out; - } - } - silc_free(client_id); - - /* Killer must be router operator */ - if (server->server_type != SILC_SERVER && - !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) { - SILC_LOG_DEBUG(("Killing is not allowed")); + silc_free(client_id); goto out; } } + silc_free(client_id); + + /* Killer must be router operator */ + if (server->server_type != SILC_SERVER && + !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) { + SILC_LOG_DEBUG(("Killing is not allowed")); + goto out; + } } /* Send the notify to local clients on the channels except to the @@ -1507,7 +1534,7 @@ void silc_server_notify(SilcServer server, /* Remove the client from all channels */ silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, - FALSE); + FALSE, TRUE); /* Check if anyone is watching this nickname */ silc_server_check_watcher_list(server, client, NULL, @@ -1638,7 +1665,7 @@ void silc_server_notify(SilcServer server, /* Get ban list */ tmp = silc_argument_get_arg_type(args, 3, &tmp_len); - if (!tmp) + if (!tmp || tmp_len < 2) goto out; /* Parse the arguments to see they are constructed correctly */ @@ -1648,9 +1675,10 @@ void silc_server_notify(SilcServer server, goto out; if (action == 0 && !channel->ban_list) - channel->ban_list = silc_hash_table_alloc(0, silc_hash_ptr, - NULL, NULL, NULL, - NULL, NULL, TRUE); + channel->ban_list = + silc_hash_table_alloc(0, silc_hash_ptr, + NULL, NULL, NULL, + silc_server_inviteban_destruct, channel, TRUE); /* Proces the ban action */ silc_server_inviteban_process(server, channel->ban_list, action, @@ -1686,7 +1714,7 @@ void silc_server_notify(SilcServer server, client_id, FALSE, NULL); if (client) { silc_server_remove_from_channels(server, NULL, client, TRUE, - NULL, TRUE); + NULL, TRUE, FALSE); silc_idlist_del_data(client); silc_idlist_del_client(server->global_list, client); } @@ -2081,9 +2109,12 @@ void silc_server_channel_key(SilcServer server, /* Save the channel key */ channel = silc_server_save_channel_key(server, buffer, NULL); - if (!channel) + if (!channel) { + SILC_LOG_ERROR(("Bad channel key from %s (%s)", + sock->hostname, sock->ip)); return; - + } + /* Distribute the key to everybody who is on the channel. If we are router we will also send it to locally connected servers. */ silc_server_send_channel_key(server, sock, channel, FALSE); @@ -3646,7 +3677,8 @@ void silc_server_resume_client(SilcServer server, server->stat.clients--; if (server->stat.cell_clients) server->stat.cell_clients--; - silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE); + silc_server_remove_from_channels(server, NULL, client, FALSE, + NULL, FALSE, FALSE); silc_server_del_from_watcher_list(server, client); if (!silc_idlist_del_client(server->local_list, client)) silc_idlist_del_client(server->global_list, client); @@ -3906,5 +3938,4 @@ void silc_server_resume_client(SilcServer server, } silc_free(client_id); - silc_idlist_del_data(detached_client); }