aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_c2s.erl
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2016-01-18 16:33:37 +0300
committerAlexey Shchepin <alexey@process-one.net>2016-01-18 16:33:57 +0300
commita150bf8fdc8061bc60e5cb1a64a1e06f962d6a4e (patch)
treeefea17a18e9d06842a3c8754342de68f8f679549 /src/ejabberd_c2s.erl
parentmod_mam: Remove unused code (diff)
Make C2S session establishment optional (ECS-11)
Diffstat (limited to 'src/ejabberd_c2s.erl')
-rw-r--r--src/ejabberd_c2s.erl163
1 files changed, 77 insertions, 86 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 021fb9739..04e41f468 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -59,7 +59,7 @@
-export([init/1, wait_for_stream/2, wait_for_auth/2,
wait_for_feature_request/2, wait_for_bind/2,
- wait_for_session/2, wait_for_sasl_response/2,
+ wait_for_sasl_response/2,
wait_for_resume/2, session_established/2,
handle_event/3, handle_sync_event/4, code_change/4,
handle_info/3, terminate/3, print_state/1, opt_type/1]).
@@ -473,7 +473,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
children = []},
#xmlel{name = <<"session">>,
attrs = [{<<"xmlns">>, ?NS_SESSION}],
- children = []}]
+ children =
+ [#xmlel{name = <<"optional">>}]}]
++
RosterVersioningFeature ++
StreamManagementFeature ++
@@ -492,7 +493,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
#xmlel{name = <<"stream:features">>,
attrs = [],
children = []}),
- fsm_next_state(wait_for_session,
+ fsm_next_state(session_established,
StateData#state{server = Server, lang = Lang})
end
end;
@@ -1059,20 +1060,32 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
send_element(StateData, Err),
fsm_next_state(wait_for_bind, StateData);
{accept_resource, R2} ->
- JID = jid:make(U, StateData#state.server, R2),
- Res = IQ#iq{type = result,
- sub_el =
- [#xmlel{name = <<"bind">>,
- attrs = [{<<"xmlns">>, ?NS_BIND}],
- children =
- [#xmlel{name = <<"jid">>,
- attrs = [],
- children =
- [{xmlcdata,
- jid:to_string(JID)}]}]}]},
- send_element(StateData, jlib:iq_to_xml(Res)),
- fsm_next_state(wait_for_session,
- StateData#state{resource = R2, jid = JID})
+ JID = jid:make(U, StateData#state.server, R2),
+ StateData2 =
+ StateData#state{resource = R2, jid = JID},
+ case open_session(StateData2) of
+ {ok, StateData3} ->
+ Res =
+ IQ#iq{
+ type = result,
+ sub_el =
+ [#xmlel{name = <<"bind">>,
+ attrs = [{<<"xmlns">>, ?NS_BIND}],
+ children =
+ [#xmlel{name = <<"jid">>,
+ attrs = [],
+ children =
+ [{xmlcdata,
+ jid:to_string(JID)}]}]}]},
+ send_element(StateData3, jlib:iq_to_xml(Res)),
+ fsm_next_state_pack(
+ session_established,
+ StateData3);
+ {error, Error} ->
+ Err = jlib:make_error_reply(El, Error),
+ send_element(StateData, Err),
+ fsm_next_state(wait_for_bind, StateData)
+ end
end
end;
_ -> fsm_next_state(wait_for_bind, StateData)
@@ -1090,75 +1103,49 @@ wait_for_bind(closed, StateData) ->
wait_for_bind(stop, StateData) ->
{stop, normal, StateData}.
-wait_for_session({xmlstreamelement, #xmlel{name = Name} = El}, StateData)
- when ?IS_STREAM_MGMT_TAG(Name) ->
- fsm_next_state(wait_for_session, dispatch_stream_mgmt(El, StateData));
-wait_for_session({xmlstreamelement, El}, StateData) ->
- NewStateData = update_num_stanzas_in(StateData, El),
- case jlib:iq_query_info(El) of
- #iq{type = set, xmlns = ?NS_SESSION} ->
- U = NewStateData#state.user,
- R = NewStateData#state.resource,
- JID = NewStateData#state.jid,
- case acl:match_rule(NewStateData#state.server,
- NewStateData#state.access, JID) of
- allow ->
- ?INFO_MSG("(~w) Opened session for ~s",
- [NewStateData#state.socket, jid:to_string(JID)]),
- Res = jlib:make_result_iq_reply(El#xmlel{children = []}),
- NewState = send_stanza(NewStateData, Res),
- change_shaper(NewState, JID),
- {Fs, Ts} = ejabberd_hooks:run_fold(
- roster_get_subscription_lists,
- NewState#state.server,
- {[], []},
- [U, NewState#state.server]),
- LJID = jid:tolower(jid:remove_resource(JID)),
- Fs1 = [LJID | Fs],
- Ts1 = [LJID | Ts],
- PrivList =
- ejabberd_hooks:run_fold(
- privacy_get_user_list,
- NewState#state.server,
- #userlist{},
- [U, NewState#state.server]),
- Conn = get_conn_type(NewState),
- Info = [{ip, NewState#state.ip}, {conn, Conn},
- {auth_module, NewState#state.auth_module}],
- ejabberd_sm:open_session(
- NewState#state.sid, U, NewState#state.server, R, Info),
- UpdatedStateData =
- NewState#state{
- conn = Conn,
- pres_f = ?SETS:from_list(Fs1),
- pres_t = ?SETS:from_list(Ts1),
- privacy_list = PrivList},
- fsm_next_state_pack(session_established,
- UpdatedStateData);
- _ ->
- ejabberd_hooks:run(forbidden_session_hook,
- NewStateData#state.server, [JID]),
- ?INFO_MSG("(~w) Forbidden session for ~s",
- [NewStateData#state.socket, jid:to_string(JID)]),
- Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
- send_element(NewStateData, Err),
- fsm_next_state(wait_for_session, NewStateData)
- end;
- _ ->
- fsm_next_state(wait_for_session, NewStateData)
- end;
-wait_for_session(timeout, StateData) ->
- {stop, normal, StateData};
-wait_for_session({xmlstreamend, _Name}, StateData) ->
- send_trailer(StateData), {stop, normal, StateData};
-wait_for_session({xmlstreamerror, _}, StateData) ->
- send_element(StateData, ?INVALID_XML_ERR),
- send_trailer(StateData),
- {stop, normal, StateData};
-wait_for_session(closed, StateData) ->
- {stop, normal, StateData};
-wait_for_session(stop, StateData) ->
- {stop, normal, StateData}.
+open_session(StateData) ->
+ U = StateData#state.user,
+ R = StateData#state.resource,
+ JID = StateData#state.jid,
+ case acl:match_rule(StateData#state.server,
+ StateData#state.access, JID) of
+ allow ->
+ ?INFO_MSG("(~w) Opened session for ~s",
+ [StateData#state.socket, jid:to_string(JID)]),
+ change_shaper(StateData, JID),
+ {Fs, Ts} = ejabberd_hooks:run_fold(
+ roster_get_subscription_lists,
+ StateData#state.server,
+ {[], []},
+ [U, StateData#state.server]),
+ LJID = jid:tolower(jid:remove_resource(JID)),
+ Fs1 = [LJID | Fs],
+ Ts1 = [LJID | Ts],
+ PrivList =
+ ejabberd_hooks:run_fold(
+ privacy_get_user_list,
+ StateData#state.server,
+ #userlist{},
+ [U, StateData#state.server]),
+ Conn = get_conn_type(StateData),
+ Info = [{ip, StateData#state.ip}, {conn, Conn},
+ {auth_module, StateData#state.auth_module}],
+ ejabberd_sm:open_session(
+ StateData#state.sid, U, StateData#state.server, R, Info),
+ UpdatedStateData =
+ StateData#state{
+ conn = Conn,
+ pres_f = ?SETS:from_list(Fs1),
+ pres_t = ?SETS:from_list(Ts1),
+ privacy_list = PrivList},
+ {ok, UpdatedStateData};
+ _ ->
+ ejabberd_hooks:run(forbidden_session_hook,
+ StateData#state.server, [JID]),
+ ?INFO_MSG("(~w) Forbidden session for ~s",
+ [StateData#state.socket, jid:to_string(JID)]),
+ {error, ?ERR_NOT_ALLOWED}
+ end.
session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData)
when ?IS_STREAM_MGMT_TAG(Name) ->
@@ -1274,6 +1261,10 @@ session_established2(El, StateData) ->
Xmlns == (?NS_BLOCKING) ->
process_privacy_iq(FromJID, ToJID, IQ,
NewStateData);
+ #iq{xmlns = ?NS_SESSION} ->
+ Res = jlib:make_result_iq_reply(
+ NewEl#xmlel{children = []}),
+ send_stanza(NewStateData, Res);
_ ->
NewEl0 = ejabberd_hooks:run_fold(
user_send_packet, Server, NewEl,