diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mod_sip_proxy.erl | 26 | ||||
-rw-r--r-- | src/mod_sip_registrar.erl | 81 |
2 files changed, 59 insertions, 48 deletions
diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index 7a10671e4..16c45df5c 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -47,9 +47,9 @@ route(Req, LServer, Opts) -> case connect(Req1, add_certfile(LServer, Opts)) of {ok, SIPSocketsWithURIs} -> lists:foreach( - fun({SIPSocket, URI}) -> + fun({SIPSocket, _URI}) -> Req2 = add_via(SIPSocket, LServer, Req1), - esip:send(SIPSocket, Req2#sip{uri = URI}) + esip:send(SIPSocket, Req2) end, SIPSocketsWithURIs); _ -> error @@ -72,9 +72,10 @@ wait_for_request({#sip{type = request} = Req, TrID}, State) -> fun(_SIPSocketWithURI, {error, _} = Err) -> Err; ({SIPSocket, URI}, #state{tr_ids = TrIDs} = AccState) -> - Req2 = add_record_route(SIPSocket, State#state.host, Req1), + Req2 = add_record_route_and_set_uri( + URI, State#state.host, Req1), Req3 = add_via(SIPSocket, State#state.host, Req2), - case esip:request(SIPSocket, Req3#sip{uri = URI}, + case esip:request(SIPSocket, Req3, {?MODULE, route, [self()]}) of {ok, ClientTrID} -> NewTrIDs = [ClientTrID|TrIDs], @@ -248,10 +249,19 @@ add_via(#sip_socket{type = Transport}, LServer, #sip{hdrs = Hdrs} = Req) -> {<<"rport">>, <<"">>}]}, Req#sip{hdrs = [{'via', [Via]}|Hdrs]}. -add_record_route(_SIPSocket, LServer, #sip{hdrs = Hdrs} = Req) -> - URI = #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}, - Hdrs1 = [{'record-route', [{<<>>, URI, []}]}|Hdrs], - Req#sip{hdrs = Hdrs1}. +add_record_route_and_set_uri(URI, LServer, #sip{hdrs = Hdrs} = Req) -> + case is_request_within_dialog(Req) of + false -> + RR_URI = #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}, + Hdrs1 = [{'record-route', [{<<>>, RR_URI, []}]}|Hdrs], + Req#sip{uri = URI, hdrs = Hdrs1}; + true -> + Req + end. + +is_request_within_dialog(#sip{hdrs = Hdrs}) -> + {_, _, Params} = esip:get_hdr('to', Hdrs), + esip:has_param(<<"tag">>, Params). get_configured_vias(LServer) -> gen_mod:get_module_opt( diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 5080cf4a7..2102af851 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -85,17 +85,9 @@ request(#sip{hdrs = Hdrs} = Req, SIPSock) -> case register_session(US, SIPSock, CallID, CSeq, ContactsWithExpires) of {ok, Res} -> - if Res == updated -> - ?INFO_MSG("register SIP session for user " - "~s@~s from ~s", - [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, + ?INFO_MSG("~s SIP session for user ~s@~s from ~s", + [Res, LUser, LServer, + inet_parse:ntoa(PeerIP)]), Cs = prepare_contacts_to_send(ContactsWithExpires), mod_sip:make_response( Req, @@ -219,48 +211,57 @@ write_session(#sip_session{us = {U, S} = US, bindings = NewBindings}) -> Err; (#binding{call_id = CallID, expires = Expires, - cseq = CSeq} = Binding, {Add, Del}) -> + cseq = CSeq} = Binding, {Add, Keep, Del}) -> case find_binding(Binding, PrevBindings) of {ok, #binding{call_id = CallID, cseq = PrevCSeq}} when PrevCSeq > CSeq -> {error, cseq_out_of_order}; {ok, PrevBinding} when Expires == 0 -> - {Add, [PrevBinding|Del]}; - {ok, _} -> - {[Binding|Add], Del}; + {Add, Keep -- [PrevBinding], [PrevBinding|Del]}; + {ok, PrevBinding} -> + {[Binding|Add], Keep -- [PrevBinding], Del}; {error, notfound} when Expires == 0 -> {error, notfound}; {error, notfound} -> - {[Binding|Add], Del} + {[Binding|Add], Keep, Del} end - end, {[], []}, NewBindings), + end, {[], PrevBindings, []}, NewBindings), MaxSessions = ejabberd_sm:get_max_user_sessions(U, S), case Res of {error, Why} -> {error, Why}; - {AddBindings, _} when length(AddBindings) > MaxSessions -> - {error, too_many_sessions}; - {AddBindings, DelBindings} -> - lists:foreach( - fun(#binding{tref = TRef}) -> - erlang:cancel_timer(TRef) - end, DelBindings), - Bindings = lists:map( - fun(#binding{tref = TRef, - expires = Expires} = Binding) -> - erlang:cancel_timer(TRef), - NewTRef = erlang:start_timer( - Expires * 1000, self(), US), - Binding#binding{tref = NewTRef} - end, AddBindings), - case Bindings of - [] -> - mnesia:dirty_delete(sip_session, US), - {ok, deleted}; - _ -> - mnesia:dirty_write( - #sip_session{us = US, bindings = Bindings}), - {ok, updated} + {AddBindings, KeepBindings, DelBindings} -> + MaxSessions = ejabberd_sm:get_max_user_sessions(U, S), + AllBindings = AddBindings ++ KeepBindings, + if length(AllBindings) > MaxSessions -> + {error, too_many_sessions}; + true -> + lists:foreach( + fun(#binding{tref = TRef}) -> + erlang:cancel_timer(TRef) + end, DelBindings), + AddBindings1 = lists:map( + fun(#binding{tref = TRef, + expires = Expires} = Binding) -> + erlang:cancel_timer(TRef), + NewTRef = erlang:start_timer( + Expires * 1000, self(), US), + Binding#binding{tref = NewTRef} + end, AddBindings), + AllBindings1 = AddBindings1 ++ KeepBindings, + case AllBindings1 of + [] -> + mnesia:dirty_delete(sip_session, US), + {ok, unregister}; + _ -> + mnesia:dirty_write( + #sip_session{us = US, bindings = AllBindings1}), + if length(DelBindings) == length(NewBindings) -> + {ok, unregister}; + true -> + {ok, register} + end + end end end. |