Rewrite several modules to use XML generator
This commit is contained in:
parent
b31ebd2ea0
commit
f91f2bc3d2
|
@ -42,7 +42,7 @@
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
|
|
||||||
-include("jlib.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-record(state,
|
-record(state,
|
||||||
{access_commands = [] :: list(),
|
{access_commands = [] :: list(),
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
-include("ejabberd_commands.hrl").
|
-include("ejabberd_commands.hrl").
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
-include("ejabberd_sm.hrl").
|
-include("ejabberd_sm.hrl").
|
||||||
-include("jlib.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
%%%
|
%%%
|
||||||
%%% gen_mod
|
%%% gen_mod
|
||||||
|
@ -879,20 +879,22 @@ set_presence(User, Host, Resource, Type, Show, Status, Priority)
|
||||||
when is_integer(Priority) ->
|
when is_integer(Priority) ->
|
||||||
BPriority = integer_to_binary(Priority),
|
BPriority = integer_to_binary(Priority),
|
||||||
set_presence(User, Host, Resource, Type, Show, Status, BPriority);
|
set_presence(User, Host, Resource, Type, Show, Status, BPriority);
|
||||||
set_presence(User, Host, Resource, Type, Show, Status, Priority) ->
|
set_presence(User, Host, Resource, Type, Show, Status, Priority0) ->
|
||||||
|
Priority = if is_integer(Priority0) -> Priority0;
|
||||||
|
true -> binary_to_integer(Priority0)
|
||||||
|
end,
|
||||||
case ejabberd_sm:get_session_pid(User, Host, Resource) of
|
case ejabberd_sm:get_session_pid(User, Host, Resource) of
|
||||||
none ->
|
none ->
|
||||||
error;
|
error;
|
||||||
Pid ->
|
Pid ->
|
||||||
USR = jid:to_string(jid:make(User, Host, Resource)),
|
From = jid:make(User, Host, Resource),
|
||||||
US = jid:to_string(jid:make(User, Host, <<>>)),
|
To = jid:make(User, Host),
|
||||||
Message = {route_xmlstreamelement,
|
Presence = #presence{from = From, to = To,
|
||||||
{xmlel, <<"presence">>,
|
type = jlib:binary_to_atom(Type),
|
||||||
[{<<"from">>, USR}, {<<"to">>, US}, {<<"type">>, Type}],
|
show = jlib:binary_to_atom(Show),
|
||||||
[{xmlel, <<"show">>, [], [{xmlcdata, Show}]},
|
status = xmpp:mk_text(Status),
|
||||||
{xmlel, <<"status">>, [], [{xmlcdata, Status}]},
|
priority = Priority},
|
||||||
{xmlel, <<"priority">>, [], [{xmlcdata, Priority}]}]}},
|
Pid ! {route, From, To, Presence},
|
||||||
Pid ! Message,
|
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -930,20 +932,12 @@ user_sessions_info(User, Host) ->
|
||||||
%%%
|
%%%
|
||||||
|
|
||||||
set_nickname(User, Host, Nickname) ->
|
set_nickname(User, Host, Nickname) ->
|
||||||
R = mod_vcard:process_sm_iq(
|
VCard = xmpp:encode(#vcard_temp{nickname = Nickname}),
|
||||||
{jid, User, Host, <<>>, User, Host, <<>>},
|
case mod_vcard:set_vcard(User, jid:nameprep(Host), VCard) of
|
||||||
{jid, User, Host, <<>>, User, Host, <<>>},
|
{error, badarg} ->
|
||||||
{iq, <<>>, set, <<>>, <<"en">>,
|
error;
|
||||||
{xmlel, <<"vCard">>, [
|
ok ->
|
||||||
{<<"xmlns">>, <<"vcard-temp">>}], [
|
ok
|
||||||
{xmlel, <<"NICKNAME">>, [], [{xmlcdata, Nickname}]}
|
|
||||||
]
|
|
||||||
}}),
|
|
||||||
case R of
|
|
||||||
{iq, <<>>, result, <<>>, _L, []} ->
|
|
||||||
ok;
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_vcard(User, Host, Name) ->
|
get_vcard(User, Host, Name) ->
|
||||||
|
@ -967,26 +961,17 @@ set_vcard(User, Host, Name, Subname, SomeContent) ->
|
||||||
%%
|
%%
|
||||||
%% Internal vcard
|
%% Internal vcard
|
||||||
|
|
||||||
get_module_resource(Server) ->
|
|
||||||
case gen_mod:get_module_opt(Server, ?MODULE, module_resource, fun(A) -> A end, none) of
|
|
||||||
none -> list_to_binary(atom_to_list(?MODULE));
|
|
||||||
R when is_binary(R) -> R
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_vcard_content(User, Server, Data) ->
|
get_vcard_content(User, Server, Data) ->
|
||||||
[{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}),
|
case mod_vcard:get_vcard(jid:nodeprep(User), jid:nameprep(Server)) of
|
||||||
JID = jid:make(User, Server, get_module_resource(Server)),
|
[_|_] = Els ->
|
||||||
IQ = #iq{type = get, xmlns = ?NS_VCARD},
|
case get_vcard(Data, Els) of
|
||||||
IQr = Module:Function(JID, JID, IQ),
|
|
||||||
[A1] = IQr#iq.sub_el,
|
|
||||||
case A1#xmlel.children of
|
|
||||||
[_|_] ->
|
|
||||||
case get_vcard(Data, A1) of
|
|
||||||
[false] -> throw(error_no_value_found_in_vcard);
|
[false] -> throw(error_no_value_found_in_vcard);
|
||||||
ElemList -> ?DEBUG("ELS ~p", [ElemList]), [fxml:get_tag_cdata(Elem) || Elem <- ElemList]
|
ElemList -> ?DEBUG("ELS ~p", [ElemList]), [fxml:get_tag_cdata(Elem) || Elem <- ElemList]
|
||||||
end;
|
end;
|
||||||
[] ->
|
[] ->
|
||||||
throw(error_no_vcard_found)
|
throw(error_no_vcard_found);
|
||||||
|
error ->
|
||||||
|
throw(database_failure)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_vcard([<<"TEL">>, TelType], {_, _, _, OldEls}) ->
|
get_vcard([<<"TEL">>, TelType], {_, _, _, OldEls}) ->
|
||||||
|
@ -1011,25 +996,19 @@ set_vcard_content(User, Server, Data, SomeContent) ->
|
||||||
[Bin | _] when is_binary(Bin) -> SomeContent;
|
[Bin | _] when is_binary(Bin) -> SomeContent;
|
||||||
Bin when is_binary(Bin) -> [SomeContent]
|
Bin when is_binary(Bin) -> [SomeContent]
|
||||||
end,
|
end,
|
||||||
[{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}),
|
|
||||||
JID = jid:make(User, Server, get_module_resource(Server)),
|
|
||||||
IQ = #iq{type = get, xmlns = ?NS_VCARD},
|
|
||||||
IQr = Module:Function(JID, JID, IQ),
|
|
||||||
|
|
||||||
%% Get old vcard
|
%% Get old vcard
|
||||||
A4 = case IQr#iq.sub_el of
|
A4 = case mod_vcard:get_vcard(jid:nodeprep(User), jid:nameprep(Server)) of
|
||||||
[A1] ->
|
[A1] ->
|
||||||
{_, _, _, A2} = A1,
|
{_, _, _, A2} = A1,
|
||||||
update_vcard_els(Data, ContentList, A2);
|
update_vcard_els(Data, ContentList, A2);
|
||||||
[] ->
|
[] ->
|
||||||
update_vcard_els(Data, ContentList, [])
|
update_vcard_els(Data, ContentList, []);
|
||||||
|
error ->
|
||||||
|
throw(database_failure)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
%% Build new vcard
|
%% Build new vcard
|
||||||
SubEl = {xmlel, <<"vCard">>, [{<<"xmlns">>,<<"vcard-temp">>}], A4},
|
SubEl = {xmlel, <<"vCard">>, [{<<"xmlns">>,<<"vcard-temp">>}], A4},
|
||||||
IQ2 = #iq{type=set, sub_el = SubEl},
|
mod_vcard:set_vcard(User, jid:nameprep(Server), SubEl),
|
||||||
|
|
||||||
Module:Function(JID, JID, IQ2),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
take_vcard_tel(TelType, [{xmlel, <<"TEL">>, _, SubEls}=OldEl | OldEls], NewEls, Taken) ->
|
take_vcard_tel(TelType, [{xmlel, <<"TEL">>, _, SubEls}=OldEl | OldEls], NewEls, Taken) ->
|
||||||
|
@ -1090,11 +1069,7 @@ add_rosteritem(LU, LS, User, Server, Nick, Group, Subscription, Xattrs) ->
|
||||||
|
|
||||||
subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) ->
|
subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) ->
|
||||||
ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}),
|
ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}),
|
||||||
mod_roster:set_items(
|
mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]}).
|
||||||
LU, LS,
|
|
||||||
{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>, ?NS_ROSTER}],
|
|
||||||
[ItemEl]}).
|
|
||||||
|
|
||||||
delete_rosteritem(LocalUser, LocalServer, User, Server) ->
|
delete_rosteritem(LocalUser, LocalServer, User, Server) ->
|
||||||
case unsubscribe(LocalUser, LocalServer, User, Server) of
|
case unsubscribe(LocalUser, LocalServer, User, Server) of
|
||||||
|
@ -1107,11 +1082,7 @@ delete_rosteritem(LocalUser, LocalServer, User, Server) ->
|
||||||
|
|
||||||
unsubscribe(LU, LS, User, Server) ->
|
unsubscribe(LU, LS, User, Server) ->
|
||||||
ItemEl = build_roster_item(User, Server, remove),
|
ItemEl = build_roster_item(User, Server, remove),
|
||||||
mod_roster:set_items(
|
mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]}).
|
||||||
LU, LS,
|
|
||||||
{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>, ?NS_ROSTER}],
|
|
||||||
[ItemEl]}).
|
|
||||||
|
|
||||||
%% -----------------------------
|
%% -----------------------------
|
||||||
%% Get Roster
|
%% Get Roster
|
||||||
|
@ -1201,28 +1172,16 @@ push_roster_item(LU, LS, R, U, S, Action) ->
|
||||||
ejabberd_router:route(jid:remove_resource(LJID), LJID, ResIQ).
|
ejabberd_router:route(jid:remove_resource(LJID), LJID, ResIQ).
|
||||||
|
|
||||||
build_roster_item(U, S, {add, Nick, Subs, Group}) ->
|
build_roster_item(U, S, {add, Nick, Subs, Group}) ->
|
||||||
{xmlel, <<"item">>,
|
#roster_item{jid = jid:make(U, S),
|
||||||
[{<<"jid">>, jid:to_string(jid:make(U, S, <<>>))},
|
name = Nick,
|
||||||
{<<"name">>, Nick},
|
subscription = jlib:binary_to_atom(Subs),
|
||||||
{<<"subscription">>, Subs}],
|
groups = [Group]};
|
||||||
[{xmlel, <<"group">>, [], [{xmlcdata, Group}]}]
|
|
||||||
};
|
|
||||||
build_roster_item(U, S, remove) ->
|
build_roster_item(U, S, remove) ->
|
||||||
{xmlel, <<"item">>,
|
#roster_item{jid = jid:make(U, S), subscription = remove}.
|
||||||
[{<<"jid">>, jid:to_string(jid:make(U, S, <<>>))},
|
|
||||||
{<<"subscription">>, <<"remove">>}],
|
|
||||||
[]
|
|
||||||
}.
|
|
||||||
|
|
||||||
build_iq_roster_push(Item) ->
|
build_iq_roster_push(Item) ->
|
||||||
{xmlel, <<"iq">>,
|
#iq{type = set, id = <<"push">>,
|
||||||
[{<<"type">>, <<"set">>}, {<<"id">>, <<"push">>}],
|
sub_els = [#roster_query{items = [Item]}]}.
|
||||||
[{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>, ?NS_ROSTER}],
|
|
||||||
[Item]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}.
|
|
||||||
|
|
||||||
build_broadcast(U, S, {add, _Nick, Subs, _Group}) ->
|
build_broadcast(U, S, {add, _Nick, Subs, _Group}) ->
|
||||||
build_broadcast(U, S, list_to_atom(binary_to_list(Subs)));
|
build_broadcast(U, S, list_to_atom(binary_to_list(Subs)));
|
||||||
|
@ -1268,17 +1227,9 @@ get_last(User, Server) ->
|
||||||
%% <aa xmlns='bb'>Cluth</aa>
|
%% <aa xmlns='bb'>Cluth</aa>
|
||||||
|
|
||||||
private_get(Username, Host, Element, Ns) ->
|
private_get(Username, Host, Element, Ns) ->
|
||||||
From = jid:make(Username, Host, <<>>),
|
Els = mod_private:get_data(jid:nodeprep(Username), jid:nameprep(Host),
|
||||||
To = jid:make(Username, Host, <<>>),
|
[Ns, Element]),
|
||||||
IQ = {iq, <<>>, get, ?NS_PRIVATE, <<>>,
|
binary_to_list(fxml:element_to_binary(xmpp:encode(#private{xml_els = Els}))).
|
||||||
{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>,?NS_PRIVATE}],
|
|
||||||
[{xmlel, Element, [{<<"xmlns">>, Ns}], []}]}},
|
|
||||||
ResIq = mod_private:process_sm_iq(From, To, IQ),
|
|
||||||
[{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>, ?NS_PRIVATE}],
|
|
||||||
[SubEl]}] = ResIq#iq.sub_el,
|
|
||||||
binary_to_list(fxml:element_to_binary(SubEl)).
|
|
||||||
|
|
||||||
private_set(Username, Host, ElementString) ->
|
private_set(Username, Host, ElementString) ->
|
||||||
case fxml_stream:parse_element(ElementString) of
|
case fxml_stream:parse_element(ElementString) of
|
||||||
|
@ -1291,13 +1242,9 @@ private_set(Username, Host, ElementString) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
private_set2(Username, Host, Xml) ->
|
private_set2(Username, Host, Xml) ->
|
||||||
From = jid:make(Username, Host, <<>>),
|
NS = fxml:get_tag_attr_s(<<"xmlns">>, Xml),
|
||||||
To = jid:make(Username, Host, <<>>),
|
mod_private:set_data(jid:nodeprep(Username), jid:nameprep(Host),
|
||||||
IQ = {iq, <<>>, set, ?NS_PRIVATE, <<>>,
|
[{NS, Xml}]),
|
||||||
{xmlel, <<"query">>,
|
|
||||||
[{<<"xmlns">>, ?NS_PRIVATE}],
|
|
||||||
[Xml]}},
|
|
||||||
mod_private:process_sm_iq(From, To, IQ),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%%%
|
%%%
|
||||||
|
@ -1395,23 +1342,25 @@ send_packet_all_resources(FromJID, ToU, ToS, ToR, Packet) ->
|
||||||
ejabberd_router:route(FromJID, ToJID, Packet).
|
ejabberd_router:route(FromJID, ToJID, Packet).
|
||||||
|
|
||||||
build_packet(Type, Subject, Body) ->
|
build_packet(Type, Subject, Body) ->
|
||||||
Tail = if Subject == <<"">>; Type == <<"chat">> -> [];
|
#message{type = jlib:binary_to_atom(Type),
|
||||||
true -> [{xmlel, <<"subject">>, [], [{xmlcdata, Subject}]}]
|
body = xmpp:mk_text(Body),
|
||||||
end,
|
subject = xmpp:mk_text(Subject)}.
|
||||||
{xmlel, <<"message">>,
|
|
||||||
[{<<"type">>, Type}, {<<"id">>, randoms:get_string()}],
|
|
||||||
[{xmlel, <<"body">>, [], [{xmlcdata, Body}]} | Tail]
|
|
||||||
}.
|
|
||||||
|
|
||||||
send_stanza(FromString, ToString, Stanza) ->
|
send_stanza(FromString, ToString, Stanza) ->
|
||||||
case fxml_stream:parse_element(Stanza) of
|
try
|
||||||
{error, Error} ->
|
#xmlel{} = El = fxml_stream:parse_element(Stanza),
|
||||||
{error, Error};
|
#jid{} = From = jid:from_string(FromString),
|
||||||
XmlEl ->
|
#jid{} = To = jid:to_string(ToString),
|
||||||
#xmlel{attrs = Attrs} = XmlEl,
|
Pkt = xmpp:decode(El, [ignore_els]),
|
||||||
From = jid:from_string(proplists:get_value(<<"from">>, Attrs, FromString)),
|
ejabberd_router:route(From, To, Pkt)
|
||||||
To = jid:from_string(proplists:get_value(<<"to">>, Attrs, ToString)),
|
catch _:{xmpp_codec, Why} ->
|
||||||
ejabberd_router:route(From, To, XmlEl)
|
io:format("incorrect stanza: ~s~n", [xmpp:format_error(Why)]),
|
||||||
|
{error, Why};
|
||||||
|
_:{badmatch, {error, Why}} ->
|
||||||
|
io:format("invalid xml: ~p~n", [Why]),
|
||||||
|
{error, Why};
|
||||||
|
_:{badmatch, error} ->
|
||||||
|
{error, "JID malformed"}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
send_stanza_c2s(Username, Host, Resource, Stanza) ->
|
send_stanza_c2s(Username, Host, Resource, Stanza) ->
|
||||||
|
@ -1427,17 +1376,15 @@ send_stanza_c2s(Username, Host, Resource, Stanza) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
privacy_set(Username, Host, QueryS) ->
|
privacy_set(Username, Host, QueryS) ->
|
||||||
From = jid:make(Username, Host, <<"">>),
|
From = jid:make(Username, Host),
|
||||||
To = jid:make(<<"">>, Host, <<"">>),
|
To = jid:make(Host),
|
||||||
QueryEl = fxml_stream:parse_element(QueryS),
|
QueryEl = fxml_stream:parse_element(QueryS),
|
||||||
StanzaEl = {xmlel, <<"iq">>, [{<<"type">>, <<"set">>}], [QueryEl]},
|
SubEl = xmpp:decode(QueryEl),
|
||||||
IQ = jlib:iq_query_info(StanzaEl),
|
IQ = #iq{type = set, id = <<"push">>, sub_els = [SubEl]},
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(privacy_iq_set,
|
||||||
privacy_iq_set,
|
Host,
|
||||||
Host,
|
{error, xmpp:err_feature_not_implemented()},
|
||||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
|
[From, To, IQ]),
|
||||||
[From, To, IQ]
|
|
||||||
),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%%%
|
%%%
|
||||||
|
@ -1618,5 +1565,4 @@ is_glob_match(String, <<"!", Glob/binary>>) ->
|
||||||
is_glob_match(String, Glob) ->
|
is_glob_match(String, Glob) ->
|
||||||
is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)).
|
is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)).
|
||||||
|
|
||||||
mod_opt_type(module_resource) -> fun (A) -> A end;
|
mod_opt_type(_) -> [].
|
||||||
mod_opt_type(_) -> [module_resource].
|
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,6 @@
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
|
|
||||||
-include("jlib.hrl").
|
|
||||||
|
|
||||||
-include_lib("kernel/include/file.hrl").
|
-include_lib("kernel/include/file.hrl").
|
||||||
|
|
||||||
-record(state,
|
-record(state,
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jid.hrl").
|
||||||
|
|
||||||
-define(HOOKS, [offline_message_hook,
|
-define(HOOKS, [offline_message_hook,
|
||||||
sm_register_connection_hook, sm_remove_connection_hook,
|
sm_register_connection_hook, sm_remove_connection_hook,
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
-include("jlib.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-record(pres_counter,
|
-record(pres_counter,
|
||||||
{dir, start, count, logged = false}).
|
{dir, start, count, logged = false}).
|
||||||
|
@ -52,27 +52,24 @@ depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
check_packet(_, _User, Server, _PrivacyList,
|
check_packet(_, _User, Server, _PrivacyList,
|
||||||
{From, To, #xmlel{name = Name, attrs = Attrs}}, Dir) ->
|
{From, To, #presence{type = Type}}, Dir) ->
|
||||||
case Name of
|
IsSubscription = case Type of
|
||||||
<<"presence">> ->
|
subscribe -> true;
|
||||||
IsSubscription = case fxml:get_attr_s(<<"type">>, Attrs)
|
subscribed -> true;
|
||||||
of
|
unsubscribe -> true;
|
||||||
<<"subscribe">> -> true;
|
unsubscribed -> true;
|
||||||
<<"subscribed">> -> true;
|
_ -> false
|
||||||
<<"unsubscribe">> -> true;
|
end,
|
||||||
<<"unsubscribed">> -> true;
|
if IsSubscription ->
|
||||||
_ -> false
|
JID = case Dir of
|
||||||
end,
|
in -> To;
|
||||||
if IsSubscription ->
|
out -> From
|
||||||
JID = case Dir of
|
end,
|
||||||
in -> To;
|
update(Server, JID, Dir);
|
||||||
out -> From
|
true -> allow
|
||||||
end,
|
end;
|
||||||
update(Server, JID, Dir);
|
check_packet(_, _User, _Server, _PrivacyList, _Pkt, _Dir) ->
|
||||||
true -> allow
|
allow.
|
||||||
end;
|
|
||||||
_ -> allow
|
|
||||||
end.
|
|
||||||
|
|
||||||
update(Server, JID, Dir) ->
|
update(Server, JID, Dir) ->
|
||||||
StormCount = gen_mod:get_module_opt(Server, ?MODULE, count,
|
StormCount = gen_mod:get_module_opt(Server, ?MODULE, count,
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_sm_iq/1, import/3,
|
-export([start/2, stop/1, process_sm_iq/1, import/3,
|
||||||
remove_user/2, get_data/2, export/1, import/1,
|
remove_user/2, get_data/2, get_data/3, export/1, import/1,
|
||||||
mod_opt_type/1, set_data/3, depends/2]).
|
mod_opt_type/1, set_data/3, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
|
@ -33,24 +33,17 @@
|
||||||
-export([init/1, handle_info/2, handle_call/3,
|
-export([init/1, handle_info/2, handle_call/3,
|
||||||
handle_cast/2, terminate/2, code_change/3]).
|
handle_cast/2, terminate/2, code_change/3]).
|
||||||
|
|
||||||
-export([start_link/2, add_listener/2,
|
-export([start_link/2, add_listener/2, process_disco_info/1,
|
||||||
|
process_disco_items/1, process_vcard/1, process_bytestreams/1,
|
||||||
transform_module_options/1, delete_listener/1]).
|
transform_module_options/1, delete_listener/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("xmpp.hrl").
|
||||||
-include("jlib.hrl").
|
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_proxy65_service).
|
-define(PROCNAME, ejabberd_mod_proxy65_service).
|
||||||
|
|
||||||
-record(state,
|
-record(state, {myhost = <<"">> :: binary()}).
|
||||||
{myhost = <<"">> :: binary(),
|
|
||||||
serverhost = <<"">> :: binary(),
|
|
||||||
name = <<"">> :: binary(),
|
|
||||||
stream_addr = [] :: [attr()],
|
|
||||||
port = 0 :: inet:port_number(),
|
|
||||||
ip = {127,0,0,1} :: inet:ip_address(),
|
|
||||||
acl = none :: atom()}).
|
|
||||||
|
|
||||||
%%%------------------------
|
%%%------------------------
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
|
@ -62,34 +55,32 @@ start_link(Host, Opts) ->
|
||||||
[Host, Opts], []).
|
[Host, Opts], []).
|
||||||
|
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
State = parse_options(Host, Opts),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
ejabberd_router:register_route(State#state.myhost, Host),
|
one_queue),
|
||||||
{ok, State}.
|
MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
|
||||||
|
?MODULE, process_disco_info, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS,
|
||||||
|
?MODULE, process_disco_items, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD,
|
||||||
|
?MODULE, process_vcard, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS,
|
||||||
|
?MODULE, process_bytestreams, IQDisc),
|
||||||
|
ejabberd_router:register_route(MyHost, Host),
|
||||||
|
{ok, #state{myhost = MyHost}}.
|
||||||
|
|
||||||
terminate(_Reason, #state{myhost = MyHost}) ->
|
terminate(_Reason, #state{myhost = MyHost}) ->
|
||||||
ejabberd_router:unregister_route(MyHost), ok.
|
ejabberd_router:unregister_route(MyHost),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS).
|
||||||
|
|
||||||
handle_info({route, From, To,
|
handle_info({route, From, To, #iq{} = Packet}, State) ->
|
||||||
#xmlel{name = <<"iq">>} = Packet},
|
ejabberd_router:process_iq(From, To, Packet),
|
||||||
State) ->
|
|
||||||
IQ = jlib:iq_query_info(Packet),
|
|
||||||
case catch process_iq(From, IQ, State) of
|
|
||||||
Result when is_record(Result, iq) ->
|
|
||||||
ejabberd_router:route(To, From, jlib:iq_to_xml(Result));
|
|
||||||
{'EXIT', Reason} ->
|
|
||||||
?ERROR_MSG("Error when processing IQ stanza: ~p",
|
|
||||||
[Reason]),
|
|
||||||
Err = jlib:make_error_reply(Packet,
|
|
||||||
?ERR_INTERNAL_SERVER_ERROR),
|
|
||||||
ejabberd_router:route(To, From, Err);
|
|
||||||
_ -> ok
|
|
||||||
end,
|
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_info(_Info, State) -> {noreply, State}.
|
handle_info(_Info, State) -> {noreply, State}.
|
||||||
|
|
||||||
handle_call(get_port_ip, _From, State) ->
|
|
||||||
{reply, {port_ip, State#state.port, State#state.ip},
|
|
||||||
State};
|
|
||||||
handle_call(_Request, _From, State) ->
|
handle_call(_Request, _From, State) ->
|
||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
|
|
||||||
|
@ -102,185 +93,122 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||||
%%%------------------------
|
%%%------------------------
|
||||||
|
|
||||||
add_listener(Host, Opts) ->
|
add_listener(Host, Opts) ->
|
||||||
State = parse_options(Host, Opts),
|
|
||||||
NewOpts = [Host | Opts],
|
NewOpts = [Host | Opts],
|
||||||
ejabberd_listener:add_listener({State#state.port,
|
ejabberd_listener:add_listener(get_port_ip(Host),
|
||||||
State#state.ip},
|
|
||||||
mod_proxy65_stream, NewOpts).
|
mod_proxy65_stream, NewOpts).
|
||||||
|
|
||||||
delete_listener(Host) ->
|
delete_listener(Host) ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
catch ejabberd_listener:delete_listener(get_port_ip(Host),
|
||||||
{port_ip, Port, IP} = gen_server:call(Proc,
|
|
||||||
get_port_ip),
|
|
||||||
catch ejabberd_listener:delete_listener({Port, IP},
|
|
||||||
mod_proxy65_stream).
|
mod_proxy65_stream).
|
||||||
|
|
||||||
%%%------------------------
|
%%%------------------------
|
||||||
%%% IQ Processing
|
%%% IQ Processing
|
||||||
%%%------------------------
|
%%%------------------------
|
||||||
|
-spec process_disco_info(iq()) -> iq().
|
||||||
|
process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
|
process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) ->
|
||||||
|
Host = ejabberd_router:host_of_route(To#jid.lserver),
|
||||||
|
Name = gen_mod:get_module_opt(Host, mod_proxy65, name,
|
||||||
|
fun iolist_to_binary/1,
|
||||||
|
<<"SOCKS5 Bytestreams">>),
|
||||||
|
Info = ejabberd_hooks:run_fold(disco_info, Host,
|
||||||
|
[], [Host, ?MODULE, <<"">>, <<"">>]),
|
||||||
|
xmpp:make_iq_result(
|
||||||
|
IQ, #disco_info{xdata = Info,
|
||||||
|
identities = [#identity{category = <<"proxy">>,
|
||||||
|
type = <<"bytestreams">>,
|
||||||
|
name = translate:translate(Lang, Name)}],
|
||||||
|
features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS,
|
||||||
|
?NS_VCARD, ?NS_BYTESTREAMS]}).
|
||||||
|
|
||||||
%% disco#info request
|
-spec process_disco_items(iq()) -> iq().
|
||||||
process_iq(_,
|
process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
#iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} =
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
IQ,
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
#state{name = Name, serverhost = ServerHost}) ->
|
process_disco_items(#iq{type = get} = IQ) ->
|
||||||
Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
|
xmpp:make_iq_result(IQ, #disco_items{}).
|
||||||
[], [ServerHost, ?MODULE, <<"">>, <<"">>]),
|
|
||||||
IQ#iq{type = result,
|
-spec process_vcard(iq()) -> iq().
|
||||||
sub_el =
|
process_vcard(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
[#xmlel{name = <<"query">>,
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}],
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
children = iq_disco_info(Lang, Name) ++ Info}]};
|
process_vcard(#iq{type = get, lang = Lang} = IQ) ->
|
||||||
%% disco#items request
|
Desc = translate:translate(Lang, <<"ejabberd SOCKS5 Bytestreams module">>),
|
||||||
process_iq(_,
|
Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>,
|
||||||
#iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) ->
|
xmpp:make_iq_result(
|
||||||
IQ#iq{type = result,
|
IQ, #vcard_temp{fn = <<"ejabberd/mod_proxy65">>,
|
||||||
sub_el =
|
url = ?EJABBERD_URI,
|
||||||
[#xmlel{name = <<"query">>,
|
desc = <<Desc/binary, $\n, Copyright/binary>>}).
|
||||||
attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}],
|
|
||||||
children = []}]};
|
-spec process_bytestreams(iq()) -> iq().
|
||||||
%% vCard request
|
process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) ->
|
||||||
process_iq(_,
|
Host = To#jid.lserver,
|
||||||
#iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ,
|
ServerHost = ejabberd_router:host_of_route(Host),
|
||||||
_) ->
|
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access,
|
||||||
IQ#iq{type = result,
|
fun acl:access_rules_validator/1,
|
||||||
sub_el =
|
all),
|
||||||
[#xmlel{name = <<"vCard">>,
|
|
||||||
attrs = [{<<"xmlns">>, ?NS_VCARD}],
|
|
||||||
children = iq_vcard(Lang)}]};
|
|
||||||
%% bytestreams info request
|
|
||||||
process_iq(JID,
|
|
||||||
#iq{type = get, sub_el = SubEl, lang = Lang,
|
|
||||||
xmlns = ?NS_BYTESTREAMS} =
|
|
||||||
IQ,
|
|
||||||
#state{acl = ACL, stream_addr = StreamAddr,
|
|
||||||
serverhost = ServerHost}) ->
|
|
||||||
case acl:match_rule(ServerHost, ACL, JID) of
|
case acl:match_rule(ServerHost, ACL, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
StreamHostEl = [#xmlel{name = <<"streamhost">>,
|
StreamHost = get_streamhost(Host, ServerHost),
|
||||||
attrs = StreamAddr, children = []}],
|
xmpp:make_iq_result(IQ, #bytestreams{hosts = [StreamHost]});
|
||||||
IQ#iq{type = result,
|
deny ->
|
||||||
sub_el =
|
xmpp:make_error(IQ, xmpp:err_forbidden(<<"Denied by ACL">>, Lang))
|
||||||
[#xmlel{name = <<"query">>,
|
|
||||||
attrs = [{<<"xmlns">>, ?NS_BYTESTREAMS}],
|
|
||||||
children = StreamHostEl}]};
|
|
||||||
deny ->
|
|
||||||
Txt = <<"Denied by ACL">>,
|
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
|
||||||
end;
|
end;
|
||||||
%% bytestream activation request
|
process_bytestreams(#iq{type = set, lang = Lang,
|
||||||
process_iq(InitiatorJID,
|
sub_els = [#bytestreams{sid = undefined}]} = IQ) ->
|
||||||
#iq{type = set, sub_el = SubEl, lang = Lang,
|
Why = {missing_attr, <<"sid">>, <<"query">>, ?NS_BYTESTREAMS},
|
||||||
xmlns = ?NS_BYTESTREAMS} =
|
Txt = xmpp:format_error(Why),
|
||||||
IQ,
|
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
|
||||||
#state{acl = ACL, serverhost = ServerHost}) ->
|
process_bytestreams(#iq{type = set, lang = Lang,
|
||||||
|
sub_els = [#bytestreams{sid = SID}]} = IQ)
|
||||||
|
when SID == <<"">> orelse length(SID) > 128 ->
|
||||||
|
Why = {bad_attr_value, <<"sid">>, <<"query">>, ?NS_BYTESTREAMS},
|
||||||
|
Txt = xmpp:format_error(Why),
|
||||||
|
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
|
||||||
|
process_bytestreams(#iq{type = set, lang = Lang,
|
||||||
|
sub_els = [#bytestreams{activate = undefined}]} = IQ) ->
|
||||||
|
Why = {missing_cdata, <<"">>, <<"activate">>, ?NS_BYTESTREAMS},
|
||||||
|
Txt = xmpp:format_error(Why),
|
||||||
|
xmpp:make_error(IQ, xmpp:err_jid_malformed(Txt, Lang));
|
||||||
|
process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To,
|
||||||
|
sub_els = [#bytestreams{activate = TargetJID,
|
||||||
|
sid = SID}]} = IQ) ->
|
||||||
|
ServerHost = ejabberd_router:host_of_route(To#jid.lserver),
|
||||||
|
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access,
|
||||||
|
fun acl:access_rules_validator/1,
|
||||||
|
all),
|
||||||
case acl:match_rule(ServerHost, ACL, InitiatorJID) of
|
case acl:match_rule(ServerHost, ACL, InitiatorJID) of
|
||||||
allow ->
|
allow ->
|
||||||
ActivateEl = fxml:get_path_s(SubEl,
|
Target = jid:to_string(jid:tolower(TargetJID)),
|
||||||
[{elem, <<"activate">>}]),
|
Initiator = jid:to_string(jid:tolower(InitiatorJID)),
|
||||||
SID = fxml:get_tag_attr_s(<<"sid">>, SubEl),
|
SHA1 = p1_sha:sha(<<SID/binary, Initiator/binary, Target/binary>>),
|
||||||
case catch
|
case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID,
|
||||||
jid:from_string(fxml:get_tag_cdata(ActivateEl))
|
TargetJID, ServerHost) of
|
||||||
of
|
ok ->
|
||||||
TargetJID
|
xmpp:make_iq_result(IQ);
|
||||||
when is_record(TargetJID, jid), SID /= <<"">>,
|
false ->
|
||||||
byte_size(SID) =< 128, TargetJID /= InitiatorJID ->
|
Txt = <<"Failed to activate bytestream">>,
|
||||||
Target =
|
xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
|
||||||
jid:to_string(jid:tolower(TargetJID)),
|
limit ->
|
||||||
Initiator =
|
Txt = <<"Too many active bytestreams">>,
|
||||||
jid:to_string(jid:tolower(InitiatorJID)),
|
xmpp:make_error(IQ, xmpp:err_resource_constraint(Txt, Lang));
|
||||||
SHA1 = p1_sha:sha(<<SID/binary, Initiator/binary, Target/binary>>),
|
conflict ->
|
||||||
case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID,
|
Txt = <<"Bytestream already activated">>,
|
||||||
TargetJID, ServerHost)
|
xmpp:make_error(IQ, xmpp:err_conflict(Txt, Lang));
|
||||||
of
|
Err ->
|
||||||
ok -> IQ#iq{type = result, sub_el = []};
|
?ERROR_MSG("failed to activate bytestream from ~s to ~s: ~p",
|
||||||
false ->
|
[Initiator, Target, Err]),
|
||||||
Txt = <<"Failed to activate bytestream">>,
|
xmpp:make_error(IQ, xmpp:err_internal_server_error())
|
||||||
IQ#iq{type = error,
|
end;
|
||||||
sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
|
deny ->
|
||||||
limit ->
|
Txt = <<"Denied by ACL">>,
|
||||||
Txt = <<"Too many active bytestreams">>,
|
xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang))
|
||||||
IQ#iq{type = error,
|
end.
|
||||||
sub_el = [SubEl, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)]};
|
|
||||||
conflict ->
|
|
||||||
Txt = <<"Bytestream already activated">>,
|
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_CONFLICT(Lang, Txt)]};
|
|
||||||
_ ->
|
|
||||||
IQ#iq{type = error,
|
|
||||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
Txt = <<"Malformed JID">>,
|
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
|
||||||
end;
|
|
||||||
deny ->
|
|
||||||
Txt = <<"Denied by ACL">>,
|
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
|
||||||
end;
|
|
||||||
%% Unknown "set" or "get" request
|
|
||||||
process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _)
|
|
||||||
when Type == get; Type == set ->
|
|
||||||
IQ#iq{type = error,
|
|
||||||
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
|
|
||||||
%% IQ "result" or "error".
|
|
||||||
process_iq(_, _, _) -> ok.
|
|
||||||
|
|
||||||
%%%-------------------------
|
%%%-------------------------
|
||||||
%%% Auxiliary functions.
|
%%% Auxiliary functions.
|
||||||
%%%-------------------------
|
%%%-------------------------
|
||||||
-define(FEATURE(Feat),
|
|
||||||
#xmlel{name = <<"feature">>,
|
|
||||||
attrs = [{<<"var">>, Feat}], children = []}).
|
|
||||||
|
|
||||||
iq_disco_info(Lang, Name) ->
|
|
||||||
[#xmlel{name = <<"identity">>,
|
|
||||||
attrs =
|
|
||||||
[{<<"category">>, <<"proxy">>},
|
|
||||||
{<<"type">>, <<"bytestreams">>},
|
|
||||||
{<<"name">>, translate:translate(Lang, Name)}],
|
|
||||||
children = []},
|
|
||||||
?FEATURE((?NS_DISCO_INFO)), ?FEATURE((?NS_VCARD)),
|
|
||||||
?FEATURE((?NS_BYTESTREAMS))].
|
|
||||||
|
|
||||||
iq_vcard(Lang) ->
|
|
||||||
[#xmlel{name = <<"FN">>, attrs = [],
|
|
||||||
children = [{xmlcdata, <<"ejabberd/mod_proxy65">>}]},
|
|
||||||
#xmlel{name = <<"URL">>, attrs = [],
|
|
||||||
children = [{xmlcdata, ?EJABBERD_URI}]},
|
|
||||||
#xmlel{name = <<"DESC">>, attrs = [],
|
|
||||||
children =
|
|
||||||
[{xmlcdata,
|
|
||||||
<<(translate:translate(Lang,
|
|
||||||
<<"ejabberd SOCKS5 Bytestreams module">>))/binary,
|
|
||||||
"\nCopyright (c) 2003-2016 ProcessOne">>}]}].
|
|
||||||
|
|
||||||
parse_options(ServerHost, Opts) ->
|
|
||||||
MyHost = gen_mod:get_opt_host(ServerHost, Opts,
|
|
||||||
<<"proxy.@HOST@">>),
|
|
||||||
Port = gen_mod:get_opt(port, Opts,
|
|
||||||
fun(P) when is_integer(P), P>0, P<65536 -> P end,
|
|
||||||
7777),
|
|
||||||
ACL = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
Name = gen_mod:get_opt(name, Opts, fun iolist_to_binary/1,
|
|
||||||
<<"SOCKS5 Bytestreams">>),
|
|
||||||
IP = gen_mod:get_opt(ip, Opts,
|
|
||||||
fun(S) ->
|
|
||||||
{ok, Addr} = inet_parse:address(
|
|
||||||
binary_to_list(
|
|
||||||
iolist_to_binary(S))),
|
|
||||||
Addr
|
|
||||||
end, get_my_ip()),
|
|
||||||
HostName = gen_mod:get_opt(hostname, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
jlib:ip_to_list(IP)),
|
|
||||||
StreamAddr = [{<<"jid">>, MyHost},
|
|
||||||
{<<"host">>, HostName},
|
|
||||||
{<<"port">>, jlib:integer_to_binary(Port)}],
|
|
||||||
#state{myhost = MyHost, serverhost = ServerHost,
|
|
||||||
name = Name, port = Port, ip = IP,
|
|
||||||
stream_addr = StreamAddr, acl = ACL}.
|
|
||||||
|
|
||||||
transform_module_options(Opts) ->
|
transform_module_options(Opts) ->
|
||||||
lists:map(
|
lists:map(
|
||||||
fun({ip, IP}) when is_tuple(IP) ->
|
fun({ip, IP}) when is_tuple(IP) ->
|
||||||
|
@ -291,6 +219,33 @@ transform_module_options(Opts) ->
|
||||||
Opt
|
Opt
|
||||||
end, Opts).
|
end, Opts).
|
||||||
|
|
||||||
|
-spec get_streamhost(binary(), binary()) -> streamhost().
|
||||||
|
get_streamhost(Host, ServerHost) ->
|
||||||
|
{Port, IP} = get_port_ip(ServerHost),
|
||||||
|
HostName = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname,
|
||||||
|
fun iolist_to_binary/1,
|
||||||
|
jlib:ip_to_list(IP)),
|
||||||
|
#streamhost{jid = jid:make(Host),
|
||||||
|
host = HostName,
|
||||||
|
port = Port}.
|
||||||
|
|
||||||
|
-spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}.
|
||||||
|
get_port_ip(Host) ->
|
||||||
|
Port = gen_mod:get_module_opt(Host, mod_proxy65, port,
|
||||||
|
fun(P) when is_integer(P), P>0, P<65536 ->
|
||||||
|
P
|
||||||
|
end,
|
||||||
|
7777),
|
||||||
|
IP = gen_mod:get_module_opt(Host, mod_proxy65, ip,
|
||||||
|
fun(S) ->
|
||||||
|
{ok, Addr} = inet_parse:address(
|
||||||
|
binary_to_list(
|
||||||
|
iolist_to_binary(S))),
|
||||||
|
Addr
|
||||||
|
end, get_my_ip()),
|
||||||
|
{Port, IP}.
|
||||||
|
|
||||||
|
-spec get_my_ip() -> inet:ip_address().
|
||||||
get_my_ip() ->
|
get_my_ip() ->
|
||||||
{ok, MyHostName} = inet:gethostname(),
|
{ok, MyHostName} = inet:gethostname(),
|
||||||
case inet:getaddr(MyHostName, inet) of
|
case inet:getaddr(MyHostName, inet) of
|
||||||
|
|
|
@ -38,14 +38,12 @@
|
||||||
|
|
||||||
-record(state, {max_connections = infinity :: non_neg_integer() | infinity}).
|
-record(state, {max_connections = infinity :: non_neg_integer() | infinity}).
|
||||||
|
|
||||||
-include("jlib.hrl").
|
|
||||||
|
|
||||||
-record(bytestream,
|
-record(bytestream,
|
||||||
{sha1 = <<"">> :: binary() | '$1',
|
{sha1 = <<"">> :: binary() | '$1',
|
||||||
target :: pid() | '_',
|
target :: pid() | '_',
|
||||||
initiator :: pid() | '_',
|
initiator :: pid() | '_',
|
||||||
active = false :: boolean() | '_',
|
active = false :: boolean() | '_',
|
||||||
jid_i = {<<"">>, <<"">>, <<"">>} :: ljid() | '_'}).
|
jid_i = {<<"">>, <<"">>, <<"">>} :: jid:ljid() | '_'}).
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_proxy65_sm).
|
-define(PROCNAME, ejabberd_mod_proxy65_sm).
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,7 @@ log_user_receive(Packet, _C2SState, _JID, From, To) ->
|
||||||
log_packet(From, To, Packet, To#jid.lserver),
|
log_packet(From, To, Packet, To#jid.lserver),
|
||||||
Packet.
|
Packet.
|
||||||
|
|
||||||
log_packet(From, To,
|
log_packet(From, To, Packet, Host) ->
|
||||||
#xmlel{name = Name, attrs = Attrs, children = Els},
|
|
||||||
Host) ->
|
|
||||||
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers,
|
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers,
|
||||||
fun(L) ->
|
fun(L) ->
|
||||||
lists:map(
|
lists:map(
|
||||||
|
@ -76,22 +74,11 @@ log_packet(From, To,
|
||||||
end
|
end
|
||||||
end, L)
|
end, L)
|
||||||
end, []),
|
end, []),
|
||||||
ServerJID = #jid{user = <<"">>, server = Host,
|
ServerJID = jid:make(Host),
|
||||||
resource = <<"">>, luser = <<"">>, lserver = Host,
|
FixedPacket = xmpp:set_from_to(Packet, From, To),
|
||||||
lresource = <<"">>},
|
|
||||||
NewAttrs =
|
|
||||||
jlib:replace_from_to_attrs(jid:to_string(From),
|
|
||||||
jid:to_string(To), Attrs),
|
|
||||||
FixedPacket = #xmlel{name = Name, attrs = NewAttrs,
|
|
||||||
children = Els},
|
|
||||||
lists:foreach(fun (Logger) ->
|
lists:foreach(fun (Logger) ->
|
||||||
ejabberd_router:route(ServerJID,
|
ejabberd_router:route(ServerJID,
|
||||||
#jid{user = <<"">>,
|
jid:make(Logger),
|
||||||
server = Logger,
|
|
||||||
resource = <<"">>,
|
|
||||||
luser = <<"">>,
|
|
||||||
lserver = Logger,
|
|
||||||
lresource = <<"">>},
|
|
||||||
#xmlel{name = <<"route">>,
|
#xmlel{name = <<"route">>,
|
||||||
attrs = [],
|
attrs = [],
|
||||||
children =
|
children =
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
-export([start/2, init/3, stop/1, get_sm_features/5,
|
-export([start/2, init/3, stop/1, get_sm_features/5,
|
||||||
process_local_iq/1, process_sm_iq/1, string2lower/1,
|
process_local_iq/1, process_sm_iq/1, string2lower/1,
|
||||||
remove_user/2, export/1, import/1, import/3, depends/2,
|
remove_user/2, export/1, import/1, import/3, depends/2,
|
||||||
process_search/1, process_vcard/1,
|
process_search/1, process_vcard/1, get_vcard/2,
|
||||||
disco_items/5, disco_features/5, disco_identity/5,
|
disco_items/5, disco_features/5, disco_identity/5,
|
||||||
mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
|
mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ make_vcard_search(User, LUser, LServer, VCARD) ->
|
||||||
orgunit = OrgUnit,
|
orgunit = OrgUnit,
|
||||||
lorgunit = LOrgUnit}.
|
lorgunit = LOrgUnit}.
|
||||||
|
|
||||||
-spec set_vcard(binary(), binary(), xmlel()) -> any().
|
-spec set_vcard(binary(), binary(), xmlel()) -> {error, badarg} | ok.
|
||||||
set_vcard(User, LServer, VCARD) ->
|
set_vcard(User, LServer, VCARD) ->
|
||||||
case jid:nodeprep(User) of
|
case jid:nodeprep(User) of
|
||||||
error ->
|
error ->
|
||||||
|
|
Loading…
Reference in New Issue