mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Add accept_interval option in ejabberd_listener
This commit is contained in:
parent
5ffdfdd95d
commit
c6798fc515
@ -292,6 +292,40 @@ get_ip_tuple(IPOpt, _IPVOpt) ->
|
|||||||
IPOpt.
|
IPOpt.
|
||||||
|
|
||||||
accept(ListenSocket, Module, Opts) ->
|
accept(ListenSocket, Module, Opts) ->
|
||||||
|
IntervalOpt =
|
||||||
|
case proplists:get_value(accept_interval, Opts) of
|
||||||
|
[{linear, [I1_, T1_, T2_, I2_]}] ->
|
||||||
|
{linear, I1_, T1_, T2_, I2_};
|
||||||
|
I_ -> I_
|
||||||
|
end,
|
||||||
|
Interval =
|
||||||
|
case IntervalOpt of
|
||||||
|
undefined ->
|
||||||
|
0;
|
||||||
|
I when is_integer(I), I >= 0 ->
|
||||||
|
I;
|
||||||
|
{linear, I1, T1, T2, I2}
|
||||||
|
when is_integer(I1),
|
||||||
|
is_integer(T1),
|
||||||
|
is_integer(T2),
|
||||||
|
is_integer(I2),
|
||||||
|
I1 >= 0,
|
||||||
|
I2 >= 0,
|
||||||
|
T2 > 0 ->
|
||||||
|
{MSec, Sec, _USec} = os:timestamp(),
|
||||||
|
TS = MSec * 1000000 + Sec,
|
||||||
|
{linear, I1, TS + T1, T2, I2};
|
||||||
|
I ->
|
||||||
|
?WARNING_MSG("There is a problem in the configuration: "
|
||||||
|
"~p is a wrong accept_interval value. "
|
||||||
|
"Using 0 as fallback",
|
||||||
|
[I]),
|
||||||
|
0
|
||||||
|
end,
|
||||||
|
accept(ListenSocket, Module, Opts, Interval).
|
||||||
|
|
||||||
|
accept(ListenSocket, Module, Opts, Interval) ->
|
||||||
|
NewInterval = check_rate_limit(Interval),
|
||||||
case gen_tcp:accept(ListenSocket) of
|
case gen_tcp:accept(ListenSocket) of
|
||||||
{ok, Socket} ->
|
{ok, Socket} ->
|
||||||
case {inet:sockname(Socket), inet:peername(Socket)} of
|
case {inet:sockname(Socket), inet:peername(Socket)} of
|
||||||
@ -307,11 +341,11 @@ accept(ListenSocket, Module, Opts) ->
|
|||||||
false -> ejabberd_socket
|
false -> ejabberd_socket
|
||||||
end,
|
end,
|
||||||
CallMod:start(strip_frontend(Module), gen_tcp, Socket, Opts),
|
CallMod:start(strip_frontend(Module), gen_tcp, Socket, Opts),
|
||||||
accept(ListenSocket, Module, Opts);
|
accept(ListenSocket, Module, Opts, NewInterval);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("(~w) Failed TCP accept: ~w",
|
?ERROR_MSG("(~w) Failed TCP accept: ~w",
|
||||||
[ListenSocket, Reason]),
|
[ListenSocket, Reason]),
|
||||||
accept(ListenSocket, Module, Opts)
|
accept(ListenSocket, Module, Opts, NewInterval)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
udp_recv(Socket, Module, Opts) ->
|
udp_recv(Socket, Module, Opts) ->
|
||||||
@ -555,6 +589,31 @@ format_error(Reason) ->
|
|||||||
ReasonStr
|
ReasonStr
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
check_rate_limit(Interval) ->
|
||||||
|
NewInterval = receive
|
||||||
|
{rate_limit, AcceptInterval} ->
|
||||||
|
AcceptInterval
|
||||||
|
after 0 ->
|
||||||
|
Interval
|
||||||
|
end,
|
||||||
|
case NewInterval of
|
||||||
|
0 -> ok;
|
||||||
|
Ms when is_integer(Ms) ->
|
||||||
|
timer:sleep(Ms);
|
||||||
|
{linear, I1, T1, T2, I2} ->
|
||||||
|
{MSec, Sec, _USec} = os:timestamp(),
|
||||||
|
TS = MSec * 1000000 + Sec,
|
||||||
|
I =
|
||||||
|
if
|
||||||
|
TS =< T1 -> I1;
|
||||||
|
TS >= T1 + T2 -> I2;
|
||||||
|
true ->
|
||||||
|
round((I2 - I1) * (TS - T1) / T2 + I1)
|
||||||
|
end,
|
||||||
|
timer:sleep(I)
|
||||||
|
end,
|
||||||
|
NewInterval.
|
||||||
|
|
||||||
-define(IS_CHAR(C), (is_integer(C) and (C >= 0) and (C =< 255))).
|
-define(IS_CHAR(C), (is_integer(C) and (C >= 0) and (C =< 255))).
|
||||||
-define(IS_UINT(U), (is_integer(U) and (U >= 0) and (U =< 65535))).
|
-define(IS_UINT(U), (is_integer(U) and (U >= 0) and (U =< 65535))).
|
||||||
-define(IS_PORT(P), (is_integer(P) and (P > 0) and (P =< 65535))).
|
-define(IS_PORT(P), (is_integer(P) and (P > 0) and (P =< 65535))).
|
||||||
|
Loading…
Reference in New Issue
Block a user