diff options
-rw-r--r-- | doc/guide.html | 53 | ||||
-rw-r--r-- | doc/guide.tex | 31 | ||||
-rw-r--r-- | src/ejabberd.cfg.example | 5 | ||||
-rw-r--r-- | src/mod_offline.erl | 34 | ||||
-rw-r--r-- | src/mod_offline_odbc.erl | 33 |
5 files changed, 116 insertions, 40 deletions
diff --git a/doc/guide.html b/doc/guide.html index 467a4dfe5..c8160e502 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -2423,11 +2423,31 @@ sent to an offline user will be stored on the server until that user comes online again. Thus it is very similar to how email works. Note that <TT>ejabberdctl</TT> has a command to delete expired messages (see section <A HREF="#ejabberdctl">4.1</A>).</P><DL CLASS="description"><DT CLASS="dt-description"> -<B><TT>user_max_messages</TT></B></DT><DD CLASS="dd-description">This option -is use to set a max number of offline messages per user (quota). Its -value can be either <TT>infinity</TT> or a strictly positive -integer. The default value is <TT>infinity</TT>. -</DD></DL><P> <A NAME="modprivacy"></A> </P><!--TOC subsection <TT>mod_privacy</TT>--> +<B><TT>access_max_user_messages</TT></B></DT><DD CLASS="dd-description"> +This option defines which access rule will be enforced to limit +the maximum number of offline messages that a user can have (quota). +When a user has too many offline messages, any new messages that he receive are discarded, +and a resource-constraint error is returned to the sender. +The default value is <TT>max_user_offline_messages</TT>. +Then you can define an access rule with a syntax similar to +<TT>max_user_sessions</TT> (see <A HREF="#configmaxsessions">3.1.5</A>). +</DD></DL><P>This example allows power users to have as much as 5000 offline messages, +administrators up to 2000, +and all the other users up to 100. +</P><PRE CLASS="verbatim">{acl, admin, {user, "admin1", "localhost"}}. +{acl, admin, {user, "admin2", "example.org"}}. +{acl, poweruser, {user, "bob", "example.org"}}. +{acl, poweruser, {user, "jane", "example.org"}}. + +{access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}. + +{modules, + [ + ... + {mod_offline, [ {access_max_user_messages, max_user_offline_messages} ]}, + ... + ]}. +</PRE><P> <A NAME="modprivacy"></A> </P><!--TOC subsection <TT>mod_privacy</TT>--> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc48">3.3.11</A>  <A HREF="#modprivacy"><TT>mod_privacy</TT></A></H3><!--SEC END --><P> <A NAME="modprivacy"></A> </P><P>This module implements Blocking Communication (also known as Privacy Rules) as defined in section 10 from XMPP IM. If end users have support for it in @@ -2538,12 +2558,27 @@ is replaced at start time with the real virtual host name. </DD><DT CLASS="dt-description"><B><TT>access_createnode</TT></B></DT><DD CLASS="dd-description"> This option restricts which users are allowed to create pubsub nodes using -ACL and ACCESS. The default value is <TT>pubsub_createnode</TT>. </DD><DT CLASS="dt-description"><B><TT>plugins</TT></B></DT><DD CLASS="dd-description"> To specify which pubsub node plugins to use. If not defined, the default +ACL and ACCESS. The default value is <TT>pubsub_createnode</TT>. </DD><DT CLASS="dt-description"><B><TT>plugins</TT></B></DT><DD CLASS="dd-description"> +To specify which pubsub node plugins to use. If not defined, the default pubsub plugin is always used. -</DD><DT CLASS="dt-description"><B><TT>nodetree</TT></B></DT><DD CLASS="dd-description"> To specify which nodetree to use. If not defined, the default pubsub -nodetree is used. Nodetrees are default and virtual. Only one nodetree can be used +</DD><DT CLASS="dt-description"><B><TT>nodetree</TT></B></DT><DD CLASS="dd-description"> +To specify which nodetree to use. If not defined, the default pubsub +nodetree is used. Only one nodetree can be used per host, and is shared by all node plugins. -</DD></DL><P>Example: +</DD><DT CLASS="dt-description"><B><TT>pep_sendlast_offline</TT></B></DT><DD CLASS="dd-description"> +To specify whether or not we should get last published PEP items +from users in our roster which are offline when we connect. Value is true or false. +If not defined, pubsub assumes false so we only get last items of online contacts. +</DD><DT CLASS="dt-description"><B><TT>last_item_cache</TT></B></DT><DD CLASS="dd-description"> +To specify whether or not pubsub should cache last items. Value is true +or false. If not defined, pubsub do not cache last items. On systems with not so many nodes, +caching last items speeds up pubsub and allows to raise user connection rate. The cost is memory +usage, as every item is stored in memory. +</DD><DT CLASS="dt-description"><B><TT>pep_mapping</TT></B></DT><DD CLASS="dd-description"> +This allow to define a Key-Value list to choose defined node plugins on given PEP namespace. +The following example will use node_tune instead of node_pep for every PEP node with tune namespace: +<PRE CLASS="verbatim"> {mod_pubsub, [{pep_mapping, [{"http://jabber.org/protocol/tune", "tune"}]}]} +</PRE></DD></DL><P>Example: </P><PRE CLASS="verbatim">{modules, [ ... diff --git a/doc/guide.tex b/doc/guide.tex index 1406b0523..66747bbe5 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -3132,12 +3132,35 @@ online again. Thus it is very similar to how email works. Note that (see section~\ref{ejabberdctl}). \begin{description} - \titem{user\_max\_messages}\ind{options!user\_max\_messages}This option - is use to set a max number of offline messages per user (quota). Its - value can be either \term{infinity} or a strictly positive - integer. The default value is \term{infinity}. + \titem{access\_max\_user\_messages}\ind{options!access\_max\_user\_messages} + This option defines which access rule will be enforced to limit + the maximum number of offline messages that a user can have (quota). + When a user has too many offline messages, any new messages that he receive are discarded, + and a resource-constraint error is returned to the sender. + The default value is \term{max\_user\_offline\_messages}. + Then you can define an access rule with a syntax similar to + \term{max\_user\_sessions} (see \ref{configmaxsessions}). \end{description} +This example allows power users to have as much as 5000 offline messages, +administrators up to 2000, +and all the other users up to 100. +\begin{verbatim} +{acl, admin, {user, "admin1", "localhost"}}. +{acl, admin, {user, "admin2", "example.org"}}. +{acl, poweruser, {user, "bob", "example.org"}}. +{acl, poweruser, {user, "jane", "example.org"}}. + +{access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}. + +{modules, + [ + ... + {mod_offline, [ {access_max_user_messages, max_user_offline_messages} ]}, + ... + ]}. +\end{verbatim} + \makesubsection{modprivacy}{\modprivacy{}} \ind{modules!\modprivacy{}}\ind{Blocking Communication}\ind{Privacy Rules}\ind{protocols!RFC 3921: XMPP IM} diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example index b0fcecadb..ebcd44ed0 100644 --- a/src/ejabberd.cfg.example +++ b/src/ejabberd.cfg.example @@ -379,6 +379,9 @@ %% Maximum number of simultaneous sessions allowed for a single user: {access, max_user_sessions, [{10, all}]}. +%% Maximum number of offline messages that users can have: +{access, max_user_offline_messages, [{5000, admin}, {100, all}]}, + %% This rule allows access only for local users: {access, local, [{allow, local}]}. @@ -481,7 +484,7 @@ {access_admin, muc_admin} ]}, %%{mod_muc_log,[]}, - {mod_offline, []}, + {mod_offline, [{access_max_user_messages, max_user_offline_messages}]}, {mod_privacy, []}, {mod_private, []}, %%{mod_proxy65,[]}, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index e3898eb4f..c9fe276c1 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -30,7 +30,7 @@ -behaviour(gen_mod). -export([start/2, - init/1, + loop/1, stop/1, store_packet/3, resend_offline_messages/2, @@ -52,6 +52,9 @@ -define(PROCNAME, ejabberd_offline). -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000). +%% default value for the maximum number of user messages +-define(MAX_USER_MESSAGES, infinity). + start(Host, Opts) -> mnesia:create_table(offline_msg, [{disc_only_copies, [node()]}, @@ -72,22 +75,18 @@ start(Host, Opts) -> ?MODULE, webadmin_user, 50), ejabberd_hooks:add(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), - MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity), + AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages), register(gen_mod:get_module_proc(Host, ?PROCNAME), - spawn(?MODULE, init, [MaxOfflineMsgs])). - -%% MaxOfflineMsgs is either infinity of integer > 0 -init(infinity) -> - loop(infinity); -init(MaxOfflineMsgs) - when is_integer(MaxOfflineMsgs), MaxOfflineMsgs > 0 -> - loop(MaxOfflineMsgs). + spawn(?MODULE, loop, [AccessMaxOfflineMsgs])). -loop(MaxOfflineMsgs) -> +loop(AccessMaxOfflineMsgs) -> receive #offline_msg{us=US} = Msg -> Msgs = receive_all(US, [Msg]), Len = length(Msgs), + {User, Host} = US, + MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs, + User, Host), F = fun() -> %% Only count messages if needed: Count = if MaxOfflineMsgs =/= infinity -> @@ -113,9 +112,18 @@ loop(MaxOfflineMsgs) -> end end, mnesia:transaction(F), - loop(MaxOfflineMsgs); + loop(AccessMaxOfflineMsgs); _ -> - loop(MaxOfflineMsgs) + loop(AccessMaxOfflineMsgs) + end. + +%% Function copied from ejabberd_sm.erl: +get_max_user_messages(AccessRule, LUser, Host) -> + case acl:match_rule( + Host, AccessRule, jlib:make_jid(LUser, Host, "")) of + Max when is_integer(Max) -> Max; + infinity -> infinity; + _ -> ?MAX_USER_MESSAGES end. receive_all(US, Msgs) -> diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl index 3a61374dc..507da1f11 100644 --- a/src/mod_offline_odbc.erl +++ b/src/mod_offline_odbc.erl @@ -32,7 +32,7 @@ -export([count_offline_messages/2]). -export([start/2, - init/2, + loop/2, stop/1, store_packet/3, pop_offline_messages/3, @@ -51,6 +51,9 @@ -define(PROCNAME, ejabberd_offline). -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000). +%% default value for the maximum number of user messages +-define(MAX_USER_MESSAGES, infinity). + start(Host, Opts) -> ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, store_packet, 50), @@ -66,22 +69,17 @@ start(Host, Opts) -> ?MODULE, webadmin_user, 50), ejabberd_hooks:add(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), - MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity), + AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages), register(gen_mod:get_module_proc(Host, ?PROCNAME), - spawn(?MODULE, init, [Host, MaxOfflineMsgs])). - -%% MaxOfflineMsgs is either infinity of integer > 0 -init(Host, infinity) -> - loop(Host, infinity); -init(Host, MaxOfflineMsgs) - when is_integer(MaxOfflineMsgs), MaxOfflineMsgs > 0 -> - loop(Host, MaxOfflineMsgs). + spawn(?MODULE, loop, [Host, AccessMaxOfflineMsgs])). -loop(Host, MaxOfflineMsgs) -> +loop(Host, AccessMaxOfflineMsgs) -> receive #offline_msg{user = User} = Msg -> Msgs = receive_all(User, [Msg]), Len = length(Msgs), + MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs, + User, Host), %% Only count existing messages if needed: Count = if MaxOfflineMsgs =/= infinity -> @@ -125,9 +123,18 @@ loop(Host, MaxOfflineMsgs) -> ok end end, - loop(Host, MaxOfflineMsgs); + loop(Host, AccessMaxOfflineMsgs); _ -> - loop(Host, MaxOfflineMsgs) + loop(Host, AccessMaxOfflineMsgs) + end. + +%% Function copied from ejabberd_sm.erl: +get_max_user_messages(AccessRule, LUser, Host) -> + case acl:match_rule( + Host, AccessRule, jlib:make_jid(LUser, Host, "")) of + Max when is_integer(Max) -> Max; + infinity -> infinity; + _ -> ?MAX_USER_MESSAGES end. receive_all(Username, Msgs) -> |