Commit 1548b63e authored by Philipp Huebner's avatar Philipp Huebner

Imported Upstream version 1.0.0

parent f37866b3
sudo: false
language: erlang
before_install:
- pip install --user cpp-coveralls coveralls-merge
install:
- rebar get-deps
script: rebar compile xref && rebar skip_deps=true eunit
otp_release:
- 17.1
- 17.5
- 18.1
after_success:
- coveralls --exclude lib --exclude tests --gcov-options '\-lp' --dump c.json
- coveralls-merge c.json erlang.json
# Version 1.0.0
* Prepare release on Hex.pm (Mickaël Rémond)
* Rename application to stun instead of p1_stun.
* Document usage (Evgeny Khramtsov)
This diff is collapsed.
This diff is collapsed.
# STUN
[![Build Status](https://travis-ci.org/processone/stun.svg?branch=master)](https://travis-ci.org/processone/stun) [![Coverage Status](https://coveralls.io/repos/processone/stun/badge.svg?branch=master&service=github)](https://coveralls.io/github/processone/stun?branch=master) [![Hex version](https://img.shields.io/hexpm/v/stun.svg "Hex version")](https://hex.pm/packages/stun)
STUN and TURN library for Erlang / Elixir.
Both [STUN](https://en.wikipedia.org/wiki/STUN) (Session Traversal
Utilities for NAT) and
[TURN](https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT)
standards are used as technics to establish media connection between
peers for VoIP (for example using
[SIP](https://en.wikipedia.org/wiki/Session_Initiation_Protocol) or
[Jingle](http://xmpp.org/about-xmpp/technology-overview/jingle/)) and
[WebRTC](https://en.wikipedia.org/wiki/WebRTC).
They are part of a more general negociation technique know as
[ICE](https://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment)
(Interactive Connectivity Establishment).
To summarize:
* A STUN server is used to get an external network address. It does
not serve as a relay for the mediat raffic.
* TURN servers are used to relay traffic if direct (peer to peer)
connection fails.
## Build
This is a pure Erlang implementation, so you do not need to have
specific C libraries installed for the STUN, TURN, ICE code.
However, this code depends on ProcessOne
[Fast TLS](https://github.com/processone/fast_tls), which depends on
OpenSSL 1.0.0+ library.
### Generic build
You can trigger build with:
make
# Usage
The following sequence describe a STUN establishment.
First, start the application and stun listener:
```
1> application:start(stun).
ok
2> stun_listener:add_listener(3478, udp, []).
ok
```
Then, you can form and send a BindRequest:
```
3> rr(stun).
[state,stun,turn]
4> random:seed(erlang:timestamp()).
undefined
```
You can form a transaction id. Should be always 96 bit:
```
5> TrID = random:uniform(1 bsl 96).
41809861624941132369239212033
```
You then create a BindRequest message.
`16#001` is `?STUN_METHOD_BINDING`, defined in `include/stun.hrl`
```
6> Msg = #stun{method = 16#001, class = request, trid = TrID}.
#stun{class = request,method = 1,magic = 554869826,
trid = 41809861624941132369239212033,raw = <<>>,
unsupported = [],'ALTERNATE-SERVER' = undefined,
'CHANNEL-NUMBER' = undefined,'DATA' = undefined,
'DONT-FRAGMENT' = false,'ERROR-CODE' = undefined,
'LIFETIME' = undefined,'MAPPED-ADDRESS' = undefined,
'MESSAGE-INTEGRITY' = undefined,'NONCE' = undefined,
'REALM' = undefined,'REQUESTED-TRANSPORT' = undefined,
'SOFTWARE' = undefined,'UNKNOWN-ATTRIBUTES' = [],
'USERNAME' = undefined,'XOR-MAPPED-ADDRESS' = undefined,
'XOR-PEER-ADDRESS' = [],'XOR-RELAYED-ADDRESS' = undefined}
```
You can then establish connection to running server:
```
7> {ok, Socket} = gen_udp:open(0, [binary, {ip,
7> {127,0,0,1}},{active,false}]).
{ok,#Port<0.1020>}
8> {ok, Addr} = inet:sockname(Socket).
{ok,{{127,0,0,1},41906}}
```
The following call is for encoding BindRequest:
```
9> PktOut = stun_codec:encode(Msg).
<<0,1,0,0,33,18,164,66,135,24,78,148,65,4,128,0,0,0,0,1>>
```
The BindRequest can then be send:
```
10> gen_udp:send(Socket, {127,0,0,1}, 3478, PktOut).
ok
```
The follow code receives the BindResponse:
```
11> {ok, {_, _, PktIn}} = gen_udp:recv(Socket, 0).
{ok,{{127,0,0,1},
3478,
<<1,1,0,32,33,18,164,66,135,24,78,148,65,4,128,0,0,0,0,
1,128,34,0,15,...>>}}
```
You can then decode the BindResponse:
```
12> {ok, Response} = stun_codec:decode(PktIn, datagram).
{ok,#stun{class = response,method = 1,magic = 554869826,
trid = 41809861624941132369239212033,raw = <<>>,
unsupported = [],'ALTERNATE-SERVER' = undefined,
'CHANNEL-NUMBER' = undefined,'DATA' = undefined,
'DONT-FRAGMENT' = false,'ERROR-CODE' = undefined,
'LIFETIME' = undefined,'MAPPED-ADDRESS' = undefined,
'MESSAGE-INTEGRITY' = undefined,'NONCE' = undefined,
'REALM' = undefined,'REQUESTED-TRANSPORT' = undefined,
'SOFTWARE' = <<"P1 STUN library">>,
'UNKNOWN-ATTRIBUTES' = [],'USERNAME' = undefined,
'XOR-MAPPED-ADDRESS' = {{127,0,0,1},41906},
'XOR-PEER-ADDRESS' = [],'XOR-RELAYED-ADDRESS' = undefined}}
```
Finally, checking 'XOR-MAPPED-ADDRESS' attribute, should be equal to locally
binded address:
```
13> Addr == Response#stun.'XOR-MAPPED-ADDRESS'.
true
```
## Development
### Test
#### Unit test
You can run eunit test with the command:
make test
# References
You can refer to IETF specifications to learn more:
* [RFC 5389](https://tools.ietf.org/html/rfc5389): Session Traversal
Utilities for NAT (STUN).
* [RFC 5766](https://tools.ietf.org/html/rfc5766): Traversal Using
Relays around NAT (TURN): Relay Extensions to STUN.
* [RFC 5245](https://tools.ietf.org/html/rfc5245): Interactive
Connectivity Establishment (ICE): A Protocol for NAT Traversal for
Offer/Answer Protocols.
* [RFC 6544](https://tools.ietf.org/html/rfc6544): TCP Candidates with
Interactive Connectivity Establishment (ICE)
......@@ -5,22 +5,19 @@
%%% Created : 8 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%-------------------------------------------------------------------
-define(STUN_MAGIC, 16#2112a442).
......
%%%----------------------------------------------------------------------
%%% File : rebar.config.script
%%% Author : Mickael Remond <mremond@process-one.net>
%%% Purpose : Rebar build script. Compliant with rebar and rebar3.
%%% Created : 24 Nov 2015 by Mickael Remond <mremond@process-one.net>
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed 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.
%%%
%%%----------------------------------------------------------------------
{erl_opts, [debug_info, {i, "include"}]}.
{deps, [{p1_tls, ".*", {git, "https://github.com/processone/tls", {tag, "1.0.0"}}},
{deps, [{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.0"}}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.3"}}}]}.
{cover_enabled, true}.
{cover_export_enabled, true}.
{xref_checks, [undefined_function_calls, undefined_functions, deprecated_function_calls, deprecated_functions]}.
%% Local Variables:
%% mode: erlang
%% End:
......
%%%----------------------------------------------------------------------
%%% File : rebar.config.script
%%% Author : Mickael Remond <mremond@process-one.net>
%%% Purpose : Rebar build script. Compliant with rebar and rebar3.
%%% Created : 24 Nov 2015 by Mickael Remond <mremond@process-one.net>
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed 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.
%%%
%%%----------------------------------------------------------------------
ModCfg0 = fun(F, Cfg, [Key|Tail], Op, Default) ->
{OldVal,PartCfg} = case lists:keytake(Key, 1, Cfg) of
{value, {_, V1}, V2} -> {V1, V2};
false -> {if Tail == [] -> Default; true -> [] end, Cfg}
end,
case Tail of
[] ->
[{Key, Op(OldVal)} | PartCfg];
_ ->
[{Key, F(F, OldVal, Tail, Op, Default)} | PartCfg]
end
end,
ModCfg = fun(Cfg, Keys, Op, Default) -> ModCfg0(ModCfg0, Cfg, Keys, Op, Default) end.
%% Rebar3 support for hex.pm support:
%% - Transform dependencies specification to use hex.pm packages:
%% deps of the form: {Name, _Vsn, {git, _URL, {tag, Version}}}
%% are expected to refer to package and are rewritten for rebar3 as:
%% {Name, Version}
%% - Add rebar3_hex plugin
IsRebar3 = case application:get_key(rebar, vsn) of
{ok, VSN} ->
[VSN1 | _] = string:tokens(VSN, "-"),
[Maj, Min, Patch] = string:tokens(VSN1, "."),
(list_to_integer(Maj) >= 3);
undefined ->
lists:keymember(mix, 1, application:loaded_applications())
end,
Cfg2 = case IsRebar3 of
true ->
DepsFun = fun(DepsList) -> lists:map(fun({DepName,_, {git,_, {tag,Version}}}) ->
{DepName, Version};
(Dep) ->
Dep
end, DepsList)
end,
RB1 = ModCfg(CONFIG, [deps], DepsFun, []),
ModCfg(RB1, [plugins], fun(V) -> V ++ [rebar3_hex] end, []);
false ->
CONFIG
end,
%% When running Travis test, upload test coverage result to coveralls:
Config = case os:getenv("TRAVIS") of
"true" ->
JobId = os:getenv("TRAVIS_JOB_ID"),
Cfg3 = ModCfg(Cfg2, [deps], fun(V) -> [{coveralls, ".*", {git, "https://github.com/markusn/coveralls-erl.git", "master"}}|V] end, []),
ModCfg(Cfg3, [post_hooks], fun(V) -> V ++ [{eunit, "echo '\n%%! -pa .eunit/ deps/coveralls/ebin\nmain(_)->{ok,F}=file:open(\"erlang.json\",[write]),io:fwrite(F,\"~s\",[coveralls:convert_file(\".eunit/cover.coverdata\", \""++JobId++"\", \"travis-ci\")]).' > getcover.erl"},
{eunit, "escript ./getcover.erl"}] end, []);
_ ->
Cfg2
end,
Config.
%% Local Variables:
%% mode: erlang
%% End:
%% vim: set filetype=erlang tabstop=8:
%%%-------------------------------------------------------------------
%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%% @copyright (C) 2013, Evgeniy Khramtsov
%%% @doc
%%%
%%% @end
%%% Created : 4 Apr 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%-------------------------------------------------------------------
{application, p1_stun,
[{description, "STUN library"},
{vsn, "0.9.0"},
{modules, []},
{registered, []},
{applications, [kernel, stdlib]},
{mod, {stun_app,[]}}]}.
%% Local Variables:
%% mode: erlang
%% End:
%% vim: set filetype=erlang tabstop=8:
%%%----------------------------------------------------------------------
%%% File : stun.app.src
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%% Purpose : Application package description
%%% Created : 4 Apr 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed 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.
%%%
%%%----------------------------------------------------------------------
{application, stun,
[{description, "STUN and TURN library for Erlang / Elixir"},
{vsn, "1.0.0"},
{modules, []},
{registered, []},
{applications, [kernel, stdlib]},
{mod, {stun_app,[]}},
%% hex.pm packaging:
{licenses, ["Apache 2.0"]},
{maintainers, ["ProcessOne"]},
{links, [{"Github", "https://github.com/processone/stun"}]}]}.
%% Local Variables:
%% mode: erlang
%% End:
%% vim: set filetype=erlang tabstop=8:
......@@ -5,22 +5,19 @@
%%% Created : 8 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%-------------------------------------------------------------------
......@@ -66,8 +63,8 @@
-type addr() :: {inet:ip_address(), inet:port_number()}.
-record(state,
{sock :: inet:socket() | p1_tls:tls_socket(),
sock_mod = gen_tcp :: gen_udp | gen_tcp | p1_tls,
{sock :: inet:socket() | fast_tls:tls_socket(),
sock_mod = gen_tcp :: gen_udp | gen_tcp | fast_tls,
certfile :: iodata(),
peer = {{0,0,0,0}, 0} :: addr(),
tref = make_ref() :: reference(),
......@@ -153,9 +150,9 @@ handle_sync_event(_Event, _From, StateName, State) ->
{reply, {error, badarg}, StateName, State}.
handle_info({tcp, _Sock, TLSData}, StateName,
#state{sock_mod = p1_tls} = State) ->
#state{sock_mod = fast_tls} = State) ->
NewState = update_shaper(State, TLSData),
case p1_tls:recv_data(NewState#state.sock, TLSData) of
case fast_tls:recv_data(NewState#state.sock, TLSData) of
{ok, Data} ->
process_data(StateName, NewState, Data);
_Err ->
......@@ -583,16 +580,15 @@ cancel_timer(TRef) ->
end.
now_priority() ->
{MSec, Sec, USec} = now(),
-((MSec*1000000 + Sec)*1000000 + USec).
{p1_time_compat:monotonic_time(micro_seconds), p1_time_compat:unique_integer([monotonic])}.
clean_treap(Treap, CleanPriority) ->
case treap:is_empty(Treap) of
true ->
Treap;
false ->
{_Key, Priority, _Value} = treap:get_root(Treap),
if Priority > CleanPriority ->
{_Key, {TS, _}, _Value} = treap:get_root(Treap),
if TS > CleanPriority ->
clean_treap(treap:delete_root(Treap), CleanPriority);
true ->
Treap
......@@ -601,13 +597,14 @@ clean_treap(Treap, CleanPriority) ->
make_nonce(Addr, Nonces) ->
Priority = now_priority(),
{TS, _} = Priority,
Nonce = list_to_binary(integer_to_list(random:uniform(1 bsl 32))),
NewNonces = clean_treap(Nonces, Priority + ?NONCE_LIFETIME),
NewNonces = clean_treap(Nonces, TS + ?NONCE_LIFETIME),
{Nonce, treap:insert(Nonce, Priority, Addr, NewNonces)}.
have_nonce(Nonce, Nonces) ->
Priority = now_priority(),
NewNonces = clean_treap(Nonces, Priority + ?NONCE_LIFETIME),
TS = p1_time_compat:monotonic_time(micro_seconds),
NewNonces = clean_treap(Nonces, TS + ?NONCE_LIFETIME),
case treap:lookup(Nonce, NewNonces) of
{ok, _, _} ->
{true, NewNonces};
......@@ -623,7 +620,7 @@ addr_to_str(Addr) ->
get_sockmod(Opts) ->
case proplists:get_bool(tls, Opts) of
true ->
p1_tls;
fast_tls;
false ->
gen_tcp
end.
......@@ -636,18 +633,18 @@ get_certfile(Opts) ->
undefined
end.
maybe_starttls(_Sock, p1_tls, undefined, {IP, Port}) ->
maybe_starttls(_Sock, fast_tls, undefined, {IP, Port}) ->
error_logger:error_msg("failed to start TLS connection for ~s:~p: "
"option 'certfile' is not set",
[inet_parse:ntoa(IP), Port]),
{error, eprotonosupport};
maybe_starttls(Sock, p1_tls, CertFile, _PeerAddr) ->
p1_tls:tcp_to_tls(Sock, [{certfile, CertFile}]);
maybe_starttls(Sock, fast_tls, CertFile, _PeerAddr) ->
fast_tls:tcp_to_tls(Sock, [{certfile, CertFile}]);
maybe_starttls(Sock, gen_tcp, _CertFile, _PeerAddr) ->
{ok, Sock}.
seed() ->
{A, B, C} = now(),
{A, B, C} = p1_time_compat:timestamp(),
random:seed(A, B, C).
prepare_response(State, Msg) ->
......
......@@ -5,22 +5,19 @@
%%% Created : 2 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%----------------------------------------------------------------------
......@@ -52,7 +49,7 @@
%% @end
%%--------------------------------------------------------------------
start(_StartType, _StartArgs) ->
application:start(p1_tls),
application:start(fast_tls),
case stun_sup:start_link() of
{ok, Pid} ->
{ok, Pid};
......
......@@ -5,22 +5,19 @@
%%% Created : 7 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%-------------------------------------------------------------------
......
......@@ -5,22 +5,19 @@
%%% Created : 9 Jan 2011 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%----------------------------------------------------------------------
......
......@@ -5,22 +5,19 @@
%%% Created : 9 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%
%%%----------------------------------------------------------------------
......@@ -46,7 +43,7 @@
new(none) -> none;
new(MaxRate) when is_integer(MaxRate) ->
#maxrate{maxrate = MaxRate, lastrate = 0.0,
lasttime = now_to_usec(now())}.
lasttime = p1_time_compat:monotonic_time(micro_seconds)}.
-spec update(shaper(), integer()) -> {shaper(), integer()}.
......@@ -54,19 +51,16 @@ update(none, _Size) -> {none, 0};
update(#maxrate{} = State, Size) ->
MinInterv = 1000 * Size /
(2 * State#maxrate.maxrate - State#maxrate.lastrate),
Interv = (now_to_usec(now()) - State#maxrate.lasttime) /
Interv = (p1_time_compat:monotonic_time(micro_seconds) - State#maxrate.lasttime) /
1000,
Pause = if MinInterv > Interv ->
1 + trunc(MinInterv - Interv);
true -> 0
end,
NextNow = now_to_usec(now()) + Pause * 1000,
NextNow = p1_time_compat:monotonic_time(micro_seconds) + Pause * 1000,
{State#maxrate{lastrate =
(State#maxrate.lastrate +
1000000 * Size / (NextNow - State#maxrate.lasttime))
/ 2,
lasttime = NextNow},
Pause}.
now_to_usec({MSec, Sec, USec}) ->
(MSec * 1000000 + Sec) * 1000000 + USec.
......@@ -5,22 +5,19 @@
%%% Created : 2 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% stun, Copyright (C) 2002-2015 ProcessOne
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%% Licensed 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
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% 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.
%%%