Доброго времени суток!
В локальной сети используется следующая связка ejabberd 1.0.0 + shared roster и Psi 0.10.
В клиенте есть такая функция "sending message to group". Некоторые особо активные пользователи пользуются данной опцией и рассылают всякого рода флуд всем остальным пользователям. Бороться с этим организационными методами практически невозможно.
Сообщения отправляемые таким образом визуально отличаются от обычных личных сообщений, что говорит о том, что методы отправки имеют различия. С какой бы стороны зацепиться к этим различиям?
Вопрос: каким образом можно ограничить использование данной функции?
Варианты:
1. отключить данную функцию на уровне сервера (если возможно);
2. установить минимальное время между отправкой более чем одного сообщения;
3. попросить разработчиков Psi выпустить релиз без данной функции и на уровне сервера (если возможно) сделать проверку версии клиента.
В идеале, было здорово, если бы только администраторы могли пользоваться данной функцией.
Несколько недель назад начал обсуждать проблему в основной ветке форума - http://www.ejabberd.im/node/762
Но, к сожалению, решение проблемы так и не было найдено.
Может есть у кого мысли на этот счет?
Заранее спасибо!
Я тоже хочу
Я тоже хочу побороть эту проблему. Но пока никаких результатов.
Как ограничить отправку групповых
Столько времени прошло, а решение так и не найдено... Обидно.
Данная проблема создает много неприятностей.
Может все-таки есть у кого-нибудь мысли на этот счет?
Было бы приятно услышать мнение разработчика сервера ejabberd.
Заранее спасибо.
Ну, я не
Ну, я не разработчик, а вот мой патч. Кажется, он работает, но попробуйте собственным риском :)
--- orig/src/ejabberd_c2s.erl +++ mod/src/ejabberd_c2s.erl @@ -63,7 +63,8 @@ pres_timestamp, pres_invis = false, privacy_list = none, - lang}). + lang, + last_message = {{0,0,0}, noone, none}}). %when, whom, what %-define(DBGFSM, true). @@ -91,6 +92,13 @@ -define(POLICY_VIOLATION_ERR(Lang, Text), xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))). +%% Attempt to "disallow" sending group messages. When a user sends +%% two subsequent messages with identical text longer than M bytes and +%% different receivers within less than N seconds, disconnect +%% immediately. Set M and N here: +-define(DONTFLOOD_MIN_SIZE, 10). +-define(DONTFLOOD_INTERVAL, 1). + %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- @@ -816,16 +824,35 @@ end end; "message" -> - ejabberd_hooks:run(user_send_packet, - Server, - [FromJID, ToJID, NewEl]), - ejabberd_router:route(FromJID, ToJID, NewEl), - StateData; + {NewStateData, Flooding} = + check_flooding(StateData, NewEl), + if Flooding -> + flooding; + true -> + ejabberd_hooks:run(user_send_packet, + Server, + [FromJID, ToJID, NewEl]), + ejabberd_router:route(FromJID, ToJID, NewEl), + NewStateData + end; _ -> StateData end end, - {next_state, session_established, NewState}; + case NewState of + flooding -> + ?INFO_MSG("(~w) ~s kicked for flooding", + [StateData#state.socket, + jlib:jid_to_string(StateData#state.jid)]), + send_text(StateData, + ?POLICY_VIOLATION_ERR( + StateData#state.lang, + "Flooding forbidden") ++ + ?STREAM_TRAILER), + {stop, normal, StateData}; + _ -> + {next_state, session_established, NewState} + end; session_established({xmlstreamend, _Name}, StateData) -> send_text(StateData, ?STREAM_TRAILER), @@ -1210,6 +1237,32 @@ send_element(StateData, El) -> send_text(StateData, xml:element_to_string(El)). +check_flooding(StateData, El) -> + %%{NewStateData, Flooding} = + case El of + {xmlelement, "message", _, _} -> + {LastTime, LastReceiver, LastText} = StateData#state.last_message, + %% check time + {LMS, LS, _} = LastTime, + {NMS, NS, _} = now(), + %% check receiver + Receiver = xml:get_tag_attr_s("to", El), + %% check text + Text = xml:get_path_s(El, [{elem, "body"}, cdata]), + {StateData#state{last_message = {now(), Receiver, Text}}, + if NMS > LMS; LS + ?DONTFLOOD_INTERVAL < NS -> + false; + LastReceiver == Receiver -> + false; + Text /= LastText -> + false; + true -> + true + end}; + _ -> + {StateData, false} + end. + new_id() -> randoms:get_string().Все работает, спасибо!
Решил заодно перейти на 1.1.2. Наложил данный патч. Работает прекрасно.
Единственное, парочка клиентов сказали, что у них происходило разъединение во время обычного общения.
Возможно это связано с частотой отправки сообщений (не групповых) разным адресатам одним пользователем.
В любом случае, спасибо!