Ограничение отправки групповых сообщений

Доброго времени суток!

В локальной сети используется следующая связка 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. Наложил данный патч. Работает прекрасно.

Единственное, парочка клиентов сказали, что у них происходило разъединение во время обычного общения.
Возможно это связано с частотой отправки сообщений (не групповых) разным адресатам одним пользователем.

В любом случае, спасибо!

Syndicate content