mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Process bindings from multiple UACs correctly
This commit is contained in:
parent
da22da23cd
commit
86f2af6fdc
@ -85,17 +85,9 @@ request(#sip{hdrs = Hdrs} = Req, SIPSock) ->
|
|||||||
case register_session(US, SIPSock, CallID, CSeq,
|
case register_session(US, SIPSock, CallID, CSeq,
|
||||||
ContactsWithExpires) of
|
ContactsWithExpires) of
|
||||||
{ok, Res} ->
|
{ok, Res} ->
|
||||||
if Res == updated ->
|
?INFO_MSG("~s SIP session for user ~s@~s from ~s",
|
||||||
?INFO_MSG("register SIP session for user "
|
[Res, LUser, LServer,
|
||||||
"~s@~s from ~s",
|
inet_parse:ntoa(PeerIP)]),
|
||||||
[LUser, LServer,
|
|
||||||
inet_parse:ntoa(PeerIP)]);
|
|
||||||
Res == deleted ->
|
|
||||||
?INFO_MSG("unregister SIP session for user "
|
|
||||||
"~s@~s from ~s",
|
|
||||||
[LUser, LServer,
|
|
||||||
inet_parse:ntoa(PeerIP)])
|
|
||||||
end,
|
|
||||||
Cs = prepare_contacts_to_send(ContactsWithExpires),
|
Cs = prepare_contacts_to_send(ContactsWithExpires),
|
||||||
mod_sip:make_response(
|
mod_sip:make_response(
|
||||||
Req,
|
Req,
|
||||||
@ -219,33 +211,36 @@ write_session(#sip_session{us = {U, S} = US, bindings = NewBindings}) ->
|
|||||||
Err;
|
Err;
|
||||||
(#binding{call_id = CallID,
|
(#binding{call_id = CallID,
|
||||||
expires = Expires,
|
expires = Expires,
|
||||||
cseq = CSeq} = Binding, {Add, Del}) ->
|
cseq = CSeq} = Binding, {Add, Keep, Del}) ->
|
||||||
case find_binding(Binding, PrevBindings) of
|
case find_binding(Binding, PrevBindings) of
|
||||||
{ok, #binding{call_id = CallID, cseq = PrevCSeq}}
|
{ok, #binding{call_id = CallID, cseq = PrevCSeq}}
|
||||||
when PrevCSeq > CSeq ->
|
when PrevCSeq > CSeq ->
|
||||||
{error, cseq_out_of_order};
|
{error, cseq_out_of_order};
|
||||||
{ok, PrevBinding} when Expires == 0 ->
|
{ok, PrevBinding} when Expires == 0 ->
|
||||||
{Add, [PrevBinding|Del]};
|
{Add, Keep -- [PrevBinding], [PrevBinding|Del]};
|
||||||
{ok, _} ->
|
{ok, PrevBinding} ->
|
||||||
{[Binding|Add], Del};
|
{[Binding|Add], Keep -- [PrevBinding], Del};
|
||||||
{error, notfound} when Expires == 0 ->
|
{error, notfound} when Expires == 0 ->
|
||||||
{error, notfound};
|
{error, notfound};
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
{[Binding|Add], Del}
|
{[Binding|Add], Keep, Del}
|
||||||
end
|
end
|
||||||
end, {[], []}, NewBindings),
|
end, {[], PrevBindings, []}, NewBindings),
|
||||||
MaxSessions = ejabberd_sm:get_max_user_sessions(U, S),
|
MaxSessions = ejabberd_sm:get_max_user_sessions(U, S),
|
||||||
case Res of
|
case Res of
|
||||||
{error, Why} ->
|
{error, Why} ->
|
||||||
{error, Why};
|
{error, Why};
|
||||||
{AddBindings, _} when length(AddBindings) > MaxSessions ->
|
{AddBindings, KeepBindings, DelBindings} ->
|
||||||
|
MaxSessions = ejabberd_sm:get_max_user_sessions(U, S),
|
||||||
|
AllBindings = AddBindings ++ KeepBindings,
|
||||||
|
if length(AllBindings) > MaxSessions ->
|
||||||
{error, too_many_sessions};
|
{error, too_many_sessions};
|
||||||
{AddBindings, DelBindings} ->
|
true ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(#binding{tref = TRef}) ->
|
fun(#binding{tref = TRef}) ->
|
||||||
erlang:cancel_timer(TRef)
|
erlang:cancel_timer(TRef)
|
||||||
end, DelBindings),
|
end, DelBindings),
|
||||||
Bindings = lists:map(
|
AddBindings1 = lists:map(
|
||||||
fun(#binding{tref = TRef,
|
fun(#binding{tref = TRef,
|
||||||
expires = Expires} = Binding) ->
|
expires = Expires} = Binding) ->
|
||||||
erlang:cancel_timer(TRef),
|
erlang:cancel_timer(TRef),
|
||||||
@ -253,14 +248,20 @@ write_session(#sip_session{us = {U, S} = US, bindings = NewBindings}) ->
|
|||||||
Expires * 1000, self(), US),
|
Expires * 1000, self(), US),
|
||||||
Binding#binding{tref = NewTRef}
|
Binding#binding{tref = NewTRef}
|
||||||
end, AddBindings),
|
end, AddBindings),
|
||||||
case Bindings of
|
AllBindings1 = AddBindings1 ++ KeepBindings,
|
||||||
|
case AllBindings1 of
|
||||||
[] ->
|
[] ->
|
||||||
mnesia:dirty_delete(sip_session, US),
|
mnesia:dirty_delete(sip_session, US),
|
||||||
{ok, deleted};
|
{ok, unregister};
|
||||||
_ ->
|
_ ->
|
||||||
mnesia:dirty_write(
|
mnesia:dirty_write(
|
||||||
#sip_session{us = US, bindings = Bindings}),
|
#sip_session{us = US, bindings = AllBindings1}),
|
||||||
{ok, updated}
|
if length(DelBindings) == length(NewBindings) ->
|
||||||
|
{ok, unregister};
|
||||||
|
true ->
|
||||||
|
{ok, register}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user