Skip to content

Commit

Permalink
Registrar rework
Browse files Browse the repository at this point in the history
  • Loading branch information
kalta committed Jun 14, 2014
1 parent a823605 commit 5fcb912
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 116 deletions.
12 changes: 8 additions & 4 deletions plugins/nksip_registrar/include/nksip_registrar.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


-record(reg_contact, {
index :: nksip_registrar:index(),
index :: nksip_registrar_lib:index(),
contact :: nksip:uri(),
updated :: nksip_lib:l_timestamp(),
expire :: nksip_lib:timestamp(),
Expand All @@ -36,6 +36,10 @@
meta = [] :: nksip:optslist() % No current use
}).




-record(nksip_registrar_time, {
min :: pos_integer(),
max :: pos_integer(),
default :: pos_integer(),
time :: pos_integer(),
time_long :: pos_integer()
}).
91 changes: 3 additions & 88 deletions plugins/nksip_registrar/src/nksip_registrar.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,8 @@

-export([find/2, find/4, qfind/2, qfind/4, delete/4, clear/1]).
-export([is_registered/1, request/1]).
-export([internal_get_all/0, internal_clear/0, internal_print_all/0]).
-export([version/0, deps/0, parse_config/2]).

-export_type([reg_contact/0, index/0, times/0]).


%% ===================================================================
%% Types and records
%% ===================================================================

-type reg_contact() :: #reg_contact{}.

-type index() ::
{
Scheme::sip|sips,
Proto::nksip:protocol(),
User::binary(),
Domain::binary(),
Port::inet:port_number()
}
|
{ob, Instance::binary(), RegId::binary()}.

-type times() :: {integer(), integer(), integer(), integer(), integer()}.



%% ===================================================================
%% Plugin specific
Expand Down Expand Up @@ -81,9 +57,9 @@ deps() ->

parse_config(PluginOpts, Config) ->
Defaults = [
{registrar_default_time, 3600}, % (secs) 1 hour
{registrar_min_time, 60}, % (secs) 1 min
{registrar_max_time, 86400} % (secs) 24 hour
{nksip_registrar_default_time, 3600}, % (secs) 1 hour
{nksip_registrar_min_time, 60}, % (secs) 1 min
{nksip_registrar_max_time, 86400} % (secs) 24 hour
],
PluginOpts1 = nksip_lib:defaults(PluginOpts, Defaults),
Allow = nksip_lib:get_value(allow, Config),
Expand Down Expand Up @@ -225,64 +201,3 @@ clear(App) ->
sipapp_not_found
end.


%% ===================================================================
%% Utilities available only using internal store
%% ===================================================================


% @private Get all current registrations. Use it with care.

-spec internal_get_all() ->
[{nksip:app_id(), nksip:aor(), [#reg_contact{}]}].

internal_get_all() ->
[
{AppId, AOR, nksip_store:get({nksip_registrar, AppId, AOR}, [])}
|| {AppId, AOR} <- internal_all()
].


%% @private
internal_print_all() ->
Now = nksip_lib:timestamp(),
Print = fun({AppId, {Scheme, User, Domain}, Regs}) ->
io:format("\n --- ~p --- ~p:~s@~s ---\n", [AppId:name(), Scheme, User, Domain]),
lists:foreach(
fun(#reg_contact{contact=Contact, expire=Expire, q=Q}) ->
io:format(" ~s, ~p, ~p\n", [nksip_unparse:uri(Contact), Expire-Now, Q])
end, Regs)
end,
lists:foreach(Print, internal_get_all()),
io:format("\n\n").


%% @private Clear all stored records for all SipApps, only with buil-in database
%% Returns the number of deleted items.
-spec internal_clear() ->
integer().

internal_clear() ->
Fun = fun(AppId, AOR, _Val, Acc) ->
nksip_store:del({nksip_registrar, AppId, AOR}),
Acc+1
end,
internal_fold(Fun, 0).


%% @private
internal_all() ->
internal_fold(fun(AppId, AOR, _Value, Acc) -> [{AppId, AOR}|Acc] end, []).


%% @private
internal_fold(Fun, Acc0) when is_function(Fun, 4) ->
FoldFun = fun(Key, Value, Acc) ->
case Key of
{nksip_registrar, AppId, AOR} -> Fun(AppId, AOR, Value, Acc);
_ -> Acc
end
end,
nksip_store:fold(FoldFun, Acc0).


14 changes: 12 additions & 2 deletions plugins/nksip_registrar/src/nksip_registrar_callbacks.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

-include("../../../include/nksip.hrl").
-include("../../../include/nksip_call.hrl").
-export([nkcb_sip_method/2, nkcb_terminate/3]).
-export([nkcb_sip_method/2, nkcb_terminate/3, nkcb_authorize_data/3]).


%% @private This plugin callback is called when a call to one of the method specific
Expand All @@ -40,10 +40,20 @@ nkcb_sip_method(#trans{method='REGISTER', request=Req}, #call{app_id=AppId}) ->
continue;
false ->
{reply, nksip_registrar:request(Req)}
end.
end;
nkcb_sip_method(_Trans, _Call) ->
continue.


%% @private
nkcb_terminate(AppId, _Reason, _PluginsState) ->
nksip_registrar:clear(AppId),
continue.


%% @private
nkcb_authorize_data(List, #trans{request=Req}=Trans, Call) ->
case nksip_registrar:is_registered(Req) of
true -> {continue, [[register|List], Trans, Call]};
false -> continue
end.
59 changes: 41 additions & 18 deletions plugins/nksip_registrar/src/nksip_registrar_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,30 @@

-export([parse_config/3, find/2, find/4, qfind/4, is_registered/2, request/1]).
-export([store_get/2, store_del/2, store_del_all/1]).
-export_type([reg_contact/0, index/0]).

-define(AES_IV, <<"12345678abcdefgh">>).


%% ===================================================================
%% Types and records
%% ===================================================================

-type reg_contact() :: #reg_contact{}.

-type index() ::
{
Scheme::sip|sips,
Proto::nksip:protocol(),
User::binary(),
Domain::binary(),
Port::inet:port_number()
}
|
{ob, Instance::binary(), RegId::binary()}.



%% ===================================================================
%% Internal
%% ===================================================================
Expand All @@ -48,17 +68,17 @@ parse_config([], Unknown, Config) ->

parse_config([Term|Rest], Unknown, Config) ->
Op = case Term of
{registrar_default_time, Secs} ->
{nksip_registrar_default_time, Secs} ->
case is_integer(Secs) andalso Secs>=5 of
true -> update;
false -> error
end;
{registrar_min_time, Secs} ->
{nksip_registrar_min_time, Secs} ->
case is_integer(Secs) andalso Secs>=1 of
true -> update;
false -> error
end;
{registrar_max_time, Secs} ->
{nksip_registrar_max_time, Secs} ->
case is_integer(Secs) andalso Secs>=60 of
true -> update;
false -> error
Expand Down Expand Up @@ -208,7 +228,7 @@ request(#sipmsg{app_id=AppId, to={To, _}}=Req) ->
case nksip_outbound:registrar(Req) of
{true, Req1} -> Opts1 = [{outbound, true}];
{false, Req1} -> Opts1 = [{outbound, false}];
continue -> Req1 = Req, Opts1 = [];
no_outbound -> Req1 = Req, Opts1 = [];
{error, OutError} -> Req1 = Opts1 = throw(OutError)
% end;
% false ->
Expand Down Expand Up @@ -249,20 +269,18 @@ process(Req, Opts) ->
true -> throw(unsupported_uri_scheme)
end,
Config = AppId:config(),
MinTime = nksip_lib:get_value(nksip_registrar_min_time, Config),
MaxTime = nksip_lib:get_value(nksip_registrar_max_time, Config),
DefTime = nksip_lib:get_value(nksip_registrar_default_time, Config),
Default = case nksip_sipmsg:meta(expires, Req) of
D0 when is_integer(D0) -> D0;
_ -> DefTime
end,
Long = nksip_lib:l_timestamp(),
Times = {
MinTime,
MaxTime,
Default,
Long div 1000000,
Long
TimeLong = nksip_lib:l_timestamp(),
Times = #nksip_registrar_time{
min = nksip_lib:get_value(nksip_registrar_min_time, Config),
max = nksip_lib:get_value(nksip_registrar_max_time, Config),
default = Default,
time = TimeLong div 1000000,
time_long = TimeLong
},
case Contacts of
[] -> ok;
Expand All @@ -273,18 +291,17 @@ process(Req, Opts) ->


%% @private
-spec update(nksip:request(), nksip_registrar:times(), nksip:optslist()) ->
-spec update(nksip:request(), #nksip_registrar_time{}, nksip:optslist()) ->
ok.

update(Req, Times, Opts) ->
#sipmsg{app_id=AppId, to={To, _}, contacts=Contacts} = Req,
{_, _, Default, Now, _LongNow} = Times,
#nksip_registrar_time{default=Default, time=Now} = Times,
check_several_reg_id(Contacts, Default, false),
Path = case nksip_sipmsg:header(<<"path">>, Req, uris) of
error -> throw({invalid_request, "Invalid Path"});
Path0 -> Path0
end,
{_, _, _, Now, _LongNow} = Times,
AOR = aor(To),
{ok, Regs} = store_get(AppId, AOR),
RegContacts0 = [
Expand Down Expand Up @@ -312,15 +329,21 @@ update(Req, Times, Opts) ->


%% @private Extracts from each contact a index, uri, expire time and q
-spec update_regcontacts([#uri{}], nksip:request(), nksip_registrar:times(),
-spec update_regcontacts([#uri{}], nksip:request(), #nksip_registrar_time{},
[nksip:uri()], nksip:optslist(), [#reg_contact{}]) ->
[#reg_contact{}].

update_regcontacts([Contact|Rest], Req, Times, Path, Opts, Acc) ->
#uri{scheme=Scheme, user=User, domain=Domain, ext_opts=ExtOpts} = Contact,
#sipmsg{to={To, _}, call_id=CallId, cseq={CSeq, _}, transport=Transp} = Req,
update_checks(Contact, Req),
{Min, Max, Default, Now, LongNow} = Times,
#nksip_registrar_time{
min = Min,
max = Max,
default = Default,
time = Now,
time_long = LongNow
} = Times,
UriExp = case nksip_lib:get_list(<<"expires">>, ExtOpts) of
[] ->
Default;
Expand Down
2 changes: 1 addition & 1 deletion plugins/nksip_registrar/src/nksip_registrar_sipapp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
{del, AOR} | del_all,
AppId :: nksip:app_id(),
AOR :: nksip:aor(),
RegContact :: nksip_registrar:reg_contact(),
RegContact :: nksip_registrar_lib:reg_contact(),
TTL :: integer().

sip_registrar_store(Op, AppId) ->
Expand Down
88 changes: 88 additions & 0 deletions plugins/nksip_registrar/src/nksip_registrar_util.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2013 Carlos Gonzalez Florido. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------

%% @doc NkSIP Registrar Server Plugin Utilities (only for internal storage)
-module(nksip_registrar_util).
-author('Carlos Gonzalez <[email protected]>').

-include("nksip_registrar.hrl").

-export([get_all/0, clear/0, print_all/0]).


%% ===================================================================
%% Utilities available only using internal store
%% ===================================================================


% @private Get all current registrations. Use it with care.
-spec get_all() ->
[{nksip:app_id(), nksip:aor(), [#reg_contact{}]}].

get_all() ->
[
{AppId, AOR, nksip_store:get({nksip_registrar, AppId, AOR}, [])}
|| {AppId, AOR} <- all()
].


%% @private
print_all() ->
Now = nksip_lib:timestamp(),
Print = fun({AppId, {Scheme, User, Domain}, Regs}) ->
io:format("\n --- ~p --- ~p:~s@~s ---\n", [AppId:name(), Scheme, User, Domain]),
lists:foreach(
fun(#reg_contact{contact=Contact, expire=Expire, q=Q}) ->
io:format(" ~s, ~p, ~p\n", [nksip_unparse:uri(Contact), Expire-Now, Q])
end, Regs)
end,
lists:foreach(Print, get_all()),
io:format("\n\n").


%% @private Clear all stored records for all SipApps, only with buil-in database
%% Returns the number of deleted items.
-spec clear() ->
integer().

clear() ->
Fun = fun(AppId, AOR, _Val, Acc) ->
nksip_store:del({nksip_registrar, AppId, AOR}),
Acc+1
end,
fold(Fun, 0).


%% @private
all() ->
fold(fun(AppId, AOR, _Value, Acc) -> [{AppId, AOR}|Acc] end, []).


%% @private
fold(Fun, Acc0) when is_function(Fun, 4) ->
FoldFun = fun(Key, Value, Acc) ->
case Key of
{nksip_registrar, AppId, AOR} -> Fun(AppId, AOR, Value, Acc);
_ -> Acc
end
end,
nksip_store:fold(FoldFun, Acc0).


Loading

0 comments on commit 5fcb912

Please sign in to comment.