24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-09-21 14:06:57 +02:00

* src/ejabberd_c2s.erl: Some fixes in work with socket

SVN Revision: 99
This commit is contained in:
Alexey Shchepin 2003-04-15 13:48:43 +00:00
parent ae6669c9af
commit 0a166ec7a6
2 changed files with 52 additions and 45 deletions

View File

@ -1,3 +1,7 @@
2003-04-15 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_c2s.erl: Some fixes in work with socket
2003-04-13 Alexey Shchepin <alexey@sevcom.net> 2003-04-13 Alexey Shchepin <alexey@sevcom.net>
* src/mod_muc/mod_muc_room.erl: Support for members-only * src/mod_muc/mod_muc_room.erl: Support for members-only

View File

@ -34,7 +34,9 @@
-define(SETS, gb_sets). -define(SETS, gb_sets).
-record(state, {socket, receiver, streamid, -record(state, {socket, receiver,
sockmod,
streamid,
sasl_state, sasl_state,
access, access,
shaper, shaper,
@ -99,6 +101,7 @@ init([{SockMod, Socket}, Opts]) ->
_ -> none _ -> none
end, end,
{ok, wait_for_stream, #state{socket = Socket, {ok, wait_for_stream, #state{socket = Socket,
sockmod = SockMod,
receiver = ReceiverPid, receiver = ReceiverPid,
streamid = new_id(), streamid = new_id(),
access = Access, access = Access,
@ -120,13 +123,13 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
[StateData#state.streamid, [StateData#state.streamid,
?MYNAME, ?MYNAME,
" version='1.0'"]), " version='1.0'"]),
send_text(StateData#state.socket, Header), send_text(StateData, Header),
SASLState = cyrsasl:server_new("jabber", ?MYNAME, "", []), SASLState = cyrsasl:server_new("jabber", ?MYNAME, "", []),
Mechs = lists:map(fun(S) -> Mechs = lists:map(fun(S) ->
{xmlelement, "mechanism", [], {xmlelement, "mechanism", [],
[{xmlcdata, S}]} [{xmlcdata, S}]}
end, cyrsasl:listmech()), end, cyrsasl:listmech()),
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "stream:features", [], {xmlelement, "stream:features", [],
[{xmlelement, "mechanisms", [{xmlelement, "mechanisms",
[{"xmlns", ?NS_SASL_MECHANISMS}], [{"xmlns", ?NS_SASL_MECHANISMS}],
@ -137,14 +140,14 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
Header = io_lib:format( Header = io_lib:format(
?STREAM_HEADER, ?STREAM_HEADER,
[StateData#state.streamid, ?MYNAME, ""]), [StateData#state.streamid, ?MYNAME, ""]),
send_text(StateData#state.socket, Header), send_text(StateData, Header),
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
end; end;
_ -> _ ->
Header = io_lib:format( Header = io_lib:format(
?STREAM_HEADER, ?STREAM_HEADER,
[StateData#state.streamid, ?MYNAME, ""]), [StateData#state.streamid, ?MYNAME, ""]),
send_text(StateData#state.socket, send_text(StateData,
Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER), Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData} {stop, normal, StateData}
end; end;
@ -152,7 +155,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
wait_for_stream({xmlstreamerror, _}, StateData) -> wait_for_stream({xmlstreamerror, _}, StateData) ->
Header = io_lib:format(?STREAM_HEADER, Header = io_lib:format(?STREAM_HEADER,
["none", ?MYNAME, " version='1.0'"]), ["none", ?MYNAME, " version='1.0'"]),
send_text(StateData#state.socket, send_text(StateData,
Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER), Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -164,7 +167,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
case is_auth_packet(El) of case is_auth_packet(El) of
{auth, ID, get, {"", _, _, _}} -> {auth, ID, get, {"", _, _, _}} ->
Err = jlib:make_error_reply(El, "406", "Not Acceptable"), Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, get, {U, _, _, _}} -> {auth, ID, get, {U, _, _, _}} ->
{xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El), {xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El),
@ -175,11 +178,11 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{xmlelement, "digest", [], []}, {xmlelement, "digest", [], []},
{xmlelement, "resource", [], []} {xmlelement, "resource", [], []}
]}]}, ]}]},
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, set, {U, P, D, ""}} -> {auth, ID, set, {U, P, D, ""}} ->
Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED), Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, set, {U, P, D, R}} -> {auth, ID, set, {U, P, D, R}} ->
io:format("AUTH: ~p~n", [{U, P, D, R}]), io:format("AUTH: ~p~n", [{U, P, D, R}]),
@ -191,7 +194,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
true -> true ->
ejabberd_sm:open_session(U, R), ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El), Res = jlib:make_result_iq_reply(El),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
change_shaper(StateData, JID), change_shaper(StateData, JID),
{Fs, Ts} = mod_roster:get_subscription_lists(U), {Fs, Ts} = mod_roster:get_subscription_lists(U),
{next_state, session_established, {next_state, session_established,
@ -202,12 +205,12 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
_ -> _ ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
El, ?ERR_FORBIDDEN), El, ?ERR_FORBIDDEN),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
end; end;
_ -> _ ->
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
end; end;
_ -> _ ->
@ -220,7 +223,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
_ -> _ ->
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
@ -228,11 +231,11 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
end; end;
wait_for_auth({xmlstreamend, Name}, StateData) -> wait_for_auth({xmlstreamend, Name}, StateData) ->
send_text(StateData#state.socket, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_auth({xmlstreamerror, _}, StateData) -> wait_for_auth({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_auth(closed, StateData) -> wait_for_auth(closed, StateData) ->
@ -249,13 +252,13 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
Mech, Mech,
ClientIn) of ClientIn) of
{ok, Props} -> {ok, Props} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "success", {xmlelement, "success",
[{"xmlns", ?NS_SASL_MECHANISMS}], []}), [{"xmlns", ?NS_SASL_MECHANISMS}], []}),
{next_state, wait_for_resource_auth, {next_state, wait_for_resource_auth,
StateData#state{user = xml:get_attr_s(username, Props)}}; StateData#state{user = xml:get_attr_s(username, Props)}};
{continue, ServerOut, NewSASLState} -> {continue, ServerOut, NewSASLState} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "challenge", {xmlelement, "challenge",
[{"xmlns", ?NS_SASL_MECHANISMS}], [{"xmlns", ?NS_SASL_MECHANISMS}],
[{xmlcdata, [{xmlcdata,
@ -263,7 +266,7 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_sasl_response, {next_state, wait_for_sasl_response,
StateData#state{sasl_state = NewSASLState}}; StateData#state{sasl_state = NewSASLState}};
{error, Code} -> {error, Code} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "failure", {xmlelement, "failure",
[{"xmlns", ?NS_SASL_MECHANISMS}, [{"xmlns", ?NS_SASL_MECHANISMS},
{"code", Code}], {"code", Code}],
@ -280,7 +283,7 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_sasl_auth, StateData}; {next_state, wait_for_sasl_auth, StateData};
_ -> _ ->
{next_state, wait_for_sasl_auth, StateData} {next_state, wait_for_sasl_auth, StateData}
@ -288,11 +291,11 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
end; end;
wait_for_sasl_auth({xmlstreamend, Name}, StateData) -> wait_for_sasl_auth({xmlstreamend, Name}, StateData) ->
send_text(StateData#state.socket, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_sasl_auth({xmlstreamerror, _}, StateData) -> wait_for_sasl_auth({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_sasl_auth(closed, StateData) -> wait_for_sasl_auth(closed, StateData) ->
@ -303,7 +306,7 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
case is_auth_packet(El) of case is_auth_packet(El) of
{auth, ID, get, {"", _, _, _}} -> {auth, ID, get, {"", _, _, _}} ->
Err = jlib:make_error_reply(El, "406", "Not Acceptable"), Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_resource_auth, StateData}; {next_state, wait_for_resource_auth, StateData};
{auth, ID, get, {U, _, _, _}} -> {auth, ID, get, {U, _, _, _}} ->
{xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El), {xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El),
@ -313,11 +316,11 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
[{xmlcdata, StateData#state.user}]}, [{xmlcdata, StateData#state.user}]},
{xmlelement, "resource", [], []} {xmlelement, "resource", [], []}
]}]}, ]}]},
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_resource_auth, StateData}; {next_state, wait_for_resource_auth, StateData};
{auth, ID, set, {U, _, _, ""}} -> {auth, ID, set, {U, _, _, ""}} ->
Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED), Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_resource_auth, StateData}; {next_state, wait_for_resource_auth, StateData};
{auth, ID, set, {U, _, _, R}} -> {auth, ID, set, {U, _, _, R}} ->
case StateData#state.user of case StateData#state.user of
@ -328,7 +331,7 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
allow -> allow ->
ejabberd_sm:open_session(U, R), ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El), Res = jlib:make_result_iq_reply(El),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
change_shaper(StateData, JID), change_shaper(StateData, JID),
{Fs, Ts} = mod_roster:get_subscription_lists(U), {Fs, Ts} = mod_roster:get_subscription_lists(U),
{next_state, session_established, {next_state, session_established,
@ -338,12 +341,12 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts)}}; pres_t = ?SETS:from_list(Ts)}};
_ -> _ ->
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_resource_auth, StateData} {next_state, wait_for_resource_auth, StateData}
end; end;
_ -> _ ->
Err = jlib:make_error_reply(El, "406", "Not Acceptable"), Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
send_element(StateData#state.socket, Err), send_element(StateData, Err),
{next_state, wait_for_resource_auth, StateData} {next_state, wait_for_resource_auth, StateData}
end; end;
_ -> _ ->
@ -356,7 +359,7 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_resource_auth, StateData}; {next_state, wait_for_resource_auth, StateData};
_ -> _ ->
{next_state, wait_for_resource_auth, StateData} {next_state, wait_for_resource_auth, StateData}
@ -364,11 +367,11 @@ wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
end; end;
wait_for_resource_auth({xmlstreamend, Name}, StateData) -> wait_for_resource_auth({xmlstreamend, Name}, StateData) ->
send_text(StateData#state.socket, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_resource_auth({xmlstreamerror, _}, StateData) -> wait_for_resource_auth({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_resource_auth(closed, StateData) -> wait_for_resource_auth(closed, StateData) ->
@ -384,13 +387,13 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
case cyrsasl:server_step(StateData#state.sasl_state, case cyrsasl:server_step(StateData#state.sasl_state,
ClientIn) of ClientIn) of
{ok, Props} -> {ok, Props} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "success", {xmlelement, "success",
[{"xmlns", ?NS_SASL_MECHANISMS}], []}), [{"xmlns", ?NS_SASL_MECHANISMS}], []}),
{next_state, wait_for_resource_auth, {next_state, wait_for_resource_auth,
StateData#state{user = xml:get_attr_s(username, Props)}}; StateData#state{user = xml:get_attr_s(username, Props)}};
{continue, ServerOut, NewSASLState} -> {continue, ServerOut, NewSASLState} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "challenge", {xmlelement, "challenge",
[{"xmlns", ?NS_SASL_MECHANISMS}], [{"xmlns", ?NS_SASL_MECHANISMS}],
[{xmlcdata, [{xmlcdata,
@ -398,7 +401,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_sasl_response, {next_state, wait_for_sasl_response,
StateData#state{sasl_state = NewSASLState}}; StateData#state{sasl_state = NewSASLState}};
{error, Code} -> {error, Code} ->
send_element(StateData#state.socket, send_element(StateData,
{xmlelement, "failure", {xmlelement, "failure",
[{"xmlns", ?NS_SASL_MECHANISMS}, [{"xmlns", ?NS_SASL_MECHANISMS},
{"code", Code}], {"code", Code}],
@ -415,7 +418,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData#state.socket, Res), send_element(StateData, Res),
{next_state, wait_for_sasl_auth, StateData}; {next_state, wait_for_sasl_auth, StateData};
_ -> _ ->
{next_state, wait_for_sasl_auth, StateData} {next_state, wait_for_sasl_auth, StateData}
@ -423,11 +426,11 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
end; end;
wait_for_sasl_response({xmlstreamend, Name}, StateData) -> wait_for_sasl_response({xmlstreamend, Name}, StateData) ->
send_text(StateData#state.socket, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_sasl_response({xmlstreamerror, _}, StateData) -> wait_for_sasl_response({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_sasl_response(closed, StateData) -> wait_for_sasl_response(closed, StateData) ->
@ -473,11 +476,11 @@ session_established({xmlstreamelement, El}, StateData) ->
{next_state, session_established, NewState}; {next_state, session_established, NewState};
session_established({xmlstreamend, Name}, StateData) -> session_established({xmlstreamend, Name}, StateData) ->
send_text(StateData#state.socket, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
session_established({xmlstreamerror, _}, StateData) -> session_established({xmlstreamerror, _}, StateData) ->
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
session_established(closed, StateData) -> session_established(closed, StateData) ->
@ -530,7 +533,7 @@ code_change(OldVsn, StateName, StateData, Extra) ->
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_info({send_text, Text}, StateName, StateData) -> handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.socket, Text), send_text(StateData, Text),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info(replaced, StateName, StateData) -> handle_info(replaced, StateName, StateData) ->
% TODO % TODO
@ -601,7 +604,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
jlib:jid_to_string(To), jlib:jid_to_string(To),
NewAttrs), NewAttrs),
Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}), Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}),
send_text(StateData#state.socket, Text), send_text(StateData, Text),
{next_state, StateName, NewState}; {next_state, StateName, NewState};
true -> true ->
{next_state, StateName, NewState} {next_state, StateName, NewState}
@ -628,7 +631,7 @@ terminate(Reason, StateName, StateData) ->
presence_broadcast(From, StateData#state.pres_a, Packet), presence_broadcast(From, StateData#state.pres_a, Packet),
presence_broadcast(From, StateData#state.pres_i, Packet) presence_broadcast(From, StateData#state.pres_i, Packet)
end, end,
gen_tcp:close(StateData#state.socket), (StateData#state.sockmod):close(StateData#state.socket),
ok. ok.
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
@ -662,11 +665,11 @@ change_shaper(StateData, JID) ->
Shaper = acl:match_rule(StateData#state.shaper, JID), Shaper = acl:match_rule(StateData#state.shaper, JID),
StateData#state.receiver ! {change_shaper, Shaper}. StateData#state.receiver ! {change_shaper, Shaper}.
send_text(Socket, Text) -> send_text(StateData, Text) ->
gen_tcp:send(Socket,Text). (StateData#state.sockmod):send(StateData#state.socket, Text).
send_element(Socket, El) -> send_element(StateData, El) ->
send_text(Socket, xml:element_to_string(El)). send_text(StateData, xml:element_to_string(El)).
new_id() -> new_id() ->